增加进销存
This commit is contained in:
+196
@@ -0,0 +1,196 @@
|
||||
import { getAction, deleteAction, putAction, postAction, httpAction } from '@/api/manage'
|
||||
|
||||
//首页统计
|
||||
const getBuyAndSaleStatistics = (params)=>getAction("/erp/depotHead/getBuyAndSaleStatistics",params);
|
||||
const buyOrSalePrice = (params)=>getAction("/erp/depotItem/buyOrSalePrice",params);
|
||||
//租户管理
|
||||
const checkTenant = (params)=>getAction("/erp/tenant/checkIsNameExist",params);
|
||||
const editTenant = (params)=>putAction("/erp/tenant/update",params);
|
||||
//角色管理
|
||||
const addRole = (params)=>postAction("/erp/role/add",params);
|
||||
const editRole = (params)=>putAction("/erp/role/update",params);
|
||||
const checkRole = (params)=>getAction("/erp/role/checkIsNameExist",params);
|
||||
const roleAllList = (params)=>getAction("/erp/role/allList",params);
|
||||
//用户管理
|
||||
const registerUser = (params)=>postAction("/erp/user/registerUser",params);
|
||||
const addUser = (params)=>postAction("/erp/user/addUser",params);
|
||||
const editUser = (params)=>putAction("/erp/user/updateUser",params);
|
||||
const getUserList = (params)=>getAction("/erp/user/getUserList",params);
|
||||
const queryPermissionsByUser = (params)=>postAction("/erp/function/findMenuByPNumber",params);
|
||||
//机构管理
|
||||
const queryOrganizationTreeList = (params)=>getAction("/erp/organization/getOrganizationTree",params);
|
||||
const queryOrganizationById = (params)=>getAction("/erp/organization/findById",params);
|
||||
const checkOrganization = (params)=>getAction("/erp/organization/checkIsNameExist",params);
|
||||
//经手人管理
|
||||
const addPerson = (params)=>postAction("/erp/person/add",params);
|
||||
const editPerson = (params)=>putAction("/erp/person/update",params);
|
||||
const checkPerson = (params)=>getAction("/erp/person/checkIsNameExist",params);
|
||||
const getPersonByType = (params)=>getAction("/erp/person/getPersonByType",params);
|
||||
const getPersonByNumType = (params)=>getAction("/erp/person/getPersonByNumType",params);
|
||||
//账户管理
|
||||
const addAccount = (params)=>postAction("/erp/account/add",params);
|
||||
const editAccount = (params)=>putAction("/erp/account/update",params);
|
||||
const checkAccount = (params)=>getAction("/erp/account/checkIsNameExist",params);
|
||||
const getAccount = (params)=>getAction("/erp/account/getAccount",params);
|
||||
//收支项目
|
||||
const addInOutItem = (params)=>postAction("/erp/inOutItem/add",params);
|
||||
const editInOutItem = (params)=>putAction("/erp/inOutItem/update",params);
|
||||
const checkInOutItem = (params)=>getAction("/erp/inOutItem/checkIsNameExist",params);
|
||||
const findInOutItemByParam = (params)=>getAction("/erp/inOutItem/findBySelect",params);
|
||||
//仓库信息
|
||||
const addDepot = (params)=>postAction("/erp/depot/add",params);
|
||||
const editDepot = (params)=>putAction("/erp/depot/update",params);
|
||||
const checkDepot = (params)=>getAction("/erp/depot/checkIsNameExist",params);
|
||||
//商品属性
|
||||
const editMaterialProperty = (params)=>putAction("/erp/materialProperty/update",params);
|
||||
//商品类型
|
||||
const queryMaterialCategoryTreeList = (params)=>getAction("/erp/materialCategory/getMaterialCategoryTree",params);
|
||||
const queryMaterialCategoryById = (params)=>getAction("/erp/materialCategory/findById",params);
|
||||
const checkMaterialCategory = (params)=>getAction("/erp/materialCategory/checkIsNameExist",params);
|
||||
//商品管理
|
||||
const addMaterial = (params)=>postAction("/erp/material/add",params);
|
||||
const editMaterial = (params)=>putAction("/erp/material/update",params);
|
||||
const checkMaterial = (params)=>getAction("/erp/material/checkIsExist",params);
|
||||
const getMaterialBySelect = (params)=>getAction("/erp/material/findBySelect",params);
|
||||
const getSerialMaterialBySelect = (params)=>getAction("/erp/material/getMaterialEnableSerialNumberList",params);
|
||||
const getMaterialByBarCode = (params)=>getAction("/erp/material/getMaterialByBarCode",params);
|
||||
const getMaxBarCode = (params)=>getAction("/erp/material/getMaxBarCode",params);
|
||||
const checkMaterialBarCode = (params)=>getAction("/erp/materialsExtend/checkIsBarCodeExist",params);
|
||||
//序列号
|
||||
const addSerialNumber = (params)=>postAction("/erp/serialNumber/add",params);
|
||||
const editSerialNumber = (params)=>putAction("/erp/serialNumber/update",params);
|
||||
const checkSerialNumber = (params)=>getAction("/erp/serialNumber/checkIsNameExist",params);
|
||||
const batAddSerialNumber = (params)=>postAction("/erp/serialNumber/batAddSerialNumber",params);
|
||||
const getEnableSerialNumberList = (params)=>getAction("/erp/serialNumber/getEnableSerialNumberList",params);
|
||||
//多属性
|
||||
const addMaterialAttribute = (params)=>postAction("/erp/materialAttribute/add",params);
|
||||
const editMaterialAttribute = (params)=>putAction("/erp/materialAttribute/update",params);
|
||||
const checkMaterialAttribute = (params)=>getAction("/erp/materialAttribute/checkIsNameExist",params);
|
||||
const getAllMaterialAttribute = (params)=>getAction("/erp/materialAttribute/getAll",params);
|
||||
//功能管理
|
||||
const addFunction = (params)=>postAction("/erp/function/add",params);
|
||||
const editFunction = (params)=>putAction("/erp/function/update",params);
|
||||
const checkFunction = (params)=>getAction("/erp/function/checkIsNameExist",params);
|
||||
//系统配置
|
||||
const addSystemConfig = (params)=>postAction("/erp/systemConfig/add",params);
|
||||
const editSystemConfig = (params)=>putAction("/erp/systemConfig/update",params);
|
||||
const checkSystemConfig = (params)=>getAction("/erp/systemConfig/checkIsNameExist",params);
|
||||
const getCurrentSystemConfig = (params)=>getAction("/erp/systemConfig/getCurrentInfo",params);
|
||||
const fileSizeLimit = (params)=>getAction("/erp/systemConfig/fileSizeLimit",params);
|
||||
//平台参数
|
||||
const addPlatformConfig = (params)=>postAction("/erp/platformConfig/add",params);
|
||||
const editPlatformConfig = (params)=>putAction("/erp/platformConfig/update",params);
|
||||
const getPlatformConfigByKey = (params)=>getAction("/erp/platformConfig/getPlatformConfigByKey",params);
|
||||
//用户|角色|模块关系
|
||||
const addUserBusiness = (params)=>postAction("/erp/userBusiness/add",params);
|
||||
const editUserBusiness = (params)=>putAction("/erp/userBusiness/update",params);
|
||||
const checkUserBusiness = (params)=>getAction("/erp/userBusiness/checkIsValueExist",params);
|
||||
const updateBtnStrByRoleId = (params)=>postAction("/erp/userBusiness/updateBtnStr",params);
|
||||
//计量单位
|
||||
const addUnit = (params)=>postAction("/erp/unit/add",params);
|
||||
const editUnit = (params)=>putAction("/erp/unit/update",params);
|
||||
const checkUnit = (params)=>getAction("/erp/unit/checkIsNameExist",params);
|
||||
//供应商|客户|会员
|
||||
const addSupplier = (params)=>postAction("/erp/supplier/add",params);
|
||||
const editSupplier = (params)=>putAction("/erp/supplier/update",params);
|
||||
const checkSupplier = (params)=>getAction("/erp/supplier/checkIsNameAndTypeExist",params);
|
||||
const findBySelectSup = (params)=>postAction("/erp/supplier/findBySelect_sup",params);
|
||||
const findBySelectCus = (params)=>postAction("/erp/supplier/findBySelect_cus",params);
|
||||
const findBySelectRetail = (params)=>postAction("/erp/supplier/findBySelect_retail",params);
|
||||
const findBySelectOrgan = (params)=>postAction("/erp/supplier/findBySelect_organ",params);
|
||||
//单据相关
|
||||
const findBillDetailByNumber = (params)=>getAction("/erp/depotHead/getDetailByNumber",params);
|
||||
const findStockByDepotAndBarCode = (params)=>getAction("/erp/depotItem/findStockByDepotAndBarCode",params);
|
||||
const getBatchNumberList = (params)=>getAction("/erp/depotItem/getBatchNumberList",params);
|
||||
const findFinancialDetailByNumber = (params)=>getAction("/erp/accountHead/getDetailByNumber",params);
|
||||
|
||||
//租户信息
|
||||
const getAlltenantInfo = (params)=>getAction("/erp/tenant/listAllTenant",params);
|
||||
export {
|
||||
getBuyAndSaleStatistics,
|
||||
buyOrSalePrice,
|
||||
checkTenant,
|
||||
editTenant,
|
||||
addRole,
|
||||
editRole,
|
||||
checkRole,
|
||||
roleAllList,
|
||||
registerUser,
|
||||
addUser,
|
||||
editUser,
|
||||
getUserList,
|
||||
queryPermissionsByUser,
|
||||
queryOrganizationTreeList,
|
||||
queryOrganizationById,
|
||||
checkOrganization,
|
||||
addPerson,
|
||||
editPerson,
|
||||
checkPerson,
|
||||
getPersonByType,
|
||||
getPersonByNumType,
|
||||
addAccount,
|
||||
editAccount,
|
||||
checkAccount,
|
||||
getAccount,
|
||||
addInOutItem,
|
||||
editInOutItem,
|
||||
checkInOutItem,
|
||||
findInOutItemByParam,
|
||||
addDepot,
|
||||
editDepot,
|
||||
checkDepot,
|
||||
editMaterialProperty,
|
||||
queryMaterialCategoryTreeList,
|
||||
queryMaterialCategoryById,
|
||||
checkMaterialCategory,
|
||||
addMaterial,
|
||||
editMaterial,
|
||||
checkMaterial,
|
||||
getMaterialBySelect,
|
||||
getSerialMaterialBySelect,
|
||||
getMaterialByBarCode,
|
||||
getMaxBarCode,
|
||||
checkMaterialBarCode,
|
||||
addSerialNumber,
|
||||
editSerialNumber,
|
||||
checkSerialNumber,
|
||||
batAddSerialNumber,
|
||||
getEnableSerialNumberList,
|
||||
addMaterialAttribute,
|
||||
editMaterialAttribute,
|
||||
checkMaterialAttribute,
|
||||
getAllMaterialAttribute,
|
||||
addFunction,
|
||||
editFunction,
|
||||
checkFunction,
|
||||
addSystemConfig,
|
||||
editSystemConfig,
|
||||
checkSystemConfig,
|
||||
getCurrentSystemConfig,
|
||||
fileSizeLimit,
|
||||
addPlatformConfig,
|
||||
editPlatformConfig,
|
||||
getPlatformConfigByKey,
|
||||
addUserBusiness,
|
||||
editUserBusiness,
|
||||
checkUserBusiness,
|
||||
updateBtnStrByRoleId,
|
||||
addUnit,
|
||||
editUnit,
|
||||
checkUnit,
|
||||
addSupplier,
|
||||
editSupplier,
|
||||
checkSupplier,
|
||||
findBySelectSup,
|
||||
findBySelectCus,
|
||||
findBySelectRetail,
|
||||
findBySelectOrgan,
|
||||
findBillDetailByNumber,
|
||||
findStockByDepotAndBarCode,
|
||||
getBatchNumberList,
|
||||
findFinancialDetailByNumber,
|
||||
getAlltenantInfo
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
import Vue from 'vue'
|
||||
import request from '@/utils/request'
|
||||
import { typeOf } from 'mathjs'
|
||||
import Cookies from 'js-cookie'
|
||||
|
||||
const api = {
|
||||
user: '/erp/api/user',
|
||||
role: '/erp/api/role',
|
||||
service: '/erp/api/service',
|
||||
permission: '/erp/api/permission',
|
||||
permissionNoPager: '/erp/api/permission/no-pager'
|
||||
}
|
||||
|
||||
export default api
|
||||
let startTime = Cookies.get('SEASON')?Cookies.get('SEASON').startTime:"2020-01-01 00:00:00";
|
||||
//post
|
||||
export function postAction(url,parameter) {
|
||||
parameter = {startTime:startTime,...parameter}
|
||||
return request({
|
||||
url: url,
|
||||
method:'post' ,
|
||||
data: parameter
|
||||
})
|
||||
}
|
||||
|
||||
//post method= {post | put}
|
||||
export function httpAction(url,parameter,method) {
|
||||
parameter = {startTime:startTime,...parameter}
|
||||
return request({
|
||||
url: url,
|
||||
method:method ,
|
||||
data: parameter
|
||||
})
|
||||
}
|
||||
|
||||
//put
|
||||
export function putAction(url,parameter) {
|
||||
parameter = {startTime:startTime,...parameter}
|
||||
return request({
|
||||
url: url,
|
||||
method:'put',
|
||||
data: parameter
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//get
|
||||
export function getAction(url,parameter) {
|
||||
parameter = {startTime:startTime,...parameter}
|
||||
return request({
|
||||
url: url,
|
||||
method: 'get',
|
||||
params: parameter
|
||||
})
|
||||
}
|
||||
|
||||
//deleteAction
|
||||
export function deleteAction(url,parameter) {
|
||||
parameter = {startTime:startTime,...parameter}
|
||||
return request({
|
||||
url: url,
|
||||
method: 'delete',
|
||||
params: parameter
|
||||
})
|
||||
}
|
||||
|
||||
export function getUserList(parameter) {
|
||||
parameter = {startTime:startTime,...parameter}
|
||||
return request({
|
||||
url: api.user,
|
||||
method: 'get',
|
||||
params: parameter
|
||||
})
|
||||
}
|
||||
|
||||
export function getRoleList(parameter) {
|
||||
parameter = {startTime:startTime,...parameter}
|
||||
return request({
|
||||
url: api.role,
|
||||
method: 'get',
|
||||
params: parameter
|
||||
})
|
||||
}
|
||||
|
||||
export function getServiceList(parameter) {
|
||||
parameter = {startTime:startTime,...parameter}
|
||||
return request({
|
||||
url: api.service,
|
||||
method: 'get',
|
||||
params: parameter
|
||||
})
|
||||
}
|
||||
|
||||
export function getPermissions(parameter) {
|
||||
parameter = {startTime:startTime,...parameter}
|
||||
return request({
|
||||
url: api.permissionNoPager,
|
||||
method: 'get',
|
||||
params: parameter
|
||||
})
|
||||
}
|
||||
|
||||
// id == 0 add post
|
||||
// id != 0 update put
|
||||
export function saveService(parameter) {
|
||||
return request({
|
||||
url: api.service,
|
||||
method: parameter.id == 0 ? 'post' : 'put',
|
||||
data: parameter
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载文件 用于excel导出
|
||||
* @param url
|
||||
* @param parameter
|
||||
* @returns {*}
|
||||
*/
|
||||
export function downFile(url,parameter){
|
||||
return request({
|
||||
url: url,
|
||||
params: parameter,
|
||||
method:'get' ,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载文件
|
||||
* @param url 文件路径
|
||||
* @param fileName 文件名
|
||||
* @param parameter
|
||||
* @returns {*}
|
||||
*/
|
||||
export function downloadFile(url, fileName, parameter) {
|
||||
return downFile(url, parameter).then((data) => {
|
||||
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对象
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传 用于富文本上传图片
|
||||
* @param url
|
||||
* @param parameter
|
||||
* @returns {*}
|
||||
*/
|
||||
export function uploadAction(url,parameter){
|
||||
return request({
|
||||
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'
|
||||
if(avatar && avatar.startsWith(subStr)){
|
||||
return avatar;
|
||||
}else{
|
||||
if(avatar && avatar.length>0 && avatar.indexOf('[')==-1){
|
||||
return window._CONFIG['domianURL'] + "/" + avatar;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
.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;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.resize-table-th {
|
||||
position: relative;
|
||||
.table-draggable-handle {
|
||||
transform: none !important;
|
||||
position: absolute;
|
||||
height: 100% !important;
|
||||
bottom: 0;
|
||||
left: auto !important;
|
||||
right: -5px;
|
||||
cursor: col-resize;
|
||||
touch-action: none;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*列表上方操作按钮区域*/
|
||||
.ant-card-body .table-operator {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
/** 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 {
|
||||
padding: 24px 24px 12px 24px;
|
||||
height: calc(100% - 110px) !important;
|
||||
overflow-y: auto
|
||||
}
|
||||
/*弹出modal 先有content后有body 故滚动条控制在body上*/
|
||||
.ant-modal-cust-warp .ant-modal-content {
|
||||
height: 90%;
|
||||
overflow-y: hidden
|
||||
}
|
||||
/*文本框样式*/
|
||||
.ant-modal-cust-warp .ant-form-item {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
/*商品-列表页面弹出modal*/
|
||||
.ant-modal-material-warp {
|
||||
height: 100%
|
||||
}
|
||||
/*商品-弹出modal Y轴滚动条*/
|
||||
.ant-modal-material-warp .ant-modal-body {
|
||||
padding: 12px 24px 12px 24px;
|
||||
height: calc(100% - 110px) !important;
|
||||
overflow-y: auto
|
||||
}
|
||||
/*商品-弹出modal 先有content后有body 故滚动条控制在body上*/
|
||||
.ant-modal-material-warp .ant-modal-content {
|
||||
height: 90%;
|
||||
overflow-y: hidden
|
||||
}
|
||||
/*商品-文本框样式*/
|
||||
.ant-modal-material-warp .ant-form-item {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
/*列表中有图片的加这个样式 参考用户管理*/
|
||||
.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;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* 列表查询通用样式,移动端自适应
|
||||
*/
|
||||
.search{
|
||||
margin-bottom: 54px;
|
||||
}
|
||||
.fold{
|
||||
width: calc(100% - 216px);
|
||||
display: inline-block
|
||||
}
|
||||
.operator{
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
@media screen and (max-width: 900px) {
|
||||
.fold {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.operator button {
|
||||
margin-right: 5px;
|
||||
}
|
||||
i {
|
||||
cursor: pointer;
|
||||
}
|
||||
.trcolor{
|
||||
background-color: rgba(255, 192, 203, 0.31);
|
||||
color:red;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<script>
|
||||
export default {
|
||||
name: 'Ellipsis',
|
||||
props: {
|
||||
prefixCls: {
|
||||
type: String,
|
||||
default: 'ant-pro-ellipsis'
|
||||
},
|
||||
tooltip: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
length: {
|
||||
type: Number,
|
||||
default: 25,
|
||||
},
|
||||
lines: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
fullWidthRecognition: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {},
|
||||
render() {
|
||||
const { tooltip, length } = this.$props
|
||||
let text = ''
|
||||
// 处理没有default插槽时的特殊情况
|
||||
if (this.$slots.default) {
|
||||
text = this.$slots.default.map(vNode => vNode.text).join('')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,3 @@
|
||||
import Ellipsis from './Ellipsis'
|
||||
|
||||
export default Ellipsis
|
||||
@@ -0,0 +1,135 @@
|
||||
<template>
|
||||
<a-popover title="自定义列" trigger="click" placement="leftBottom">
|
||||
<template slot="content">
|
||||
<a-checkbox-group @change="onColSettingsChange" v-model="settingColumns"
|
||||
:defaultValue="settingColumns" style="width: 400px;" >
|
||||
<a-row>
|
||||
<template v-for="(item,index) in defColumns_">
|
||||
<template v-if="!ignoreColumns.includes(item.key) && !ignoreColumns.includes(item.dataIndex)">
|
||||
<a-col :span="12"><a-checkbox :value="item.dataIndex" >{{ item.title }}</a-checkbox></a-col>
|
||||
</template>
|
||||
</template>
|
||||
</a-row>
|
||||
</a-checkbox-group>
|
||||
</template>
|
||||
<a-button type="link" icon="setting">自定义列</a-button>
|
||||
</a-popover>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from "vue";
|
||||
|
||||
export default {
|
||||
name: "ListColumnsSetter",
|
||||
|
||||
props: {
|
||||
columns:{
|
||||
type:Array,
|
||||
required: true
|
||||
},
|
||||
defColumns:{
|
||||
type:Array,
|
||||
required: true
|
||||
},
|
||||
ignoreColumns:{
|
||||
type: Array,
|
||||
default: () => ['rowIndex', 'action', 'flag']
|
||||
},
|
||||
listName:{
|
||||
type:String,
|
||||
default: '',
|
||||
}
|
||||
},
|
||||
|
||||
model: {
|
||||
prop: 'columns',
|
||||
event: 'change'
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
defColumns_: [],
|
||||
settingColumns:[]
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
ls_key() { return this.$route.name + '/' + this.listName + ':colsettings'},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.defColumns_.push(...this.defColumns);
|
||||
this.initColumns();
|
||||
},
|
||||
|
||||
methods: {
|
||||
initColumns(){
|
||||
//权限过滤(列权限控制时打开,修改第二个参数为授权码前缀)
|
||||
//this.defColumns_ = colAuthFilter(this.defColumns_,'testdemo:');
|
||||
|
||||
console.log(this.ls_key)
|
||||
let colSettings = Vue.ls.get(this.ls_key);
|
||||
let columns = [];
|
||||
if(colSettings===null||colSettings===undefined){
|
||||
let allSettingColumns = [];
|
||||
this.defColumns_.forEach(function (item,i,array ) {
|
||||
allSettingColumns.push(item.dataIndex);
|
||||
})
|
||||
this.settingColumns = allSettingColumns;
|
||||
columns = this.defColumns_;
|
||||
} else {
|
||||
this.settingColumns = colSettings;
|
||||
//默认隐藏列
|
||||
// this.settingColumns.forEach((item,index) => {
|
||||
// if(item == "model") {
|
||||
// this.settingColumns.splice(index,1)
|
||||
// }
|
||||
// if(item == "color") {
|
||||
// this.settingColumns.splice(index,1)
|
||||
// }
|
||||
// if(item == "categoryName") {
|
||||
// this.settingColumns.splice(index,1)
|
||||
// }
|
||||
// if(item == "materialOther") {
|
||||
// this.settingColumns.splice(index,1)
|
||||
// }
|
||||
// if(item == "commodityDecimal") {
|
||||
// this.settingColumns.splice(index,1)
|
||||
// }
|
||||
// if(item == "lowDecimal") {
|
||||
// this.settingColumns.splice(index,1)
|
||||
// }
|
||||
// })
|
||||
columns = this.defColumns_.filter(item => {
|
||||
if(this.ignoreColumns.includes(item.key) || this.ignoreColumns.includes(item.dataIndex)){
|
||||
return true;
|
||||
}
|
||||
if (colSettings.includes(item.dataIndex)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
})
|
||||
}
|
||||
this.$emit('change', columns);
|
||||
},
|
||||
|
||||
//列设置更改事件
|
||||
onColSettingsChange (checkedValues) {
|
||||
console.log("checkedValues",checkedValues);
|
||||
Vue.ls.set(this.ls_key, checkedValues, 7*24*60*60*1000)
|
||||
this.settingColumns = checkedValues;
|
||||
const columns = this.defColumns_.filter(item => {
|
||||
if(this.ignoreColumns.includes(item.key) || this.ignoreColumns.includes(item.dataIndex)){
|
||||
return true
|
||||
}
|
||||
if (this.settingColumns.includes(item.dataIndex)) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
this.$emit('change', columns);
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,155 @@
|
||||
<template>
|
||||
<div v-if="!reloading" class="j-area-linkage">
|
||||
<area-cascader
|
||||
v-if="_type === enums.type[0]"
|
||||
:value="innerValue"
|
||||
:data="pcaa"
|
||||
:level="1"
|
||||
:style="{width}"
|
||||
v-bind="$attrs"
|
||||
v-on="_listeners"
|
||||
@change="handleChange"
|
||||
/>
|
||||
<area-select
|
||||
v-else-if="_type === enums.type[1]"
|
||||
:value="innerValue"
|
||||
:data="pcaa"
|
||||
:level="2"
|
||||
v-bind="$attrs"
|
||||
v-on="_listeners"
|
||||
@change="handleChange"
|
||||
/>
|
||||
<div v-else>
|
||||
<span style="color:red;"> Bad type value: {{_type}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { pcaa } from 'area-data'
|
||||
|
||||
export default {
|
||||
name: 'JAreaLinkage',
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
required:false
|
||||
},
|
||||
// 组件的类型,可选值:
|
||||
// select 下拉样式
|
||||
// cascader 级联样式(默认)
|
||||
type: {
|
||||
type: String,
|
||||
default: 'cascader'
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '100%'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pcaa,
|
||||
innerValue: [],
|
||||
usedListeners: ['change'],
|
||||
enums: {
|
||||
type: ['cascader', 'select']
|
||||
},
|
||||
reloading: false,
|
||||
areaData:''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
_listeners() {
|
||||
let 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)
|
||||
}
|
||||
},
|
||||
},
|
||||
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();
|
||||
let arr = this.areaData.getRealCode(value);
|
||||
this.innerValue = arr
|
||||
}
|
||||
},
|
||||
/** 通过地区code获取子级 */
|
||||
loadDataByCode(value) {
|
||||
let options = []
|
||||
let data = pcaa[value]
|
||||
if (data) {
|
||||
for (let key in data) {
|
||||
if (data.hasOwnProperty(key)) {
|
||||
options.push({ value: key, label: data[key], })
|
||||
}
|
||||
}
|
||||
return options
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
},
|
||||
/** 判断是否有子节点 */
|
||||
hasChildren(options) {
|
||||
options.forEach(option => {
|
||||
let data = this.loadDataByCode(option.value)
|
||||
option.isLeaf = data.length === 0
|
||||
})
|
||||
},
|
||||
handleChange(values) {
|
||||
let 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;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,238 @@
|
||||
<template>
|
||||
<a-tree-select
|
||||
allowClear
|
||||
labelInValue
|
||||
style="width: 100%"
|
||||
:disabled="disabled"
|
||||
:dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
:placeholder="placeholder"
|
||||
:loadData="asyncLoadTreeData"
|
||||
:value="treeValue"
|
||||
:treeData="treeData"
|
||||
:multiple="multiple"
|
||||
@change="onChange">
|
||||
</a-tree-select>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
import { getAction } from '@/api/manage'
|
||||
|
||||
export default {
|
||||
name: 'JCategorySelect',
|
||||
props: {
|
||||
value:{
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
placeholder:{
|
||||
type: String,
|
||||
default: '请选择',
|
||||
required: false
|
||||
},
|
||||
disabled:{
|
||||
type:Boolean,
|
||||
default:false,
|
||||
required:false
|
||||
},
|
||||
condition:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
},
|
||||
// 是否支持多选
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
loadTriggleChange:{
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required:false
|
||||
},
|
||||
pid:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
},
|
||||
pcode:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
},
|
||||
back:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
treeValue:"",
|
||||
treeData:[],
|
||||
url:"/sys/category/loadTreeData",
|
||||
view:'/sys/category/loadDictItem/',
|
||||
tableName:"",
|
||||
text:"",
|
||||
code:"",
|
||||
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value () {
|
||||
this.loadItemByCode()
|
||||
},
|
||||
pcode(){
|
||||
this.loadRoot();
|
||||
}
|
||||
},
|
||||
created(){
|
||||
this.validateProp().then(()=>{
|
||||
this.loadRoot()
|
||||
this.loadItemByCode()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
/**加载一级节点 */
|
||||
loadRoot(){
|
||||
let param = {
|
||||
pid:this.pid,
|
||||
pcode:!this.pcode?'0':this.pcode,
|
||||
condition:this.condition
|
||||
}
|
||||
getAction(this.url,param).then(res=>{
|
||||
if(res.success && res.result){
|
||||
for(let i of res.result){
|
||||
i.value = i.key
|
||||
if(i.leaf==false){
|
||||
i.isLeaf=false
|
||||
}else if(i.leaf==true){
|
||||
i.isLeaf=true
|
||||
}
|
||||
}
|
||||
this.treeData = [...res.result]
|
||||
}else{
|
||||
console.log("树一级节点查询结果-else",res)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
/** 数据回显*/
|
||||
loadItemByCode(){
|
||||
if(!this.value || this.value=="0"){
|
||||
this.treeValue = []
|
||||
}else{
|
||||
getAction(this.view,{ids:this.value}).then(res=>{
|
||||
if(res.success){
|
||||
let values = this.value.split(',')
|
||||
this.treeValue = res.result.map((item, index) => ({
|
||||
key: values[index],
|
||||
value: values[index],
|
||||
label: item
|
||||
}))
|
||||
this.onLoadTriggleChange(res.result[0]);
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
onLoadTriggleChange(text){
|
||||
//只有单选才会触发
|
||||
if(!this.multiple && this.loadTriggleChange){
|
||||
this.backValue(this.value,text)
|
||||
}
|
||||
},
|
||||
backValue(value,label){
|
||||
let obj = {}
|
||||
if(this.back){
|
||||
obj[this.back] = label
|
||||
}
|
||||
this.$emit('change', value, obj)
|
||||
},
|
||||
asyncLoadTreeData (treeNode) {
|
||||
return new Promise((resolve) => {
|
||||
if (treeNode.$vnode.children) {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
let pid = treeNode.$vnode.key
|
||||
let param = {
|
||||
pid:pid,
|
||||
condition:this.condition
|
||||
}
|
||||
getAction(this.url,param).then(res=>{
|
||||
if(res.success){
|
||||
for(let i of res.result){
|
||||
i.value = i.key
|
||||
if(i.leaf==false){
|
||||
i.isLeaf=false
|
||||
}else if(i.leaf==true){
|
||||
i.isLeaf=true
|
||||
}
|
||||
}
|
||||
this.addChildren(pid,res.result,this.treeData)
|
||||
this.treeData = [...this.treeData]
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
},
|
||||
addChildren(pid,children,treeArray){
|
||||
if(treeArray && treeArray.length>0){
|
||||
for(let item of treeArray){
|
||||
if(item.key == pid){
|
||||
if(!children || children.length==0){
|
||||
item.isLeaf=true
|
||||
}else{
|
||||
item.children = children
|
||||
}
|
||||
break
|
||||
}else{
|
||||
this.addChildren(pid,children,item.children)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onChange(value){
|
||||
if(!value){
|
||||
this.$emit('change', '');
|
||||
this.treeValue = ''
|
||||
} else if (value instanceof Array) {
|
||||
//this.$emit('change', value.map(item => item.value).join(','))
|
||||
//this.treeValue = value
|
||||
} else {
|
||||
this.backValue(value.value,value.label)
|
||||
this.treeValue = value
|
||||
}
|
||||
},
|
||||
getCurrTreeData(){
|
||||
return this.treeData
|
||||
},
|
||||
validateProp(){
|
||||
let mycondition = this.condition
|
||||
return new Promise((resolve,reject)=>{
|
||||
if(!mycondition){
|
||||
resolve();
|
||||
}else{
|
||||
try {
|
||||
let test=JSON.parse(mycondition);
|
||||
if(typeof test == 'object' && test){
|
||||
resolve()
|
||||
}else{
|
||||
this.$message.error("组件JTreeSelect-condition传值有误,需要一个json字符串!")
|
||||
reject()
|
||||
}
|
||||
} catch(e) {
|
||||
this.$message.error("组件JTreeSelect-condition传值有误,需要一个json字符串!")
|
||||
reject()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
//2.2新增 在组件内定义 指定父组件调用时候的传值属性和事件类型 这个牛逼
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<a-checkbox-group :options="options" :value="checkboxArray" v-bind="$attrs" @change="onChange" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'JCheckbox',
|
||||
props: {
|
||||
value:{
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
/*label value*/
|
||||
options:{
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
checkboxArray:!this.value?[]:this.value.split(",")
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
value (val) {
|
||||
if(!val){
|
||||
this.checkboxArray = []
|
||||
}else{
|
||||
this.checkboxArray = this.value.split(",")
|
||||
}
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
onChange (checkedValues) {
|
||||
this.$emit('change', checkedValues.join(","));
|
||||
},
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,429 @@
|
||||
<template>
|
||||
<div v-bind="fullScreenParentProps">
|
||||
<a-icon v-if="fullScreen" class="full-screen-icon" :type="iconType" @click="()=>fullCoder=!fullCoder"/>
|
||||
|
||||
<div class="code-editor-cust full-screen-child">
|
||||
<textarea ref="textarea"></textarea>
|
||||
<span @click="nullTipClick" class="null-tip" :class="{'null-tip-hidden':hasCode}" :style="nullTipStyle">{{ placeholderShow }}</span>
|
||||
<template v-if="languageChange">
|
||||
<a-select v-model="mode" size="small" class="code-mode-select" @change="changeMode" placeholder="请选择主题">
|
||||
<a-select-option
|
||||
v-for="mode in modes"
|
||||
:key="mode.value"
|
||||
:value="mode.value">
|
||||
{{ mode.label }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script type="text/ecmascript-6">
|
||||
// 引入全局实例
|
||||
import _CodeMirror from 'codemirror'
|
||||
|
||||
// 核心样式
|
||||
import 'codemirror/lib/codemirror.css'
|
||||
// 引入主题后还需要在 options 中指定主题才会生效 darcula gruvbox-dark hopscotch monokai
|
||||
import 'codemirror/theme/panda-syntax.css'
|
||||
//提示css
|
||||
import "codemirror/addon/hint/show-hint.css";
|
||||
|
||||
// 需要引入具体的语法高亮库才会有对应的语法高亮效果
|
||||
// codemirror 官方其实支持通过 /addon/mode/loadmode.js 和 /mode/meta.js 来实现动态加载对应语法高亮库
|
||||
// 但 vue 貌似没有无法在实例初始化后再动态加载对应 JS ,所以此处才把对应的 JS 提前引入
|
||||
import 'codemirror/mode/javascript/javascript.js'
|
||||
import 'codemirror/mode/css/css.js'
|
||||
import 'codemirror/mode/xml/xml.js'
|
||||
import 'codemirror/mode/clike/clike.js'
|
||||
import 'codemirror/mode/markdown/markdown.js'
|
||||
import 'codemirror/mode/python/python.js'
|
||||
import 'codemirror/mode/r/r.js'
|
||||
import 'codemirror/mode/shell/shell.js'
|
||||
import 'codemirror/mode/sql/sql.js'
|
||||
import 'codemirror/mode/swift/swift.js'
|
||||
import 'codemirror/mode/vue/vue.js'
|
||||
|
||||
// 尝试获取全局实例
|
||||
const CodeMirror = window.CodeMirror || _CodeMirror
|
||||
|
||||
export default {
|
||||
name: 'JCodeEditor',
|
||||
props: {
|
||||
// 外部传入的内容,用于实现双向绑定
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// 外部传入的语法类型
|
||||
language: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
languageChange:{
|
||||
type: Boolean,
|
||||
default:false,
|
||||
required:false
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
// 显示行号
|
||||
lineNumbers: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 是否显示全屏按钮
|
||||
fullScreen: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 全屏以后的z-index
|
||||
zIndex: {
|
||||
type: [Number, String],
|
||||
default: 999
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
// 内部真实的内容
|
||||
code: '',
|
||||
iconType: 'fullscreen',
|
||||
hasCode:false,
|
||||
// 默认的语法类型
|
||||
mode: 'javascript',
|
||||
// 编辑器实例
|
||||
coder: null,
|
||||
// 默认配置
|
||||
options: {
|
||||
// 缩进格式
|
||||
tabSize: 2,
|
||||
// 主题,对应主题库 JS 需要提前引入
|
||||
theme: 'panda-syntax',
|
||||
line: true,
|
||||
// extraKeys: {'Ctrl': 'autocomplete'},//自定义快捷键
|
||||
hintOptions: {
|
||||
tables: {
|
||||
users: ['name', 'score', 'birthDate'],
|
||||
countries: ['name', 'population', 'size']
|
||||
}
|
||||
},
|
||||
},
|
||||
// 支持切换的语法高亮类型,对应 JS 已经提前引入
|
||||
// 使用的是 MIME-TYPE ,不过作为前缀的 text/ 在后面指定时写死了
|
||||
modes: [{
|
||||
value: 'css',
|
||||
label: 'CSS'
|
||||
}, {
|
||||
value: 'javascript',
|
||||
label: 'Javascript'
|
||||
}, {
|
||||
value: 'html',
|
||||
label: 'XML/HTML'
|
||||
}, {
|
||||
value: 'x-java',
|
||||
label: 'Java'
|
||||
}, {
|
||||
value: 'x-objectivec',
|
||||
label: 'Objective-C'
|
||||
}, {
|
||||
value: 'x-python',
|
||||
label: 'Python'
|
||||
}, {
|
||||
value: 'x-rsrc',
|
||||
label: 'R'
|
||||
}, {
|
||||
value: 'x-sh',
|
||||
label: 'Shell'
|
||||
}, {
|
||||
value: 'x-sql',
|
||||
label: 'SQL'
|
||||
}, {
|
||||
value: 'x-swift',
|
||||
label: 'Swift'
|
||||
}, {
|
||||
value: 'x-vue',
|
||||
label: 'Vue'
|
||||
}, {
|
||||
value: 'markdown',
|
||||
label: 'Markdown'
|
||||
}],
|
||||
// code 编辑器 是否全屏
|
||||
fullCoder: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
fullCoder:{
|
||||
handler(value) {
|
||||
if(value){
|
||||
this.iconType="fullscreen-exit"
|
||||
}else{
|
||||
this.iconType="fullscreen"
|
||||
}
|
||||
}
|
||||
},
|
||||
// value: {
|
||||
// immediate: false,
|
||||
// handler(value) {
|
||||
// this._getCoder().then(() => {
|
||||
// this.coder.setValue(value)
|
||||
// })
|
||||
// }
|
||||
// },
|
||||
language: {
|
||||
immediate: true,
|
||||
handler(language) {
|
||||
this._getCoder().then(() => {
|
||||
// 尝试从父容器获取语法类型
|
||||
if (language) {
|
||||
// 获取具体的语法类型对象
|
||||
let modeObj = this._getLanguage(language)
|
||||
|
||||
// 判断父容器传入的语法是否被支持
|
||||
if (modeObj) {
|
||||
this.mode = modeObj.label
|
||||
this.coder.setOption('mode', `text/${modeObj.value}`)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
placeholderShow() {
|
||||
if (this.placeholder == null) {
|
||||
return `请在此输入${this.language}代码`
|
||||
} else {
|
||||
return this.placeholder
|
||||
}
|
||||
},
|
||||
nullTipStyle(){
|
||||
if (this.lineNumbers) {
|
||||
return { left: '36px' }
|
||||
} else {
|
||||
return { left: '12px' }
|
||||
}
|
||||
},
|
||||
// coder 配置
|
||||
coderOptions() {
|
||||
return {
|
||||
tabSize: this.options.tabSize,
|
||||
theme: this.options.theme,
|
||||
lineNumbers: this.lineNumbers,
|
||||
line: true,
|
||||
hintOptions: this.options.hintOptions
|
||||
}
|
||||
},
|
||||
fullScreenParentProps(){
|
||||
let props = {
|
||||
class: ['full-screen-parent', this.fullCoder ? 'full-screen' : ''],
|
||||
style: {}
|
||||
}
|
||||
if (this.fullCoder) {
|
||||
props.style['z-index'] = this.zIndex
|
||||
}
|
||||
return props
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
// 初始化
|
||||
this._initialize()
|
||||
},
|
||||
methods: {
|
||||
// 初始化
|
||||
_initialize () {
|
||||
// 初始化编辑器实例,传入需要被实例化的文本域对象和默认配置
|
||||
this.coder = CodeMirror.fromTextArea(this.$refs.textarea, this.coderOptions)
|
||||
// 编辑器赋值
|
||||
if(this.value||this.code){
|
||||
this.hasCode=true
|
||||
this.coder.setValue(this.value || this.code)
|
||||
}else{
|
||||
this.coder.setValue('')
|
||||
this.hasCode=false
|
||||
}
|
||||
// 支持双向绑定
|
||||
this.coder.on('change', (coder) => {
|
||||
this.code = coder.getValue()
|
||||
if(this.code){
|
||||
this.hasCode=true
|
||||
}else{
|
||||
this.hasCode=false
|
||||
}
|
||||
if (this.$emit) {
|
||||
this.$emit('input', this.code)
|
||||
}
|
||||
})
|
||||
this.coder.on('focus', () => {
|
||||
this.hasCode=true
|
||||
})
|
||||
this.coder.on('blur', () => {
|
||||
if(this.code){
|
||||
this.hasCode=true
|
||||
}else{
|
||||
this.hasCode=false
|
||||
}
|
||||
})
|
||||
|
||||
/* this.coder.on('cursorActivity',()=>{
|
||||
this.coder.showHint()
|
||||
})*/
|
||||
|
||||
},
|
||||
getCodeContent(){
|
||||
return this.code
|
||||
},
|
||||
setCodeContent(val){
|
||||
setTimeout(()=>{
|
||||
if(!val){
|
||||
this.coder.setValue('')
|
||||
}else{
|
||||
this.coder.setValue(val)
|
||||
}
|
||||
},300)
|
||||
},
|
||||
// 获取当前语法类型
|
||||
_getLanguage (language) {
|
||||
// 在支持的语法类型列表中寻找传入的语法类型
|
||||
return this.modes.find((mode) => {
|
||||
// 所有的值都忽略大小写,方便比较
|
||||
let currentLanguage = language.toLowerCase()
|
||||
let currentLabel = mode.label.toLowerCase()
|
||||
let currentValue = mode.value.toLowerCase()
|
||||
|
||||
// 由于真实值可能不规范,例如 java 的真实值是 x-java ,所以讲 value 和 label 同时和传入语法进行比较
|
||||
return currentLabel === currentLanguage || currentValue === currentLanguage
|
||||
})
|
||||
},
|
||||
_getCoder() {
|
||||
let _this = this
|
||||
return new Promise((resolve) => {
|
||||
(function get() {
|
||||
if (_this.coder) {
|
||||
resolve(_this.coder)
|
||||
} else {
|
||||
setTimeout(get, 10)
|
||||
}
|
||||
})()
|
||||
})
|
||||
},
|
||||
// 更改模式
|
||||
changeMode (val) {
|
||||
// 修改编辑器的语法配置
|
||||
this.coder.setOption('mode', `text/${val}`)
|
||||
|
||||
// 获取修改后的语法
|
||||
let label = this._getLanguage(val).label.toLowerCase()
|
||||
|
||||
// 允许父容器通过以下函数监听当前的语法值
|
||||
this.$emit('language-change', label)
|
||||
},
|
||||
nullTipClick(){
|
||||
this.coder.focus()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.code-editor-cust{
|
||||
flex-grow:1;
|
||||
display:flex;
|
||||
position:relative;
|
||||
height:100%;
|
||||
.CodeMirror{
|
||||
flex-grow:1;
|
||||
z-index:1;
|
||||
.CodeMirror-code{
|
||||
line-height:19px;
|
||||
}
|
||||
|
||||
}
|
||||
.code-mode-select{
|
||||
position:absolute;
|
||||
z-index:2;
|
||||
right:10px;
|
||||
top:10px;
|
||||
max-width:130px;
|
||||
}
|
||||
.CodeMirror{
|
||||
height: auto;
|
||||
min-height:100%;
|
||||
}
|
||||
.null-tip{
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 36px;
|
||||
z-index: 10;
|
||||
color: #ffffffc9;
|
||||
line-height: initial;
|
||||
}
|
||||
.null-tip-hidden{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* 全屏样式 */
|
||||
.full-screen-parent {
|
||||
position: relative;
|
||||
|
||||
.full-screen-icon {
|
||||
opacity: 0;
|
||||
color: black;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
line-height: 24px;
|
||||
background-color: white;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 2px;
|
||||
z-index: 9;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.full-screen-icon {
|
||||
opacity: 1;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(255, 255, 255, 0.88);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.full-screen {
|
||||
position: fixed;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
width: calc(100% - 20px);
|
||||
height: calc(100% - 20px);
|
||||
padding: 10px;
|
||||
background-color: #f5f5f5;
|
||||
|
||||
.full-screen-icon {
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
}
|
||||
.full-screen-child {
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
min-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.full-screen-child {
|
||||
min-height: 120px;
|
||||
max-height: 320px;
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.CodeMirror-cursor{
|
||||
height:18.4px !important;
|
||||
}
|
||||
</style>
|
||||
@@ -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>
|
||||
@@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<a-date-picker
|
||||
:disabled="disabled || readOnly"
|
||||
:placeholder="placeholder"
|
||||
@change="handleDateChange"
|
||||
:value="momVal"
|
||||
:showTime="showTime"
|
||||
:format="dateFormat"
|
||||
:getCalendarContainer="getCalendarContainer"
|
||||
/>
|
||||
</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 HH:mm:ss',
|
||||
required: false
|
||||
},
|
||||
//此属性可以被废弃了
|
||||
triggerChange:{
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
readOnly:{
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
disabled:{
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
showTime:{
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
getCalendarContainer: {
|
||||
type: Function,
|
||||
default: (node) => node.parentNode
|
||||
}
|
||||
},
|
||||
data () {
|
||||
let dateStr = this.value;
|
||||
return {
|
||||
decorator:"",
|
||||
momVal:!dateStr?null:moment(dateStr,this.dateFormat)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value (val) {
|
||||
if(!val){
|
||||
this.momVal = null
|
||||
}else{
|
||||
this.momVal = moment(val,this.dateFormat)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
moment,
|
||||
handleDateChange(mom,dateStr){
|
||||
this.$emit('change', dateStr);
|
||||
}
|
||||
},
|
||||
//2.2新增 在组件内定义 指定父组件调用时候的传值属性和事件类型 这个牛逼
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<a-tooltip placement="topLeft">
|
||||
<template slot="title">
|
||||
<span>{{value}}</span>
|
||||
</template>
|
||||
{{ value | ellipsis(length) }}
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'JEllipsis',
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
required: false,
|
||||
},
|
||||
length: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 25,
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<div :class="disabled?'jeecg-form-container-disabled':''">
|
||||
<fieldset :disabled="disabled">
|
||||
<slot name="detail"></slot>
|
||||
</fieldset>
|
||||
<slot name="edit"></slot>
|
||||
<fieldset disabled>
|
||||
<slot></slot>
|
||||
</fieldset>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 使用方法
|
||||
* 在form下直接写这个组件就行了,
|
||||
*<a-form layout="inline" :form="form" >
|
||||
* <j-form-container :disabled="true">
|
||||
* <!-- 表单内容省略..... -->
|
||||
* </j-form-container>
|
||||
*</a-form>
|
||||
*/
|
||||
export default {
|
||||
name: 'JFormContainer',
|
||||
props:{
|
||||
disabled:{
|
||||
type:Boolean,
|
||||
default:false,
|
||||
required:false
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
console.log("我是表单禁用专用组件,但是我并不支持表单中iframe的内容禁用")
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.jeecg-form-container-disabled{
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.jeecg-form-container-disabled fieldset[disabled] {
|
||||
-ms-pointer-events: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
.jeecg-form-container-disabled .ant-select{
|
||||
-ms-pointer-events: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.jeecg-form-container-disabled .ant-upload-select{display:none}
|
||||
.jeecg-form-container-disabled .ant-upload-list{cursor:grabbing}
|
||||
.jeecg-form-container-disabled fieldset[disabled] .ant-upload-list{
|
||||
-ms-pointer-events: auto !important;
|
||||
pointer-events: auto !important;
|
||||
}
|
||||
|
||||
.jeecg-form-container-disabled .ant-upload-list-item-actions .anticon-delete,
|
||||
.jeecg-form-container-disabled .ant-upload-list-item .anticon-close{
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,202 @@
|
||||
<template>
|
||||
<div class="gc-canvas" @click="reloadPic">
|
||||
<canvas id="gc-canvas" :width="contentWidth" :height="contentHeight"></canvas>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getAction } from '@/api/manage'
|
||||
|
||||
export default {
|
||||
name: 'JGraphicCode',
|
||||
props: {
|
||||
length:{
|
||||
type: Number,
|
||||
default: 4
|
||||
},
|
||||
fontSizeMin: {
|
||||
type: Number,
|
||||
default: 20
|
||||
},
|
||||
fontSizeMax: {
|
||||
type: Number,
|
||||
default: 45
|
||||
},
|
||||
backgroundColorMin: {
|
||||
type: Number,
|
||||
default: 180
|
||||
},
|
||||
backgroundColorMax: {
|
||||
type: Number,
|
||||
default: 240
|
||||
},
|
||||
colorMin: {
|
||||
type: Number,
|
||||
default: 50
|
||||
},
|
||||
colorMax: {
|
||||
type: Number,
|
||||
default: 160
|
||||
},
|
||||
lineColorMin: {
|
||||
type: Number,
|
||||
default: 40
|
||||
},
|
||||
lineColorMax: {
|
||||
type: Number,
|
||||
default: 180
|
||||
},
|
||||
dotColorMin: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
dotColorMax: {
|
||||
type: Number,
|
||||
default: 255
|
||||
},
|
||||
contentWidth: {
|
||||
type: Number,
|
||||
default:136
|
||||
},
|
||||
contentHeight: {
|
||||
type: Number,
|
||||
default: 38
|
||||
},
|
||||
remote:{
|
||||
type:Boolean,
|
||||
default:false,
|
||||
required:false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 生成一个随机数
|
||||
randomNum (min, max) {
|
||||
return Math.floor(Math.random() * (max - min) + min)
|
||||
},
|
||||
// 生成一个随机的颜色
|
||||
randomColor (min, max) {
|
||||
let r = this.randomNum(min, max)
|
||||
let g = this.randomNum(min, max)
|
||||
let b = this.randomNum(min, max)
|
||||
return 'rgb(' + r + ',' + g + ',' + b + ')'
|
||||
},
|
||||
drawPic () {
|
||||
this.randomCode().then(()=>{
|
||||
let canvas = document.getElementById('gc-canvas')
|
||||
let ctx = canvas.getContext('2d')
|
||||
ctx.textBaseline = 'bottom'
|
||||
// 绘制背景
|
||||
ctx.fillStyle = this.randomColor(this.backgroundColorMin, this.backgroundColorMax)
|
||||
ctx.fillRect(0, 0, this.contentWidth, this.contentHeight)
|
||||
// 绘制文字
|
||||
for (let i = 0; i < this.code.length; i++) {
|
||||
this.drawText(ctx, this.code[i], i)
|
||||
}
|
||||
this.drawLine(ctx)
|
||||
this.drawDot(ctx)
|
||||
this.$emit("success",this.code)
|
||||
})
|
||||
},
|
||||
drawText (ctx, txt, i) {
|
||||
ctx.fillStyle = this.randomColor(this.colorMin, this.colorMax)
|
||||
let fontSize = this.randomNum(this.fontSizeMin, this.fontSizeMax)
|
||||
ctx.font = fontSize + 'px SimHei'
|
||||
let padding = 10;
|
||||
let offset = (this.contentWidth-40)/(this.code.length-1)
|
||||
let x=padding;
|
||||
if(i>0){
|
||||
x = padding+(i*offset)
|
||||
}
|
||||
//let x = (i + 1) * (this.contentWidth / (this.code.length + 1))
|
||||
let y = this.randomNum(this.fontSizeMax, this.contentHeight - 5)
|
||||
if(fontSize>40){
|
||||
y=40
|
||||
}
|
||||
var deg = this.randomNum(-10,10)
|
||||
// 修改坐标原点和旋转角度
|
||||
ctx.translate(x, y)
|
||||
ctx.rotate(deg * Math.PI / 180)
|
||||
ctx.fillText(txt, 0, 0)
|
||||
// 恢复坐标原点和旋转角度
|
||||
ctx.rotate(-deg * Math.PI / 180)
|
||||
ctx.translate(-x, -y)
|
||||
},
|
||||
drawLine (ctx) {
|
||||
// 绘制干扰线
|
||||
for (let i = 0; i <1; i++) {
|
||||
ctx.strokeStyle = this.randomColor(this.lineColorMin, this.lineColorMax)
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight))
|
||||
ctx.lineTo(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight))
|
||||
ctx.stroke()
|
||||
}
|
||||
},
|
||||
drawDot (ctx) {
|
||||
// 绘制干扰点
|
||||
for (let i = 0; i < 100; i++) {
|
||||
ctx.fillStyle = this.randomColor(0, 255)
|
||||
ctx.beginPath()
|
||||
ctx.arc(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight), 1, 0, 2 * Math.PI)
|
||||
ctx.fill()
|
||||
}
|
||||
},
|
||||
reloadPic(){
|
||||
this.drawPic()
|
||||
},
|
||||
randomCode(){
|
||||
return new Promise((resolve)=>{
|
||||
if(this.remote==true){
|
||||
getAction("/sys/getCheckCode").then(res=>{
|
||||
if(res.success){
|
||||
this.checkKey = res.result.key
|
||||
this.code = window.atob(res.result.code)
|
||||
resolve();
|
||||
}else{
|
||||
this.$message.error("生成验证码错误,请联系系统管理员")
|
||||
this.code = 'BUG'
|
||||
resolve();
|
||||
}
|
||||
}).catch(()=>{
|
||||
console.log("生成验证码连接服务器异常")
|
||||
this.code = 'BUG'
|
||||
resolve();
|
||||
})
|
||||
}else{
|
||||
this.randomLocalCode();
|
||||
resolve();
|
||||
}
|
||||
})
|
||||
},
|
||||
randomLocalCode(){
|
||||
let random = ''
|
||||
//去掉了I l i o O
|
||||
let str = "QWERTYUPLKJHGFDSAZXCVBNMqwertyupkjhgfdsazxcvbnm1234567890"
|
||||
for(let i = 0; i < this.length; i++) {
|
||||
let index = Math.floor(Math.random()*57);
|
||||
random += str[index];
|
||||
}
|
||||
this.code = random
|
||||
},
|
||||
getLoginParam(){
|
||||
return {
|
||||
checkCode:this.code,
|
||||
checkKey:this.checkKey
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.drawPic()
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
code:"",
|
||||
checkKey:""
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,226 @@
|
||||
<template>
|
||||
<a-upload
|
||||
name="file"
|
||||
listType="picture-card"
|
||||
:multiple="isMultiple"
|
||||
:action="uploadAction"
|
||||
:headers="headers"
|
||||
:data="{biz:bizPath}"
|
||||
:fileList="fileList"
|
||||
:beforeUpload="beforeUpload"
|
||||
:disabled="disabled"
|
||||
:isMultiple="isMultiple"
|
||||
:showUploadList="isMultiple"
|
||||
@change="handleChange"
|
||||
@preview="handlePreview">
|
||||
<img v-if="!isMultiple && picUrl" :src="getAvatarView()" style="height:104px;max-width:300px"/>
|
||||
<div v-else >
|
||||
<a-icon :type="uploadLoading ? 'loading' : 'plus'" />
|
||||
<div class="ant-upload-text">{{ text }}</div>
|
||||
</div>
|
||||
<a-modal :visible="previewVisible" :width="1000" :footer="null" @cancel="handleCancel()">
|
||||
<img alt="example" style="width: 100%" :src="previewImage"/>
|
||||
</a-modal>
|
||||
</a-upload>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import { getFileAccessHttpUrl } from '@/api/manage'
|
||||
import { fileSizeLimit } from '@/api/api'
|
||||
|
||||
const uidGenerator=()=>{
|
||||
return '-'+parseInt(Math.random()*10000+1,10);
|
||||
}
|
||||
const getFileName=(path)=>{
|
||||
if(path.lastIndexOf("\\")>=0){
|
||||
let reg=new RegExp("\\\\","g");
|
||||
path = path.replace(reg,"/");
|
||||
}
|
||||
return path.substring(path.lastIndexOf("/")+1);
|
||||
}
|
||||
export default {
|
||||
name: 'JImageUpload',
|
||||
data(){
|
||||
return {
|
||||
uploadAction:window._CONFIG['domianURL']+"/systemConfig/upload",
|
||||
uploadLoading:false,
|
||||
picUrl:false,
|
||||
headers:{},
|
||||
fileList: [],
|
||||
previewImage:"",
|
||||
previewVisible: false,
|
||||
sizeLimit: 0,
|
||||
uploadGoOn:true,
|
||||
}
|
||||
},
|
||||
props:{
|
||||
text:{
|
||||
type:String,
|
||||
required:false,
|
||||
default:"上传"
|
||||
},
|
||||
/*这个属性用于控制文件上传的业务路径*/
|
||||
bizPath:{
|
||||
type:String,
|
||||
required:false,
|
||||
default:"temp"
|
||||
},
|
||||
value:{
|
||||
type:[String,Array],
|
||||
required:false
|
||||
},
|
||||
disabled:{
|
||||
type:Boolean,
|
||||
required:false,
|
||||
default: false
|
||||
},
|
||||
isMultiple:{
|
||||
type:Boolean,
|
||||
required:false,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
value(val){
|
||||
if (val instanceof Array) {
|
||||
this.initFileList(val.join(','))
|
||||
} else {
|
||||
this.initFileList(val)
|
||||
}
|
||||
}
|
||||
},
|
||||
created(){
|
||||
this.initFileSizeLimit()
|
||||
this.headers = {"X-Access-Token":""}
|
||||
},
|
||||
methods:{
|
||||
initFileSizeLimit() {
|
||||
fileSizeLimit().then((res)=>{
|
||||
if(res.code === 200) {
|
||||
this.sizeLimit = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
initFileList(paths){
|
||||
if(!paths || paths.length==0){
|
||||
this.fileList = [];
|
||||
this.picUrl = false;
|
||||
return;
|
||||
}
|
||||
this.picUrl = true;
|
||||
let fileList = [];
|
||||
let arr = paths.split(",")
|
||||
for(var a=0;a<arr.length;a++){
|
||||
let url = getFileAccessHttpUrl(arr[a]);
|
||||
fileList.push({
|
||||
uid: uidGenerator(),
|
||||
name: getFileName(arr[a]),
|
||||
status: 'done',
|
||||
url: url,
|
||||
response:{
|
||||
code:"history",
|
||||
data:arr[a]
|
||||
}
|
||||
})
|
||||
}
|
||||
this.fileList = fileList
|
||||
},
|
||||
beforeUpload: function(file){
|
||||
this.uploadGoOn=true
|
||||
let fileType = file.type;
|
||||
let fileSize = file.size;
|
||||
if(fileType.indexOf('image')<0){
|
||||
this.$message.warning('请上传图片');
|
||||
this.uploadGoOn=false
|
||||
return false;
|
||||
}
|
||||
//验证文件大小
|
||||
if(fileSize>this.sizeLimit) {
|
||||
let parseSizeLimit = (this.sizeLimit/1024/1024).toFixed(2)
|
||||
this.$message.warning('抱歉,图片大小不能超过' + parseSizeLimit + 'M');
|
||||
this.uploadGoOn=false
|
||||
return false;
|
||||
}
|
||||
return true
|
||||
},
|
||||
handleChange(info) {
|
||||
console.log(info,"--文件列表改变--")
|
||||
if(!info.file.status && this.uploadGoOn === false){
|
||||
info.fileList.pop();
|
||||
}
|
||||
this.picUrl = false;
|
||||
let fileList = info.fileList
|
||||
if(info.file.status==='done'){
|
||||
if(info.file.response.code === 200){
|
||||
this.picUrl = true;
|
||||
fileList = fileList.map((file) => {
|
||||
if (file.response) {
|
||||
file.url = file.response.data;
|
||||
}
|
||||
return file;
|
||||
});
|
||||
}
|
||||
//this.$message.success(`${info.file.name} 上传成功!`);
|
||||
}else if (info.file.status === 'error') {
|
||||
this.$message.error(`${info.file.name} 上传失败.`);
|
||||
}else if(info.file.status === 'removed'){
|
||||
this.handleDelete(info.file)
|
||||
}
|
||||
this.fileList = fileList
|
||||
if(info.file.status==='done' || info.file.status === 'removed'){
|
||||
this.handlePathChange()
|
||||
}
|
||||
},
|
||||
// 预览
|
||||
handlePreview (file) {
|
||||
this.previewImage = file.url || file.thumbUrl
|
||||
this.previewVisible = true
|
||||
},
|
||||
getAvatarView(){
|
||||
if(this.fileList.length>0){
|
||||
let url = this.fileList[0].url
|
||||
return url
|
||||
}
|
||||
},
|
||||
handlePathChange(){
|
||||
let uploadFiles = this.fileList
|
||||
let path = ''
|
||||
if(!uploadFiles || uploadFiles.length==0){
|
||||
path = ''
|
||||
}
|
||||
let arr = [];
|
||||
if(!this.isMultiple){
|
||||
arr.push(uploadFiles[uploadFiles.length-1].response.data)
|
||||
}else{
|
||||
for(var a=0;a<uploadFiles.length;a++){
|
||||
arr.push(uploadFiles[a].response.data)
|
||||
}
|
||||
}
|
||||
if(arr.length>0){
|
||||
path = arr.join(",")
|
||||
}
|
||||
this.$emit('change', path);
|
||||
},
|
||||
handleDelete(file){
|
||||
//如有需要新增 删除逻辑
|
||||
console.log(file)
|
||||
},
|
||||
handleCancel() {
|
||||
this.close();
|
||||
this.previewVisible = false;
|
||||
},
|
||||
close () {
|
||||
|
||||
},
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,123 @@
|
||||
<template>
|
||||
<a-modal
|
||||
title="导入EXCEL"
|
||||
:width="600"
|
||||
:visible="visible"
|
||||
:confirmLoading="uploading"
|
||||
@cancel="handleClose">
|
||||
|
||||
<a-upload
|
||||
name="file"
|
||||
:multiple="true"
|
||||
accept=".xls,.xlsx"
|
||||
:fileList="fileList"
|
||||
:remove="handleRemove"
|
||||
:beforeUpload="beforeUpload">
|
||||
<a-button>
|
||||
<a-icon type="upload" />
|
||||
选择导入文件
|
||||
</a-button>
|
||||
</a-upload>
|
||||
|
||||
<template slot="footer">
|
||||
<a-button @click="handleClose">关闭</a-button>
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="handleImport"
|
||||
:disabled="fileList.length === 0"
|
||||
:loading="uploading">
|
||||
{{ uploading ? '上传中...' : '开始上传' }}
|
||||
</a-button>
|
||||
</template>
|
||||
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { postAction } from '@/api/manage'
|
||||
export default {
|
||||
name: 'JImportModal',
|
||||
props:{
|
||||
url:{
|
||||
type: String,
|
||||
default: '',
|
||||
required: false
|
||||
},
|
||||
biz:{
|
||||
type: String,
|
||||
default: '',
|
||||
required: false
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
visible:false,
|
||||
uploading:false,
|
||||
fileList:[],
|
||||
uploadAction:'',
|
||||
foreignKeys:''
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
url (val) {
|
||||
if(val){
|
||||
this.uploadAction = window._CONFIG['domianURL']+val
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.uploadAction = window._CONFIG['domianURL']+this.url
|
||||
},
|
||||
|
||||
methods:{
|
||||
handleClose(){
|
||||
this.visible=false
|
||||
},
|
||||
show(arg){
|
||||
this.fileList = []
|
||||
this.uploading = false
|
||||
this.visible = true
|
||||
this.foreignKeys = arg;
|
||||
},
|
||||
handleRemove(file) {
|
||||
const index = this.fileList.indexOf(file);
|
||||
const newFileList = this.fileList.slice();
|
||||
newFileList.splice(index, 1);
|
||||
this.fileList = newFileList
|
||||
},
|
||||
beforeUpload(file) {
|
||||
this.fileList = [...this.fileList, file]
|
||||
return false;
|
||||
},
|
||||
handleImport() {
|
||||
const { fileList } = this;
|
||||
const formData = new FormData();
|
||||
if(this.biz){
|
||||
formData.append('isSingleTableImport',this.biz);
|
||||
}
|
||||
if(this.foreignKeys && this.foreignKeys.length>0){
|
||||
formData.append('foreignKeys',this.foreignKeys);
|
||||
}
|
||||
fileList.forEach((file) => {
|
||||
formData.append('files[]', file);
|
||||
});
|
||||
this.uploading = true
|
||||
postAction(this.uploadAction, formData).then((res) => {
|
||||
this.uploading = false
|
||||
if(res.success){
|
||||
this.$message.success(res.message)
|
||||
this.visible=false
|
||||
this.$emit('ok')
|
||||
}else{
|
||||
this.$message.warning(res.message)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<a-input :placeholder="placeholder" :value="inputVal" @input="backValue"></a-input>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const JINPUT_QUERY_LIKE = 'like';
|
||||
const JINPUT_QUERY_NE = 'ne';
|
||||
const JINPUT_QUERY_GE = 'ge'; //大于等于
|
||||
const JINPUT_QUERY_LE = 'le'; //小于等于
|
||||
|
||||
export default {
|
||||
name: 'JInput',
|
||||
props:{
|
||||
value:{
|
||||
type:String,
|
||||
required:false
|
||||
},
|
||||
type:{
|
||||
type:String,
|
||||
required:false,
|
||||
default:JINPUT_QUERY_LIKE
|
||||
},
|
||||
placeholder:{
|
||||
type:String,
|
||||
required:false,
|
||||
default:''
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
value:{
|
||||
immediate:true,
|
||||
handler:function(){
|
||||
this.initVal();
|
||||
}
|
||||
},
|
||||
// update-begin author:sunjianlei date:20200225 for:当 type 变化的时候重新计算值 ------
|
||||
type() {
|
||||
this.backValue({ target: { value: this.inputVal } })
|
||||
},
|
||||
// update-end author:sunjianlei date:20200225 for:当 type 变化的时候重新计算值 ------
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
inputVal:''
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
initVal(){
|
||||
if(!this.value){
|
||||
this.inputVal = ''
|
||||
}else{
|
||||
let text = this.value
|
||||
switch (this.type) {
|
||||
case JINPUT_QUERY_LIKE:
|
||||
text = text.substring(1,text.length-1);
|
||||
break;
|
||||
case JINPUT_QUERY_NE:
|
||||
text = text.substring(1);
|
||||
break;
|
||||
case JINPUT_QUERY_GE:
|
||||
text = text.substring(2);
|
||||
break;
|
||||
case JINPUT_QUERY_LE:
|
||||
text = text.substring(2);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
this.inputVal = text
|
||||
}
|
||||
},
|
||||
backValue(e){
|
||||
let text = e.target.value
|
||||
switch (this.type) {
|
||||
case JINPUT_QUERY_LIKE:
|
||||
text = "*"+text+"*";
|
||||
break;
|
||||
case JINPUT_QUERY_NE:
|
||||
text = "!"+text;
|
||||
break;
|
||||
case JINPUT_QUERY_GE:
|
||||
text = ">="+text;
|
||||
break;
|
||||
case JINPUT_QUERY_LE:
|
||||
text = "<="+text;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
this.$emit("change",text)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,237 @@
|
||||
<template>
|
||||
<a-modal
|
||||
ref="modal"
|
||||
:class="getClass(modalClass)"
|
||||
:style="getStyle(modalStyle)"
|
||||
:visible="visible"
|
||||
v-bind="_attrs"
|
||||
v-on="$listeners"
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
|
||||
<slot></slot>
|
||||
|
||||
<template v-if="!isNoTitle" slot="title">
|
||||
<a-row class="j-modal-title-row" type="flex">
|
||||
<a-col class="left">
|
||||
<slot name="title">{{ title }}</slot>
|
||||
</a-col>
|
||||
<a-col class="right">
|
||||
<a-button v-if="switchFullscreen" @click="toggleFullscreen" class="ant-modal-close ant-modal-close-x"
|
||||
ghost type="link" :icon="fullscreenButtonIcon"/>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
|
||||
<!-- 处理 scopedSlots -->
|
||||
<template v-for="slotName of scopedSlotsKeys" :slot="slotName">
|
||||
<slot :name="slotName"></slot>
|
||||
</template>
|
||||
|
||||
<!-- 处理 slots -->
|
||||
<template v-for="slotName of slotsKeys" v-slot:[slotName]>
|
||||
<slot :name="slotName"></slot>
|
||||
</template>
|
||||
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { getClass, getStyle } from '@/utils/props-util'
|
||||
import { triggerWindowResizeEvent } from "@/utils/util"
|
||||
import Vue from 'vue'
|
||||
|
||||
export default {
|
||||
name: 'JModal',
|
||||
props: {
|
||||
title: String,
|
||||
// 可使用 .sync 修饰符
|
||||
visible: Boolean,
|
||||
// 前缀代号
|
||||
prefixNo: String,
|
||||
// 是否全屏弹窗,当全屏时无论如何都会禁止 body 滚动。可使用 .sync 修饰符
|
||||
fullscreen: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 是否允许展示新手引导(允许后右上角会出现一个按钮)
|
||||
switchHelp: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 是否允许切换全屏(允许后右上角会出现一个按钮)
|
||||
switchFullscreen: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 点击确定按钮的时候是否关闭弹窗
|
||||
okClose: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 内部使用的 slots ,不再处理
|
||||
usedSlots: ['title'],
|
||||
// 实际控制是否全屏的参数
|
||||
innerFullscreen: this.fullscreen,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 一些未处理的参数或特殊处理的参数绑定到 a-modal 上
|
||||
_attrs() {
|
||||
let attrs = { ...this.$attrs }
|
||||
// 如果全屏就将宽度设为 100%
|
||||
if (this.innerFullscreen) {
|
||||
attrs['width'] = '100%'
|
||||
}
|
||||
return attrs
|
||||
},
|
||||
modalClass() {
|
||||
return {
|
||||
'j-modal-box': true,
|
||||
'fullscreen': this.innerFullscreen,
|
||||
'no-title': this.isNoTitle,
|
||||
'no-footer': this.isNoFooter,
|
||||
}
|
||||
},
|
||||
modalStyle() {
|
||||
let style = {}
|
||||
// 如果全屏就将top设为 0
|
||||
if (this.innerFullscreen) {
|
||||
style['top'] = '0'
|
||||
}
|
||||
return style
|
||||
},
|
||||
isNoTitle() {
|
||||
return !this.title && !this.allSlotsKeys.includes('title')
|
||||
},
|
||||
isNoFooter() {
|
||||
return this._attrs['footer'] === null
|
||||
},
|
||||
slotsKeys() {
|
||||
return Object.keys(this.$slots).filter(key => !this.usedSlots.includes(key))
|
||||
},
|
||||
scopedSlotsKeys() {
|
||||
return Object.keys(this.$scopedSlots).filter(key => !this.usedSlots.includes(key))
|
||||
},
|
||||
allSlotsKeys() {
|
||||
return this.slotsKeys.concat(this.scopedSlotsKeys)
|
||||
},
|
||||
// 切换全屏的按钮图标
|
||||
fullscreenButtonIcon() {
|
||||
return this.innerFullscreen ? 'fullscreen-exit' : 'fullscreen'
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
visible() {
|
||||
if (this.visible) {
|
||||
this.innerFullscreen = this.fullscreen
|
||||
}
|
||||
},
|
||||
innerFullscreen(val) {
|
||||
this.$emit('update:fullscreen', val)
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
||||
getClass(clazz) {
|
||||
return { ...getClass(this), ...clazz }
|
||||
},
|
||||
getStyle(style) {
|
||||
return { ...getStyle(this), ...style }
|
||||
},
|
||||
|
||||
close() {
|
||||
this.$emit('update:visible', false)
|
||||
},
|
||||
|
||||
handleOk() {
|
||||
if (this.okClose) {
|
||||
this.close()
|
||||
}
|
||||
},
|
||||
handleCancel() {
|
||||
this.close()
|
||||
},
|
||||
|
||||
|
||||
/** 切换全屏 */
|
||||
toggleFullscreen() {
|
||||
this.innerFullscreen = !this.innerFullscreen
|
||||
triggerWindowResizeEvent()
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.j-modal-box {
|
||||
|
||||
&.fullscreen {
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding: 0;
|
||||
|
||||
height: 100vh;
|
||||
|
||||
& .ant-modal-content {
|
||||
height: 100vh;
|
||||
border-radius: 0;
|
||||
|
||||
& .ant-modal-body {
|
||||
/* title 和 footer 各占 55px */
|
||||
height: calc(100% - 55px - 55px);
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
&.no-title, &.no-footer {
|
||||
.ant-modal-body {
|
||||
height: calc(100% - 55px);
|
||||
}
|
||||
}
|
||||
|
||||
&.no-title.no-footer {
|
||||
.ant-modal-body {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.j-modal-title-row {
|
||||
.left {
|
||||
width: calc(100% - 56px - 56px);
|
||||
}
|
||||
|
||||
.right {
|
||||
width: 56px;
|
||||
position: inherit;
|
||||
|
||||
.ant-modal-close {
|
||||
right: 56px;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
|
||||
&:hover {
|
||||
color: rgba(0, 0, 0, 0.75);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.j-modal-box.fullscreen {
|
||||
margin: 0;
|
||||
max-width: 100vw;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,66 @@
|
||||
<template>
|
||||
<a-select :value="arrayValue" @change="onChange" mode="multiple" :placeholder="placeholder">
|
||||
<a-select-option
|
||||
v-for="(item,index) in options"
|
||||
:key="index"
|
||||
:value="item.value">
|
||||
{{ item.text || item.label }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
//option {label:,value:}
|
||||
export default {
|
||||
name: 'JSelectMultiple',
|
||||
props: {
|
||||
placeholder:{
|
||||
type: String,
|
||||
default:'',
|
||||
required: false
|
||||
},
|
||||
value:{
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
readOnly:{
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
options:{
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
triggerChange:{
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
arrayValue:!this.value?[]:this.value.split(",")
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
value (val) {
|
||||
if(!val){
|
||||
this.arrayValue = []
|
||||
}else{
|
||||
this.arrayValue = this.value.split(",")
|
||||
}
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
onChange (selectedValue) {
|
||||
if(this.triggerChange){
|
||||
this.$emit('change', selectedValue.join(","));
|
||||
}else{
|
||||
this.$emit('input', selectedValue.join(","));
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<div class="drag" ref="dragDiv">
|
||||
<div class="drag_bg"></div>
|
||||
<div class="drag_text">{{confirmWords}}</div>
|
||||
<div ref="moveDiv" @mousedown="mousedownFn($event)" :class="{'handler_ok_bg':confirmSuccess}" class="handler handler_bg" style="border: 0.5px solid #fff;height: 34px;position: absolute;top: 0px;left: 0px;"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name:"JSlider",
|
||||
data(){
|
||||
return {
|
||||
beginClientX:0, /*距离屏幕左端距离*/
|
||||
mouseMoveStata:false, /*触发拖动状态 判断*/
|
||||
maxwidth:'', /*拖动最大宽度,依据滑块宽度算出来的*/
|
||||
confirmWords:'拖动滑块验证', /*滑块文字*/
|
||||
confirmSuccess:false /*验证成功判断*/
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isSuccess(){
|
||||
return this.confirmSuccess
|
||||
},
|
||||
mousedownFn:function (e) {
|
||||
if(!this.confirmSuccess){
|
||||
e.preventDefault && e.preventDefault(); //阻止文字选中等 浏览器默认事件
|
||||
this.mouseMoveStata = true;
|
||||
this.beginClientX = e.clientX;
|
||||
}
|
||||
}, //mousedoen 事件
|
||||
successFunction(){
|
||||
this.confirmSuccess = true
|
||||
this.confirmWords = '验证通过';
|
||||
if(window.addEventListener){
|
||||
document.getElementsByTagName('html')[0].removeEventListener('mousemove',this.mouseMoveFn);
|
||||
document.getElementsByTagName('html')[0].removeEventListener('mouseup',this.moseUpFn);
|
||||
}else {
|
||||
document.getElementsByTagName('html')[0].removeEventListener('mouseup',()=>{});
|
||||
}
|
||||
document.getElementsByClassName('drag_text')[0].style.color = '#fff'
|
||||
document.getElementsByClassName('handler')[0].style.left = this.maxwidth + 'px';
|
||||
document.getElementsByClassName('drag_bg')[0].style.width = this.maxwidth + 'px';
|
||||
|
||||
this.$emit("onSuccess",true)
|
||||
}, //验证成功函数
|
||||
mouseMoveFn(e){
|
||||
if(this.mouseMoveStata){
|
||||
let width = e.clientX - this.beginClientX;
|
||||
if(width>0 && width<=this.maxwidth){
|
||||
document.getElementsByClassName('handler')[0].style.left = width + 'px';
|
||||
document.getElementsByClassName('drag_bg')[0].style.width = width + 'px';
|
||||
}else if(width>this.maxwidth){
|
||||
this.successFunction();
|
||||
}
|
||||
}
|
||||
}, //mousemove事件
|
||||
moseUpFn(e){
|
||||
this.mouseMoveStata = false;
|
||||
var width = e.clientX - this.beginClientX;
|
||||
if(width<this.maxwidth){
|
||||
// ---- update-begin- author:sunjianlei --- date:20191009 --- for: 修复获取不到 handler 的时候报错 ----
|
||||
let handler = document.getElementsByClassName('handler')[0]
|
||||
if (handler) {
|
||||
handler.style.left = 0 + 'px'
|
||||
document.getElementsByClassName('drag_bg')[0].style.width = 0 + 'px'
|
||||
}
|
||||
// ---- update-end- author:sunjianlei --- date:20191009 --- for: 修复获取不到 handler 的时候报错 ----
|
||||
}
|
||||
} //mouseup事件
|
||||
},
|
||||
mounted(){
|
||||
this.maxwidth = this.$refs.dragDiv.clientWidth - this.$refs.moveDiv.clientWidth;
|
||||
document.getElementsByTagName('html')[0].addEventListener('mousemove',this.mouseMoveFn);
|
||||
document.getElementsByTagName('html')[0].addEventListener('mouseup',this.moseUpFn)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.drag{
|
||||
position: relative;
|
||||
background-color: #e8e8e8;
|
||||
width: 100%;
|
||||
height: 34px;
|
||||
line-height: 34px;
|
||||
text-align: center;
|
||||
}
|
||||
.handler{
|
||||
width: 40px;
|
||||
height: 32px;
|
||||
border: 1px solid #ccc;
|
||||
cursor: move;
|
||||
}
|
||||
.handler_bg{
|
||||
background: #fff url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0ZDhlNWY5My05NmI0LTRlNWQtOGFjYi03ZTY4OGYyMTU2ZTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTEyNTVEMURGMkVFMTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTEyNTVEMUNGMkVFMTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2MTc5NzNmZS02OTQxLTQyOTYtYTIwNi02NDI2YTNkOWU5YmUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NGQ4ZTVmOTMtOTZiNC00ZTVkLThhY2ItN2U2ODhmMjE1NmU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+YiRG4AAAALFJREFUeNpi/P//PwMlgImBQkA9A+bOnfsIiBOxKcInh+yCaCDuByoswaIOpxwjciACFegBqZ1AvBSIS5OTk/8TkmNEjwWgQiUgtQuIjwAxUF3yX3xyGIEIFLwHpKyAWB+I1xGSwxULIGf9A7mQkBwTlhBXAFLHgPgqEAcTkmNCU6AL9d8WII4HOvk3ITkWJAXWUMlOoGQHmsE45ViQ2KuBuASoYC4Wf+OUYxz6mQkgwAAN9mIrUReCXgAAAABJRU5ErkJggg==") no-repeat center;
|
||||
}
|
||||
.handler_ok_bg{
|
||||
background: #fff url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0ZDhlNWY5My05NmI0LTRlNWQtOGFjYi03ZTY4OGYyMTU2ZTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDlBRDI3NjVGMkQ2MTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDlBRDI3NjRGMkQ2MTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDphNWEzMWNhMC1hYmViLTQxNWEtYTEwZS04Y2U5NzRlN2Q4YTEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NGQ4ZTVmOTMtOTZiNC00ZTVkLThhY2ItN2U2ODhmMjE1NmU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+k+sHwwAAASZJREFUeNpi/P//PwMyKD8uZw+kUoDYEYgloMIvgHg/EM/ptHx0EFk9I8wAoEZ+IDUPiIMY8IN1QJwENOgj3ACo5gNAbMBAHLgAxA4gQ5igAnNJ0MwAVTsX7IKyY7L2UNuJAf+AmAmJ78AEDTBiwGYg5gbifCSxFCZoaBMCy4A4GOjnH0D6DpK4IxNSVIHAfSDOAeLraJrjgJp/AwPbHMhejiQnwYRmUzNQ4VQgDQqXK0ia/0I17wJiPmQNTNBEAgMlQIWiQA2vgWw7QppBekGxsAjIiEUSBNnsBDWEAY9mEFgMMgBk00E0iZtA7AHEctDQ58MRuA6wlLgGFMoMpIG1QFeGwAIxGZo8GUhIysmwQGSAZgwHaEZhICIzOaBkJkqyM0CAAQDGx279Jf50AAAAAABJRU5ErkJggg==") no-repeat center;
|
||||
}
|
||||
.drag_bg{
|
||||
background-color: #7ac23c;
|
||||
height: 34px;
|
||||
width: 0px;
|
||||
}
|
||||
.drag_text{
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
width: 100%;text-align: center;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
-o-user-select:none;
|
||||
-ms-user-select:none;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,638 @@
|
||||
<template>
|
||||
<div class="j-super-query-box">
|
||||
|
||||
<slot name="button" :isActive="superQueryFlag" :isMobile="izMobile" :open="handleOpen" :reset="handleReset">
|
||||
<a-tooltip v-if="superQueryFlag" v-bind="tooltipProps" :mouseLeaveDelay="0.2">
|
||||
<!-- begin 不知道为什么不加上这段代码就无法生效 -->
|
||||
<span v-show="false">{{tooltipProps}}</span>
|
||||
<!-- end 不知道为什么不加上这段代码就无法生效 -->
|
||||
<template slot="title">
|
||||
<span>已有高级查询条件生效</span>
|
||||
<a-divider type="vertical"/>
|
||||
<a @click="handleReset">清空</a>
|
||||
</template>
|
||||
<a-button-group>
|
||||
<a-button type="primary" @click="handleOpen">
|
||||
<a-icon type="appstore" theme="twoTone" spin/>
|
||||
<span>高级查询</span>
|
||||
</a-button>
|
||||
<a-button v-if="izMobile" type="primary" icon="delete" @click="handleReset"/>
|
||||
</a-button-group>
|
||||
</a-tooltip>
|
||||
<a-button v-else type="primary" icon="filter" @click="handleOpen">高级查询</a-button>
|
||||
</slot>
|
||||
|
||||
<j-modal
|
||||
title="高级查询构造器"
|
||||
:width="1000"
|
||||
:visible="visible"
|
||||
@cancel="handleCancel"
|
||||
:mask="false"
|
||||
:fullscreen="izMobile"
|
||||
class="j-super-query-modal"
|
||||
style="top:5%;max-height: 95%;"
|
||||
>
|
||||
|
||||
<template slot="footer">
|
||||
<div style="float: left">
|
||||
<a-button :loading="loading" @click="handleReset">重置</a-button>
|
||||
<a-button :loading="loading" @click="handleSave">保存查询条件</a-button>
|
||||
</div>
|
||||
<a-button :loading="loading" @click="handleCancel">关闭</a-button>
|
||||
<a-button :loading="loading" type="primary" @click="handleOk">查询</a-button>
|
||||
</template>
|
||||
|
||||
<a-spin :spinning="loading">
|
||||
<a-row>
|
||||
<a-col :sm="24" :md="24-5">
|
||||
|
||||
<a-empty v-if="queryParamsModel.length === 0" style="margin-bottom: 12px;">
|
||||
<div slot="description">
|
||||
<span>没有任何查询条件</span>
|
||||
<a-divider type="vertical"/>
|
||||
<a @click="handleAdd">点击新增</a>
|
||||
</div>
|
||||
</a-empty>
|
||||
|
||||
<a-form v-else layout="inline">
|
||||
|
||||
<a-row style="margin-bottom: 12px;">
|
||||
<a-col :md="12" :xs="24">
|
||||
<a-form-item label="过滤条件匹配" :labelCol="{md: 6,xs:24}" :wrapperCol="{md: 18,xs:24}" style="width: 100%;">
|
||||
<a-select v-model="matchType" :getPopupContainer="node=>node.parentNode" style="width: 100%;">
|
||||
<a-select-option value="and">AND(所有条件都要求匹配)</a-select-option>
|
||||
<a-select-option value="or">OR(条件中的任意一个匹配)</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row type="flex" style="margin-bottom:10px" :gutter="16" v-for="(item, index) in queryParamsModel" :key="index">
|
||||
|
||||
<a-col :md="8" :xs="24" style="margin-bottom: 12px;">
|
||||
<a-tree-select
|
||||
showSearch
|
||||
v-model="item.field"
|
||||
:treeData="fieldTreeData"
|
||||
:dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
placeholder="选择查询字段"
|
||||
allowClear
|
||||
treeDefaultExpandAll
|
||||
:getPopupContainer="node=>node.parentNode"
|
||||
style="width: 100%"
|
||||
@select="(val,option)=>handleSelected(option,item)"
|
||||
>
|
||||
</a-tree-select>
|
||||
</a-col>
|
||||
|
||||
<a-col :md="4" :xs="24" style="margin-bottom: 12px;">
|
||||
<a-select placeholder="匹配规则" :value="item.rule" :getPopupContainer="node=>node.parentNode" @change="handleRuleChange(item,$event)">
|
||||
<a-select-option value="eq">等于</a-select-option>
|
||||
<a-select-option value="like">包含</a-select-option>
|
||||
<a-select-option value="right_like">以..开始</a-select-option>
|
||||
<a-select-option value="left_like">以..结尾</a-select-option>
|
||||
<a-select-option value="in">在...中</a-select-option>
|
||||
<a-select-option value="ne">不等于</a-select-option>
|
||||
<a-select-option value="gt">大于</a-select-option>
|
||||
<a-select-option value="ge">大于等于</a-select-option>
|
||||
<a-select-option value="lt">小于</a-select-option>
|
||||
<a-select-option value="le">小于等于</a-select-option>
|
||||
</a-select>
|
||||
</a-col>
|
||||
|
||||
<a-col :md="8" :xs="24" style="margin-bottom: 12px;">
|
||||
<template v-if="item.dictCode">
|
||||
<template v-if="item.type === 'table-dict'">
|
||||
<j-popup
|
||||
v-model="item.val"
|
||||
:code="item.dictTable"
|
||||
:field="item.dictCode"
|
||||
:orgFields="item.dictCode"
|
||||
:destFields="item.dictCode"
|
||||
></j-popup>
|
||||
</template>
|
||||
<template v-else>
|
||||
<j-multi-select-tag v-show="allowMultiple(item)" v-model="item.val" :dictCode="item.dictCode" placeholder="请选择"/>
|
||||
<j-dict-select-tag v-show="!allowMultiple(item)" v-model="item.val" :dictCode="item.dictCode" placeholder="请选择"/>
|
||||
</template>
|
||||
</template>
|
||||
<j-popup v-else-if="item.type === 'popup'" :value="item.val" v-bind="item.popup" group-id="superQuery" @input="(e,v)=>handleChangeJPopup(item,e,v)"/>
|
||||
<j-select-multi-user
|
||||
v-else-if="item.type === 'select-user' || item.type === 'sel_user'"
|
||||
v-model="item.val"
|
||||
:buttons="false"
|
||||
:multiple="false"
|
||||
placeholder="请选择用户"
|
||||
:returnKeys="['id', item.customReturnField || 'username']"
|
||||
/>
|
||||
<j-select-depart
|
||||
v-else-if="item.type === 'select-depart' || item.type === 'sel_depart'"
|
||||
v-model="item.val"
|
||||
:multi="false"
|
||||
placeholder="请选择部门"
|
||||
:customReturnField="item.customReturnField || 'id'"
|
||||
/>
|
||||
<a-select
|
||||
v-else-if="item.options instanceof Array"
|
||||
v-model="item.val"
|
||||
:options="item.options"
|
||||
allowClear
|
||||
placeholder="请选择"
|
||||
:mode="allowMultiple(item)?'multiple':''"
|
||||
/>
|
||||
<j-area-linkage v-model="item.val" v-else-if="item.type==='area-linkage' || item.type==='pca'" style="width: 100%"/>
|
||||
<j-date v-else-if=" item.type=='date' " v-model="item.val" placeholder="请选择日期" style="width: 100%"></j-date>
|
||||
<j-date v-else-if=" item.type=='datetime' " v-model="item.val" placeholder="请选择时间" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%"></j-date>
|
||||
<a-time-picker v-else-if="item.type==='time'" :value="item.val ? moment(item.val,'HH:mm:ss') : null" format="HH:mm:ss" style="width: 100%" @change="(time,value)=>item.val=value"/>
|
||||
<a-input-number v-else-if=" item.type=='int'||item.type=='number' " style="width: 100%" placeholder="请输入数值" v-model="item.val"/>
|
||||
<a-input v-else v-model="item.val" placeholder="请输入值"/>
|
||||
</a-col>
|
||||
|
||||
<a-col :md="4" :xs="0" style="margin-bottom: 12px;">
|
||||
<a-button @click="handleAdd" icon="plus"></a-button>
|
||||
<a-button @click="handleDel( index )" icon="minus"></a-button>
|
||||
</a-col>
|
||||
|
||||
<a-col :md="0" :xs="24" style="margin-bottom: 12px;text-align: right;">
|
||||
<a-button @click="handleAdd" icon="plus"></a-button>
|
||||
<a-button @click="handleDel( index )" icon="minus"></a-button>
|
||||
</a-col>
|
||||
|
||||
</a-row>
|
||||
|
||||
</a-form>
|
||||
</a-col>
|
||||
<a-col :sm="24" :md="5">
|
||||
<!-- 查询记录 -->
|
||||
|
||||
<a-card class="j-super-query-history-card" :bordered="true">
|
||||
<div slot="title">
|
||||
保存的查询
|
||||
</div>
|
||||
|
||||
<a-empty v-if="saveTreeData.length === 0" class="j-super-query-history-empty" description="没有保存任何查询"/>
|
||||
<a-tree
|
||||
v-else
|
||||
class="j-super-query-history-tree"
|
||||
showIcon
|
||||
:treeData="saveTreeData"
|
||||
:selectedKeys="[]"
|
||||
@select="handleTreeSelect"
|
||||
>
|
||||
</a-tree>
|
||||
</a-card>
|
||||
|
||||
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
|
||||
</a-spin>
|
||||
|
||||
<a-modal title="请输入保存的名称" :visible="prompt.visible" @cancel="prompt.visible=false" @ok="handlePromptOk">
|
||||
<a-input v-model="prompt.value"></a-input>
|
||||
</a-modal>
|
||||
|
||||
</j-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from 'moment'
|
||||
import * as utils from '@/utils/util'
|
||||
import JDate from '@/components/jeecg/JDate.vue'
|
||||
import JSelectDepart from '@/components/jeecgbiz/JSelectDepart'
|
||||
import JSelectMultiUser from '@/components/jeecgbiz/JSelectMultiUser'
|
||||
import JAreaLinkage from '@comp/jeecg/JAreaLinkage'
|
||||
|
||||
export default {
|
||||
name: 'JSuperQuery',
|
||||
// mixins: [mixinDevice],
|
||||
components: { JAreaLinkage, JDate, JSelectDepart, JSelectMultiUser },
|
||||
props: {
|
||||
/*
|
||||
fieldList: [{
|
||||
value:'',
|
||||
text:'',
|
||||
type:'',
|
||||
dictCode:'' // 只要 dictCode 有值,无论 type 是什么,都显示为字典下拉框
|
||||
}]
|
||||
type:date datetime int number string
|
||||
* */
|
||||
fieldList: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
/*
|
||||
* 这个回调函数接收一个数组参数 即查询条件
|
||||
* */
|
||||
callback: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'handleSuperQuery'
|
||||
},
|
||||
|
||||
// 当前是否在加载中
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
|
||||
// 保存查询条件的唯一 code,通过该 code 区分
|
||||
// 默认为 null,代表以当前路由全路径为区分Code
|
||||
saveCode: {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
moment,
|
||||
fieldTreeData: [],
|
||||
|
||||
prompt: {
|
||||
visible: false,
|
||||
value: ''
|
||||
},
|
||||
|
||||
visible: false,
|
||||
queryParamsModel: [],
|
||||
treeIcon: <a-icon type="file-text"/>,
|
||||
// 保存查询条件的treeData
|
||||
saveTreeData: [],
|
||||
// 保存查询条件的前缀名
|
||||
saveCodeBefore: 'JSuperQuerySaved_',
|
||||
// 查询类型,过滤条件匹配(and、or)
|
||||
matchType: 'and',
|
||||
superQueryFlag: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
izMobile() {
|
||||
return this.device === 'mobile'
|
||||
},
|
||||
tooltipProps() {
|
||||
return this.izMobile ? { visible: false } : {}
|
||||
},
|
||||
fullSaveCode() {
|
||||
let saveCode = this.saveCode
|
||||
if (saveCode == null || saveCode === '') {
|
||||
saveCode = this.$route.fullPath
|
||||
}
|
||||
return this.saveCodeBefore + saveCode
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
// 当 saveCode 变化时,重新查询已保存的条件
|
||||
fullSaveCode: {
|
||||
immediate: true,
|
||||
handler() {
|
||||
let list = this.$ls.get(this.fullSaveCode)
|
||||
if (list instanceof Array) {
|
||||
this.saveTreeData = list.map(i => this.renderSaveTreeData(i))
|
||||
}
|
||||
}
|
||||
},
|
||||
fieldList: {
|
||||
deep: true,
|
||||
immediate: true,
|
||||
handler(val) {
|
||||
let mainData = [], subData = []
|
||||
val.forEach(item => {
|
||||
let data = { ...item }
|
||||
data.label = data.label || data.text
|
||||
let hasChildren = (data.children instanceof Array)
|
||||
data.disabled = hasChildren
|
||||
data.selectable = !hasChildren
|
||||
if (hasChildren) {
|
||||
data.children = data.children.map(item2 => {
|
||||
let child = { ...item2 }
|
||||
child.label = child.label || child.text
|
||||
child.label = data.label + '-' + child.label
|
||||
child.value = data.value + ',' + child.value
|
||||
child.val = ''
|
||||
return child
|
||||
})
|
||||
data.val = ''
|
||||
subData.push(data)
|
||||
} else {
|
||||
mainData.push(data)
|
||||
}
|
||||
})
|
||||
this.fieldTreeData = mainData.concat(subData)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
show() {
|
||||
if (!this.queryParamsModel || this.queryParamsModel.length === 0) {
|
||||
this.resetLine()
|
||||
}
|
||||
this.visible = true
|
||||
},
|
||||
handleOk() {
|
||||
if (!this.isNullArray(this.queryParamsModel)) {
|
||||
let event = {
|
||||
matchType: this.matchType,
|
||||
params: this.removeEmptyObject(this.queryParamsModel)
|
||||
}
|
||||
// 移动端模式下关闭弹窗
|
||||
if (this.izMobile) {
|
||||
this.visible = false
|
||||
}
|
||||
this.emitCallback(event)
|
||||
} else {
|
||||
this.$message.warn("不能查询空条件")
|
||||
}
|
||||
},
|
||||
emitCallback(event = {}) {
|
||||
let { params = [], matchType = this.matchType } = event
|
||||
this.superQueryFlag = (params && params.length > 0)
|
||||
for (let param of params) {
|
||||
if (Array.isArray(param.val)) {
|
||||
param.val = param.val.join(',')
|
||||
}
|
||||
}
|
||||
console.debug('---高级查询参数--->', { params, matchType })
|
||||
this.$emit(this.callback, params, matchType)
|
||||
},
|
||||
handleCancel() {
|
||||
this.close()
|
||||
},
|
||||
close() {
|
||||
this.$emit('close')
|
||||
this.visible = false
|
||||
},
|
||||
handleAdd() {
|
||||
this.addNewLine()
|
||||
},
|
||||
addNewLine() {
|
||||
this.queryParamsModel.push({ rule: 'eq' })
|
||||
},
|
||||
resetLine() {
|
||||
this.superQueryFlag = false
|
||||
this.queryParamsModel = []
|
||||
this.addNewLine()
|
||||
},
|
||||
handleDel(index) {
|
||||
this.queryParamsModel.splice(index, 1)
|
||||
},
|
||||
handleSelected(node, item) {
|
||||
let { type, options, dictCode, dictTable, customReturnField, popup } = node.dataRef
|
||||
item['type'] = type
|
||||
item['options'] = options
|
||||
item['dictCode'] = dictCode
|
||||
item['dictTable'] = dictTable
|
||||
item['customReturnField'] = customReturnField
|
||||
if (popup) {
|
||||
item['popup'] = popup
|
||||
}
|
||||
this.$set(item, 'val', undefined)
|
||||
},
|
||||
handleOpen() {
|
||||
this.show()
|
||||
},
|
||||
handleReset() {
|
||||
this.resetLine()
|
||||
this.emitCallback()
|
||||
},
|
||||
handleSave() {
|
||||
let queryParams = this.removeEmptyObject(this.queryParamsModel)
|
||||
if (this.isNullArray(queryParams)) {
|
||||
this.$message.warning('空条件不能保存')
|
||||
} else {
|
||||
this.prompt.value = ''
|
||||
this.prompt.visible = true
|
||||
}
|
||||
},
|
||||
handlePromptOk() {
|
||||
let { value } = this.prompt
|
||||
if(!value){
|
||||
this.$message.warning('保存名称不能为空')
|
||||
return
|
||||
}
|
||||
// 取出查询条件
|
||||
let records = this.removeEmptyObject(this.queryParamsModel)
|
||||
// 判断有没有重名的
|
||||
let filterList = this.saveTreeData.filter(i => i.originTitle === value)
|
||||
if (filterList.length > 0) {
|
||||
this.$confirm({
|
||||
content: `${value} 已存在,是否覆盖?`,
|
||||
onOk: () => {
|
||||
this.prompt.visible = false
|
||||
filterList[0].records = records
|
||||
this.saveToLocalStore()
|
||||
this.$message.success('保存成功')
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// 没有重名的,直接添加
|
||||
this.prompt.visible = false
|
||||
// 添加到树列表中
|
||||
this.saveTreeData.push(this.renderSaveTreeData({
|
||||
title: value,
|
||||
matchType: this.matchType,
|
||||
records: records
|
||||
}))
|
||||
// 保存到 LocalStore
|
||||
this.saveToLocalStore()
|
||||
this.$message.success('保存成功')
|
||||
}
|
||||
},
|
||||
handleTreeSelect(idx, event) {
|
||||
if (event.selectedNodes[0]) {
|
||||
let { matchType, records } = event.selectedNodes[0].data.props
|
||||
// 将保存的matchType取出,兼容旧数据,如果没有保存就还是使用原来的
|
||||
this.matchType = matchType || this.matchType
|
||||
this.queryParamsModel = utils.cloneObject(records)
|
||||
}
|
||||
},
|
||||
handleRemoveSaveTreeItem(event, vNode) {
|
||||
// 阻止事件冒泡
|
||||
event.stopPropagation()
|
||||
|
||||
this.$confirm({
|
||||
content: '是否删除当前查询?',
|
||||
onOk: () => {
|
||||
let { eventKey } = vNode
|
||||
this.saveTreeData.splice(Number.parseInt(eventKey.substring(2)), 1)
|
||||
this.saveToLocalStore()
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
// 将查询保存到 LocalStore 里
|
||||
saveToLocalStore() {
|
||||
let saveValue = this.saveTreeData.map(({ originTitle, matchType, records }) => ({ title: originTitle, matchType, records }))
|
||||
this.$ls.set(this.fullSaveCode, saveValue)
|
||||
},
|
||||
|
||||
isNullArray(array) {
|
||||
//判断是不是空数组对象
|
||||
if (!array || array.length === 0) {
|
||||
return true
|
||||
}
|
||||
if (array.length === 1) {
|
||||
let obj = array[0]
|
||||
if (!obj.field || (obj.val == null || obj.val === '') || !obj.rule) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
},
|
||||
// 去掉数组中的空对象
|
||||
removeEmptyObject(arr) {
|
||||
let array = utils.cloneObject(arr)
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
let item = array[i]
|
||||
if (item == null || Object.keys(item).length <= 0) {
|
||||
array.splice(i--, 1)
|
||||
} else {
|
||||
if (Array.isArray(item.options)) {
|
||||
// 如果有字典属性,就不需要保存 options 了
|
||||
if (item.dictCode) {
|
||||
// 去掉特殊属性
|
||||
delete item.options
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return array
|
||||
},
|
||||
|
||||
/** 渲染保存查询条件的 title(加个删除按钮) */
|
||||
renderSaveTreeData(item) {
|
||||
item.icon = this.treeIcon
|
||||
item.originTitle = item['title']
|
||||
item.title = (fn, vNode) => {
|
||||
let { originTitle } = vNode.dataRef
|
||||
return (
|
||||
<div class="j-history-tree-title">
|
||||
<span>{originTitle}</span>
|
||||
|
||||
<div class="j-history-tree-title-closer" onClick={e => this.handleRemoveSaveTreeItem(e, vNode)}>
|
||||
<a-icon type="close-circle"/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return item
|
||||
},
|
||||
|
||||
/** 判断是否允许多选 */
|
||||
allowMultiple(item) {
|
||||
return item.rule === 'in'
|
||||
},
|
||||
|
||||
handleRuleChange(item, newValue) {
|
||||
let oldValue = item.rule
|
||||
this.$set(item, 'rule', newValue)
|
||||
// 上一个规则是否是 in,且type是字典或下拉
|
||||
if (oldValue === 'in') {
|
||||
if (item.dictCode || item.options instanceof Array) {
|
||||
let value = item.val
|
||||
if (typeof item.val === 'string') {
|
||||
value = item.val.split(',')[0]
|
||||
} else if (Array.isArray(item.val)) {
|
||||
value = item.val[0]
|
||||
}
|
||||
this.$set(item, 'val', value)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
handleChangeJPopup(item, e, values) {
|
||||
item.val = values[item.popup['destFields']]
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
.j-super-query-box {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.j-super-query-modal {
|
||||
|
||||
.j-super-query-history-card {
|
||||
/deep/ .ant-card-body,
|
||||
/deep/ .ant-card-head-title {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/deep/ .ant-card-head {
|
||||
padding: 4px 8px;
|
||||
min-height: initial;
|
||||
}
|
||||
}
|
||||
|
||||
.j-super-query-history-empty {
|
||||
/deep/ .ant-empty-image {
|
||||
height: 80px;
|
||||
line-height: 80px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/deep/ img {
|
||||
width: 80px;
|
||||
height: 65px;
|
||||
}
|
||||
|
||||
/deep/ .ant-empty-description {
|
||||
color: #afafaf;
|
||||
margin: 8px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.j-super-query-history-tree {
|
||||
|
||||
.j-history-tree-title {
|
||||
width: calc(100% - 24px);
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
&-closer {
|
||||
color: #999999;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
text-align: center;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s, color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.j-history-tree-title-closer {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/deep/ .ant-tree-switcher {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/deep/ .ant-tree-node-content-wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<a-switch v-model="checkStatus" :disabled="disabled" @change="handleChange"/>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'JSwitch',
|
||||
props: {
|
||||
value:{
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
disabled:{
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
options:{
|
||||
type:Array,
|
||||
required:false,
|
||||
default:()=>['Y','N']
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
checkStatus: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value:{
|
||||
immediate: true,
|
||||
handler(val){
|
||||
if(!val){
|
||||
this.checkStatus = false
|
||||
this.$emit('change', this.options[1]);
|
||||
}else{
|
||||
if(this.options[0]==val){
|
||||
this.checkStatus = true
|
||||
}else{
|
||||
this.checkStatus = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleChange(checked){
|
||||
let flag = checked===false?this.options[1]:this.options[0];
|
||||
this.$emit('change', flag);
|
||||
}
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,199 @@
|
||||
<template>
|
||||
<a-tree-select
|
||||
allowClear
|
||||
labelInValue
|
||||
style="width: 100%"
|
||||
:disabled="disabled"
|
||||
:dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
:placeholder="placeholder"
|
||||
:loadData="asyncLoadTreeData"
|
||||
:value="treeValue"
|
||||
:treeData="treeData"
|
||||
@change="onChange"
|
||||
@search="onSearch">
|
||||
</a-tree-select>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getAction } from '@/api/manage'
|
||||
|
||||
export default {
|
||||
name: 'JTreeDict',
|
||||
data(){
|
||||
return {
|
||||
treeData:[],
|
||||
treeValue: null,
|
||||
url_root:"/sys/category/loadTreeRoot",
|
||||
url_children:"/sys/category/loadTreeChildren",
|
||||
url_view:'/sys/category/loadOne',
|
||||
}
|
||||
},
|
||||
props:{
|
||||
value:{
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
placeholder:{
|
||||
type: String,
|
||||
default: '请选择',
|
||||
required: false
|
||||
},
|
||||
parentCode:{
|
||||
type: String,
|
||||
default: '',
|
||||
required: false
|
||||
},
|
||||
field:{
|
||||
type: String,
|
||||
default: 'id',
|
||||
required: false
|
||||
},
|
||||
root:{
|
||||
type:Object,
|
||||
required:false,
|
||||
default:()=>{
|
||||
return {
|
||||
pid:'0'
|
||||
}
|
||||
}
|
||||
},
|
||||
async:{
|
||||
type:Boolean,
|
||||
default:false,
|
||||
required:false
|
||||
},
|
||||
disabled:{
|
||||
type:Boolean,
|
||||
default:false,
|
||||
required:false
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
root:{
|
||||
handler(val){
|
||||
console.log("root-change",val)
|
||||
},
|
||||
deep:true
|
||||
},
|
||||
parentCode:{
|
||||
handler(){
|
||||
this.loadRoot()
|
||||
}
|
||||
},
|
||||
value:{
|
||||
handler(){
|
||||
this.loadViewInfo()
|
||||
}
|
||||
}
|
||||
},
|
||||
created(){
|
||||
this.loadRoot()
|
||||
this.loadViewInfo()
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
},
|
||||
methods:{
|
||||
loadViewInfo(){
|
||||
if(!this.value || this.value=="0"){
|
||||
this.treeValue = null
|
||||
}else{
|
||||
let param = {
|
||||
field:this.field,
|
||||
val:this.value
|
||||
}
|
||||
getAction(this.url_view,param).then(res=>{
|
||||
if(res.success){
|
||||
this.treeValue = {
|
||||
value:this.value,
|
||||
label:res.result.name
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
loadRoot(){
|
||||
let param = {
|
||||
async:this.async,
|
||||
pcode:this.parentCode
|
||||
}
|
||||
getAction(this.url_root,param).then(res=>{
|
||||
if(res.success){
|
||||
this.handleTreeNodeValue(res.result)
|
||||
console.log("aaaa",res.result)
|
||||
this.treeData = [...res.result]
|
||||
}else{
|
||||
this.$message.error(res.message)
|
||||
}
|
||||
})
|
||||
},
|
||||
asyncLoadTreeData (treeNode) {
|
||||
return new Promise((resolve) => {
|
||||
if(!this.async){
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
if (treeNode.$vnode.children) {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
let pid = treeNode.$vnode.key
|
||||
let param = {
|
||||
pid:pid
|
||||
}
|
||||
getAction(this.url_children,param).then(res=>{
|
||||
if(res.success){
|
||||
this.handleTreeNodeValue(res.result)
|
||||
this.addChildren(pid,res.result,this.treeData)
|
||||
this.treeData = [...this.treeData]
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
},
|
||||
addChildren(pid,children,treeArray){
|
||||
if(treeArray && treeArray.length>0){
|
||||
for(let item of treeArray){
|
||||
if(item.key == pid){
|
||||
if(!children || children.length==0){
|
||||
item.leaf = true
|
||||
}else{
|
||||
item.children = children
|
||||
}
|
||||
break
|
||||
}else{
|
||||
this.addChildren(pid,children,item.children)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
handleTreeNodeValue(result){
|
||||
let storeField = this.field=='code'?'code':'key'
|
||||
for(let i of result){
|
||||
i.value = i[storeField]
|
||||
i.isLeaf = (!i.leaf)?false:true
|
||||
if(i.children && i.children.length>0){
|
||||
this.handleTreeNodeValue(i.children)
|
||||
}
|
||||
}
|
||||
},
|
||||
onChange(value){
|
||||
console.log(value)
|
||||
if(!value){
|
||||
this.$emit('change', '');
|
||||
}else{
|
||||
this.$emit('change', value.value);
|
||||
}
|
||||
this.treeValue = value
|
||||
},
|
||||
onSearch(value){
|
||||
console.log(value)
|
||||
},
|
||||
getCurrTreeData(){
|
||||
return this.treeData
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,260 @@
|
||||
<template>
|
||||
<a-tree-select
|
||||
allowClear
|
||||
labelInValue
|
||||
:getPopupContainer="(node) => node.parentNode"
|
||||
style="width: 100%"
|
||||
:disabled="disabled"
|
||||
:dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
:placeholder="placeholder"
|
||||
:loadData="asyncLoadTreeData"
|
||||
:value="treeValue"
|
||||
:treeData="treeData"
|
||||
:multiple="multiple"
|
||||
@change="onChange"
|
||||
@search="onSearch">
|
||||
</a-tree-select>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
/*
|
||||
* 异步树加载组件 通过传入表名 显示字段 存储字段 加载一个树控件
|
||||
* <j-tree-select dict="aa_tree_test,aad,id" pid-field="pid" ></j-tree-select>
|
||||
* */
|
||||
import { getAction } from '@/api/manage'
|
||||
|
||||
export default {
|
||||
name: 'JTreeSelect',
|
||||
props: {
|
||||
value:{
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
placeholder:{
|
||||
type: String,
|
||||
default: '请选择',
|
||||
required: false
|
||||
},
|
||||
dict:{
|
||||
type: String,
|
||||
default: '',
|
||||
required: false
|
||||
},
|
||||
pidField:{
|
||||
type: String,
|
||||
default: 'pid',
|
||||
required: false
|
||||
},
|
||||
pidValue:{
|
||||
type: String,
|
||||
default: '',
|
||||
required: false
|
||||
},
|
||||
disabled:{
|
||||
type:Boolean,
|
||||
default:false,
|
||||
required:false
|
||||
},
|
||||
hasChildField:{
|
||||
type: String,
|
||||
default: '',
|
||||
required: false
|
||||
},
|
||||
condition:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
},
|
||||
// 是否支持多选
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
loadTriggleChange:{
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required:false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
treeValue: null,
|
||||
treeData:[],
|
||||
url:"/sys/dict/loadTreeData",
|
||||
view:'/sys/dict/loadDictItem/',
|
||||
tableName:"",
|
||||
text:"",
|
||||
code:"",
|
||||
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value () {
|
||||
this.loadItemByCode()
|
||||
},
|
||||
dict(){
|
||||
this.initDictInfo()
|
||||
this.loadRoot();
|
||||
}
|
||||
},
|
||||
created(){
|
||||
this.validateProp().then(()=>{
|
||||
this.initDictInfo()
|
||||
this.loadRoot()
|
||||
this.loadItemByCode()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
loadItemByCode(){
|
||||
if(!this.value || this.value=="0"){
|
||||
this.treeValue = null
|
||||
}else{
|
||||
getAction(`${this.view}${this.dict}`,{key:this.value}).then(res=>{
|
||||
if(res.success){
|
||||
let values = this.value.split(',')
|
||||
this.treeValue = res.result.map((item, index) => ({
|
||||
key: values[index],
|
||||
value: values[index],
|
||||
label: item
|
||||
}))
|
||||
this.onLoadTriggleChange(res.result[0]);
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
onLoadTriggleChange(text){
|
||||
//只有单选才会触发
|
||||
if(!this.multiple && this.loadTriggleChange){
|
||||
this.$emit('change', this.value,text)
|
||||
}
|
||||
},
|
||||
initDictInfo(){
|
||||
let arr = this.dict.split(",")
|
||||
this.tableName = arr[0]
|
||||
this.text = arr[1]
|
||||
this.code = arr[2]
|
||||
},
|
||||
asyncLoadTreeData (treeNode) {
|
||||
return new Promise((resolve) => {
|
||||
if (treeNode.$vnode.children) {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
let pid = treeNode.$vnode.key
|
||||
let param = {
|
||||
pid:pid,
|
||||
tableName:this.tableName,
|
||||
text:this.text,
|
||||
code:this.code,
|
||||
pidField:this.pidField,
|
||||
hasChildField:this.hasChildField,
|
||||
condition:this.condition
|
||||
}
|
||||
getAction(this.url,param).then(res=>{
|
||||
if(res.success){
|
||||
for(let i of res.result){
|
||||
i.value = i.key
|
||||
if(i.leaf==false){
|
||||
i.isLeaf=false
|
||||
}else if(i.leaf==true){
|
||||
i.isLeaf=true
|
||||
}
|
||||
}
|
||||
this.addChildren(pid,res.result,this.treeData)
|
||||
this.treeData = [...this.treeData]
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
},
|
||||
addChildren(pid,children,treeArray){
|
||||
if(treeArray && treeArray.length>0){
|
||||
for(let item of treeArray){
|
||||
if(item.key == pid){
|
||||
if(!children || children.length==0){
|
||||
item.isLeaf=true
|
||||
}else{
|
||||
item.children = children
|
||||
}
|
||||
break
|
||||
}else{
|
||||
this.addChildren(pid,children,item.children)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
loadRoot(){
|
||||
let param = {
|
||||
pid:this.pidValue,
|
||||
tableName:this.tableName,
|
||||
text:this.text,
|
||||
code:this.code,
|
||||
pidField:this.pidField,
|
||||
hasChildField:this.hasChildField,
|
||||
condition:this.condition
|
||||
}
|
||||
getAction(this.url,param).then(res=>{
|
||||
if(res.success && res.result){
|
||||
for(let i of res.result){
|
||||
i.value = i.key
|
||||
if(i.leaf==false){
|
||||
i.isLeaf=false
|
||||
}else if(i.leaf==true){
|
||||
i.isLeaf=true
|
||||
}
|
||||
}
|
||||
this.treeData = [...res.result]
|
||||
}else{
|
||||
console.log("数根节点查询结果-else",res)
|
||||
}
|
||||
})
|
||||
},
|
||||
onChange(value){
|
||||
if(!value){
|
||||
this.$emit('change', '');
|
||||
this.treeValue = null
|
||||
} else if (value instanceof Array) {
|
||||
this.$emit('change', value.map(item => item.value).join(','))
|
||||
this.treeValue = value
|
||||
} else {
|
||||
this.$emit('change', value.value,value.label)
|
||||
this.treeValue = value
|
||||
}
|
||||
|
||||
},
|
||||
onSearch(value){
|
||||
console.log(value)
|
||||
},
|
||||
getCurrTreeData(){
|
||||
return this.treeData
|
||||
},
|
||||
validateProp(){
|
||||
let mycondition = this.condition
|
||||
return new Promise((resolve,reject)=>{
|
||||
if(!mycondition){
|
||||
resolve();
|
||||
}else{
|
||||
try {
|
||||
let test=JSON.parse(mycondition);
|
||||
console.log("aaaaasdsdd",typeof test)
|
||||
if(typeof test == 'object' && test){
|
||||
resolve()
|
||||
}else{
|
||||
this.$message.error("组件JTreeSelect-condition传值有误,需要一个json字符串!")
|
||||
reject()
|
||||
}
|
||||
} catch(e) {
|
||||
this.$message.error("组件JTreeSelect-condition传值有误,需要一个json字符串!")
|
||||
reject()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
//2.2新增 在组件内定义 指定父组件调用时候的传值属性和事件类型 这个牛逼
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,180 @@
|
||||
<template>
|
||||
<a-table
|
||||
:rowKey="rowKey"
|
||||
:columns="columns"
|
||||
:dataSource="dataSource"
|
||||
:expandedRowKeys="expandedRowKeys"
|
||||
v-bind="tableAttrs"
|
||||
v-on="$listeners"
|
||||
@expand="handleExpand"
|
||||
@expandedRowsChange="expandedRowKeys=$event">
|
||||
|
||||
<template v-for="(slotItem) of slots" :slot="slotItem" slot-scope="text, record, index">
|
||||
<slot :name="slotItem" v-bind="{text,record,index}"></slot>
|
||||
</template>
|
||||
|
||||
</a-table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getAction } from '@/api/manage'
|
||||
|
||||
export default {
|
||||
name: 'JTreeTable',
|
||||
props: {
|
||||
rowKey: {
|
||||
type: String,
|
||||
default: 'id'
|
||||
},
|
||||
// 根据什么查询,如果传递 id 就根据 id 查询
|
||||
queryKey: {
|
||||
type: String,
|
||||
default: 'parentId'
|
||||
},
|
||||
queryParams: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
// 查询顶级时的值,如果顶级为0,则传0
|
||||
topValue: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
columns: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
childrenUrl: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
tableProps: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
/** 是否在创建组件的时候就查询数据 */
|
||||
immediateRequest: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
condition:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dataSource: [],
|
||||
expandedRowKeys: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getChildrenUrl() {
|
||||
if (this.childrenUrl) {
|
||||
return this.childrenUrl
|
||||
} else {
|
||||
return this.url
|
||||
}
|
||||
},
|
||||
slots() {
|
||||
let slots = []
|
||||
for (let column of this.columns) {
|
||||
if (column.scopedSlots && column.scopedSlots.customRender) {
|
||||
slots.push(column.scopedSlots.customRender)
|
||||
}
|
||||
}
|
||||
return slots
|
||||
},
|
||||
tableAttrs() {
|
||||
return Object.assign(this.$attrs, this.tableProps)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
queryParams: {
|
||||
deep: true,
|
||||
handler() {
|
||||
this.loadData()
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (this.immediateRequest) this.loadData()
|
||||
},
|
||||
methods: {
|
||||
|
||||
/** 加载数据*/
|
||||
loadData(id = this.topValue, first = true, url = this.url) {
|
||||
this.$emit('requestBefore', { first })
|
||||
|
||||
if (first) {
|
||||
this.expandedRowKeys = []
|
||||
}
|
||||
|
||||
let params = Object.assign({}, this.queryParams || {})
|
||||
params[this.queryKey] = id
|
||||
if(this.condition && this.condition.length>0){
|
||||
params['condition'] = this.condition
|
||||
}
|
||||
|
||||
return getAction(url, params).then(res => {
|
||||
let list = []
|
||||
if (res.result instanceof Array) {
|
||||
list = res.result
|
||||
} else if (res.result.records instanceof Array) {
|
||||
list = res.result.records
|
||||
} else {
|
||||
throw '返回数据类型不识别'
|
||||
}
|
||||
let dataSource = list.map(item => {
|
||||
// 判断是否标记了带有子级
|
||||
if (item.hasChildren === true) {
|
||||
// 查找第一个带有dataIndex的值的列
|
||||
let firstColumn
|
||||
for (let column of this.columns) {
|
||||
firstColumn = column.dataIndex
|
||||
if (firstColumn) break
|
||||
}
|
||||
// 定义默认展开时显示的loading子级,实际子级数据只在展开时加载
|
||||
let loadChild = { id: `${item.id}_loadChild`, [firstColumn]: 'loading...', isLoading: true }
|
||||
item.children = [loadChild]
|
||||
}
|
||||
return item
|
||||
})
|
||||
if (first) {
|
||||
this.dataSource = dataSource
|
||||
}
|
||||
this.$emit('requestSuccess', { first, dataSource, res })
|
||||
return Promise.resolve(dataSource)
|
||||
}).finally(() => this.$emit('requestFinally', { first }))
|
||||
},
|
||||
|
||||
/** 点击展开图标时触发 */
|
||||
handleExpand(expanded, record) {
|
||||
// 判断是否是展开状态
|
||||
if (expanded) {
|
||||
// 判断子级的首个项的标记是否是“正在加载中”,如果是就加载数据
|
||||
if (record.children[0].isLoading === true) {
|
||||
this.loadData(record.id, false, this.getChildrenUrl).then(dataSource => {
|
||||
// 处理好的数据可直接赋值给children
|
||||
if (dataSource.length === 0) {
|
||||
record.children = null
|
||||
} else {
|
||||
record.children = dataSource
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,452 @@
|
||||
<template>
|
||||
<div :id="containerId" style="position: relative">
|
||||
|
||||
<!-- ---------------------------- begin 图片左右换位置 ------------------------------------- -->
|
||||
<div class="movety-container" :style="{top:top+'px',left:left+'px',display:moveDisplay}" style="padding:0 8px;position: absolute;z-index: 91;height: 32px;width: 104px;text-align: center;">
|
||||
<div :id="containerId+'-mover'" :class="showMoverTask?'uploadty-mover-mask':'movety-opt'" style="margin-top: 12px">
|
||||
<a @click="moveLast" style="margin: 0 5px;"><a-icon type="arrow-left" style="color: #fff;font-size: 16px"/></a>
|
||||
<a @click="moveNext" style="margin: 0 5px;"><a-icon type="arrow-right" style="color: #fff;font-size: 16px"/></a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ---------------------------- end 图片左右换位置 ------------------------------------- -->
|
||||
|
||||
<a-upload
|
||||
name="file"
|
||||
:multiple="true"
|
||||
:action="uploadAction"
|
||||
:headers="headers"
|
||||
:data="{'biz':bizPath}"
|
||||
:fileList="fileList"
|
||||
:beforeUpload="beforeUpload"
|
||||
@change="handleChange"
|
||||
:disabled="disabled"
|
||||
:returnUrl="returnUrl"
|
||||
:listType="complistType"
|
||||
@preview="handlePreview"
|
||||
:class="{'uploadty-disabled':disabled}">
|
||||
<template>
|
||||
<div v-if="isImageComp">
|
||||
<a-icon type="plus" />
|
||||
<div class="ant-upload-text">{{ text }}</div>
|
||||
</div>
|
||||
<a-button v-else-if="buttonVisible">
|
||||
<a-icon type="upload" />{{ text }}
|
||||
</a-button>
|
||||
</template>
|
||||
</a-upload>
|
||||
<a-modal :visible="previewVisible" :width="1000" :footer="null" @cancel="handleCancel">
|
||||
<img alt="example" style="width: 100%" :src="previewImage" />
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import Vue from 'vue'
|
||||
import { getFileAccessHttpUrl } from '@/api/manage';
|
||||
import { fileSizeLimit } from '@/api/api'
|
||||
|
||||
const FILE_TYPE_ALL = "all"
|
||||
const FILE_TYPE_IMG = "image"
|
||||
const FILE_TYPE_TXT = "file"
|
||||
const uidGenerator=()=>{
|
||||
return '-'+parseInt(Math.random()*10000+1,10);
|
||||
}
|
||||
const getFileName=(path)=>{
|
||||
if(path.lastIndexOf("\\")>=0){
|
||||
let reg=new RegExp("\\\\","g");
|
||||
path = path.replace(reg,"/");
|
||||
}
|
||||
return path.substring(path.lastIndexOf("/")+1);
|
||||
}
|
||||
export default {
|
||||
name: 'JUpload',
|
||||
data(){
|
||||
return {
|
||||
uploadAction:window._CONFIG['domianURL']+"/systemConfig/upload",
|
||||
headers:{},
|
||||
fileList: [],
|
||||
newFileList: [],
|
||||
uploadGoOn:true,
|
||||
previewVisible: false,
|
||||
//---------------------------- begin 图片左右换位置 -------------------------------------
|
||||
previewImage: '',
|
||||
containerId:'',
|
||||
top:'',
|
||||
left:'',
|
||||
moveDisplay:'none',
|
||||
showMoverTask:false,
|
||||
moverHold:false,
|
||||
currentImg:'',
|
||||
//---------------------------- end 图片左右换位置 -------------------------------------
|
||||
sizeLimit: 0
|
||||
}
|
||||
},
|
||||
props:{
|
||||
text:{
|
||||
type:String,
|
||||
required:false,
|
||||
default:"点击上传"
|
||||
},
|
||||
fileType:{
|
||||
type:String,
|
||||
required:false,
|
||||
default:FILE_TYPE_ALL
|
||||
},
|
||||
/*这个属性用于控制文件上传的业务路径*/
|
||||
bizPath:{
|
||||
type:String,
|
||||
required:false,
|
||||
default:"temp"
|
||||
},
|
||||
value:{
|
||||
type:[String,Array],
|
||||
required:false
|
||||
},
|
||||
// update-begin- --- author:wangshuai ------ date:20190929 ---- for:Jupload组件增加是否能够点击
|
||||
disabled:{
|
||||
type:Boolean,
|
||||
required:false,
|
||||
default: false
|
||||
},
|
||||
// update-end- --- author:wangshuai ------ date:20190929 ---- for:Jupload组件增加是否能够点击
|
||||
//此属性被废弃了
|
||||
triggerChange:{
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
/**
|
||||
* update -- author:lvdandan -- date:20190219 -- for:Jupload组件增加是否返回url,
|
||||
* true:仅返回url
|
||||
* false:返回fileName filePath fileSize
|
||||
*/
|
||||
returnUrl:{
|
||||
type:Boolean,
|
||||
required:false,
|
||||
default: true
|
||||
},
|
||||
number:{
|
||||
type:Number,
|
||||
required:false,
|
||||
default: 0
|
||||
},
|
||||
buttonVisible:{
|
||||
type:Boolean,
|
||||
required:false,
|
||||
default: true
|
||||
},
|
||||
},
|
||||
watch:{
|
||||
value:{
|
||||
immediate: true,
|
||||
handler() {
|
||||
let val = this.value
|
||||
if (val instanceof Array) {
|
||||
if(this.returnUrl){
|
||||
this.initFileList(val.join(','))
|
||||
}else{
|
||||
this.initFileListArr(val);
|
||||
}
|
||||
} else {
|
||||
this.initFileList(val)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
isImageComp(){
|
||||
return this.fileType === FILE_TYPE_IMG
|
||||
},
|
||||
complistType(){
|
||||
return this.fileType === FILE_TYPE_IMG?'picture-card':'text'
|
||||
}
|
||||
},
|
||||
created(){
|
||||
this.initFileSizeLimit()
|
||||
const token = Vue.ls.get("");
|
||||
//---------------------------- begin 图片左右换位置 -------------------------------------
|
||||
this.headers = {"X-Access-Token":token};
|
||||
this.containerId = 'container-ty-'+new Date().getTime();
|
||||
//---------------------------- end 图片左右换位置 -------------------------------------
|
||||
},
|
||||
|
||||
methods:{
|
||||
initFileSizeLimit() {
|
||||
fileSizeLimit().then((res)=>{
|
||||
if(res.code === 200) {
|
||||
this.sizeLimit = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
initFileListArr(val){
|
||||
if(!val || val.length==0){
|
||||
this.fileList = [];
|
||||
return;
|
||||
}
|
||||
let fileList = [];
|
||||
for(var a=0;a<val.length;a++){
|
||||
let url = getFileAccessHttpUrl(val[a].filePath);
|
||||
fileList.push({
|
||||
uid:uidGenerator(),
|
||||
name:val[a].fileName,
|
||||
status: 'done',
|
||||
url: url,
|
||||
response:{
|
||||
code:"history",
|
||||
data:val[a].filePath
|
||||
}
|
||||
})
|
||||
}
|
||||
this.fileList = fileList
|
||||
},
|
||||
initFileList(paths){
|
||||
if(!paths || paths.length==0){
|
||||
//return [];
|
||||
// update-begin- --- author:os_chengtgen ------ date:20190729 ---- for:issues:326,Jupload组件初始化bug
|
||||
this.fileList = [];
|
||||
return;
|
||||
// update-end- --- author:os_chengtgen ------ date:20190729 ---- for:issues:326,Jupload组件初始化bug
|
||||
}
|
||||
let fileList = [];
|
||||
let arr = paths.split(",")
|
||||
for(var a=0;a<arr.length;a++){
|
||||
let url = getFileAccessHttpUrl(arr[a]);
|
||||
fileList.push({
|
||||
uid:uidGenerator(),
|
||||
name:getFileName(arr[a]),
|
||||
status: 'done',
|
||||
url: url,
|
||||
response:{
|
||||
code:"history",
|
||||
data:arr[a]
|
||||
}
|
||||
})
|
||||
}
|
||||
this.fileList = fileList
|
||||
},
|
||||
handlePathChange(){
|
||||
let uploadFiles = this.fileList
|
||||
let path = ''
|
||||
if(!uploadFiles || uploadFiles.length==0){
|
||||
path = ''
|
||||
}
|
||||
let arr = [];
|
||||
|
||||
for(var a=0;a<uploadFiles.length;a++){
|
||||
arr.push(uploadFiles[a].response.data)
|
||||
}
|
||||
if(arr.length>0){
|
||||
path = arr.join(",")
|
||||
}
|
||||
this.$emit('change', path);
|
||||
},
|
||||
beforeUpload(file){
|
||||
this.uploadGoOn=true
|
||||
let fileType = file.type;
|
||||
let fileSize = file.size;
|
||||
if(this.fileType===FILE_TYPE_IMG){
|
||||
if(fileType.indexOf('image')<0){
|
||||
this.$message.warning('请上传图片');
|
||||
this.uploadGoOn=false
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//验证文件大小
|
||||
if(fileSize>this.sizeLimit) {
|
||||
let parseSizeLimit = (this.sizeLimit/1024/1024).toFixed(2)
|
||||
this.$message.warning('抱歉,文件大小不能超过' + parseSizeLimit + 'M');
|
||||
this.uploadGoOn=false
|
||||
return false;
|
||||
}
|
||||
return true
|
||||
},
|
||||
handleChange(info) {
|
||||
console.log("--文件列表改变--")
|
||||
if(!info.file.status && this.uploadGoOn === false){
|
||||
info.fileList.pop();
|
||||
}
|
||||
let fileList = info.fileList
|
||||
if(info.file.status==='done'){
|
||||
if(this.number>0){
|
||||
fileList = fileList.slice(-this.number);
|
||||
}
|
||||
if(info.file.response.code === 200){
|
||||
fileList = fileList.map((file) => {
|
||||
if (file.response) {
|
||||
let reUrl = file.response.data;
|
||||
file.url = getFileAccessHttpUrl(reUrl);
|
||||
}
|
||||
return file;
|
||||
});
|
||||
}
|
||||
//this.$message.success(`${info.file.name} 上传成功!`);
|
||||
}else if (info.file.status === 'error') {
|
||||
this.$message.error(`${info.file.name} 上传失败.`);
|
||||
}else if(info.file.status === 'removed'){
|
||||
this.handleDelete(info.file)
|
||||
}
|
||||
this.fileList = fileList
|
||||
if(info.file.status==='done' || info.file.status === 'removed'){
|
||||
//returnUrl为true时仅返回文件路径
|
||||
if(this.returnUrl){
|
||||
this.handlePathChange()
|
||||
}else{
|
||||
//returnUrl为false时返回文件名称、文件路径及文件大小
|
||||
this.newFileList = [];
|
||||
for(var a=0;a<fileList.length;a++){
|
||||
var fileJson = {
|
||||
fileName:fileList[a].name,
|
||||
filePath:fileList[a].response.data,
|
||||
fileSize:fileList[a].size
|
||||
};
|
||||
this.newFileList.push(fileJson);
|
||||
}
|
||||
this.$emit('change', this.newFileList);
|
||||
}
|
||||
}
|
||||
},
|
||||
handleDelete(file){
|
||||
//如有需要新增 删除逻辑
|
||||
console.log(file)
|
||||
},
|
||||
handlePreview(file){
|
||||
let postfix = file.name.substring(file.name.indexOf('.'))
|
||||
if(postfix === '.gif' || postfix === '.jpg' || postfix === '.jpeg' || postfix === '.png' ||
|
||||
postfix === '.GIF' || postfix === '.JPG' || postfix === '.JPEG' || postfix === '.PNG') {
|
||||
this.previewImage = file.url || file.thumbUrl;
|
||||
this.previewVisible = true;
|
||||
}else{
|
||||
location.href=file.url
|
||||
}
|
||||
},
|
||||
handleCancel(){
|
||||
this.previewVisible = false;
|
||||
},
|
||||
//---------------------------- begin 图片左右换位置 -------------------------------------
|
||||
moveLast(){
|
||||
//console.log(ev)
|
||||
//console.log(this.fileList)
|
||||
//console.log(this.currentImg)
|
||||
let index = this.getIndexByUrl();
|
||||
if(index==0){
|
||||
this.$message.warn('未知的操作')
|
||||
}else{
|
||||
let curr = this.fileList[index].url;
|
||||
let last = this.fileList[index-1].url;
|
||||
let arr =[]
|
||||
for(let i=0;i<this.fileList.length;i++){
|
||||
if(i==index-1){
|
||||
arr.push(curr)
|
||||
}else if(i==index){
|
||||
arr.push(last)
|
||||
}else{
|
||||
arr.push(this.fileList[i].url)
|
||||
}
|
||||
}
|
||||
this.currentImg = last
|
||||
this.$emit('change',arr.join(','))
|
||||
}
|
||||
},
|
||||
moveNext(){
|
||||
let index = this.getIndexByUrl();
|
||||
if(index==this.fileList.length-1){
|
||||
this.$message.warn('已到最后~')
|
||||
}else{
|
||||
let curr = this.fileList[index].url;
|
||||
let next = this.fileList[index+1].url;
|
||||
let arr =[]
|
||||
for(let i=0;i<this.fileList.length;i++){
|
||||
if(i==index+1){
|
||||
arr.push(curr)
|
||||
}else if(i==index){
|
||||
arr.push(next)
|
||||
}else{
|
||||
arr.push(this.fileList[i].url)
|
||||
}
|
||||
}
|
||||
this.currentImg = next
|
||||
this.$emit('change',arr.join(','))
|
||||
}
|
||||
},
|
||||
getIndexByUrl(){
|
||||
for(let i=0;i<this.fileList.length;i++){
|
||||
if(this.fileList[i].url === this.currentImg || encodeURI(this.fileList[i].url) === this.currentImg){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
const moverObj = document.getElementById(this.containerId+'-mover');
|
||||
moverObj.addEventListener('mouseover',()=>{
|
||||
this.moverHold = true
|
||||
this.moveDisplay = 'block';
|
||||
});
|
||||
moverObj.addEventListener('mouseout',()=>{
|
||||
this.moverHold = false
|
||||
this.moveDisplay = 'none';
|
||||
});
|
||||
let picList = document.getElementById(this.containerId)?document.getElementById(this.containerId).getElementsByClassName('ant-upload-list-picture-card'):[];
|
||||
if(picList && picList.length>0){
|
||||
picList[0].addEventListener('mouseover',(ev)=>{
|
||||
ev = ev || window.event;
|
||||
let target = ev.target || ev.srcElement;
|
||||
if('ant-upload-list-item-info' == target.className){
|
||||
this.showMoverTask=false
|
||||
let item = target.parentElement
|
||||
this.left = item.offsetLeft
|
||||
this.top=item.offsetTop+item.offsetHeight-50;
|
||||
this.moveDisplay = 'block';
|
||||
this.currentImg = target.getElementsByTagName('img')[0].src
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
picList[0].addEventListener('mouseout',(ev)=>{
|
||||
ev = ev || window.event;
|
||||
let target = ev.target || ev.srcElement;
|
||||
//console.log('移除',target)
|
||||
if('ant-upload-list-item-info' == target.className){
|
||||
this.showMoverTask=true
|
||||
setTimeout(()=>{
|
||||
if(this.moverHold === false)
|
||||
this.moveDisplay = 'none';
|
||||
},100)
|
||||
}
|
||||
if('ant-upload-list-item ant-upload-list-item-done' == target.className || 'ant-upload-list ant-upload-list-picture-card'== target.className){
|
||||
this.moveDisplay = 'none';
|
||||
}
|
||||
})
|
||||
//---------------------------- end 图片左右换位置 -------------------------------------
|
||||
}
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.uploadty-disabled{
|
||||
.ant-upload-list-item {
|
||||
.anticon-close{
|
||||
display: none;
|
||||
}
|
||||
.anticon-delete{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
//---------------------------- begin 图片左右换位置 -------------------------------------
|
||||
.uploadty-mover-mask{
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
opacity: .8;
|
||||
color: #fff;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
}
|
||||
//---------------------------- end 图片左右换位置 -------------------------------------
|
||||
</style>
|
||||
@@ -0,0 +1,509 @@
|
||||
# JDate 日期组件 使用文档
|
||||
|
||||
###### 说明: antd-vue日期组件需要用moment中转一下,用起来不是很方便,特二次封装,使用时只需要传字符串即可
|
||||
## 参数配置
|
||||
| 参数 | 类型 | 必填 |说明|
|
||||
|--------------|---------|----|---------|
|
||||
| placeholder |string | | placeholder |
|
||||
| readOnly | boolean | | true/false 默认false |
|
||||
| value | string | | 绑定v-model或是v-decorator后不需要设置 |
|
||||
| showTime | boolean | | 是否展示时间true/false 默认false |
|
||||
| dateFormat | string | |日期格式 默认'YYYY-MM-DD' 若showTime设置为true则需要将其设置成对应的时间格式(如:YYYY-MM-DD HH:mm:ss) |
|
||||
| triggerChange | string | |触发组件值改变的事件是否是change,当使用v-decorator时且没有设置decorator的option.trigger为input需要设置该值为true |
|
||||
使用示例
|
||||
----
|
||||
1.组件带有v-model的使用方法
|
||||
```vue
|
||||
<j-date v-model="dateStr"></j-date>
|
||||
```
|
||||
|
||||
2.组件带有v-decorator的使用方法
|
||||
a).设置trigger-change属性为true
|
||||
```vue
|
||||
<j-date :trigger-change="true" v-decorator="['dateStr',{}]"></j-date>
|
||||
```
|
||||
|
||||
b).设置decorator的option.trigger为input
|
||||
```vue
|
||||
<j-date v-decorator="['dateStr',{trigger:'input'}]"></j-date>
|
||||
```
|
||||
|
||||
3.其他使用
|
||||
添加style
|
||||
```vue
|
||||
<j-date v-model="dateStr" style="width:100%"></j-date>
|
||||
```
|
||||
添加placeholder
|
||||
```vue
|
||||
<j-date v-model="dateStr" placeholder="请输入dateStr"></j-date>
|
||||
```
|
||||
添加readOnly
|
||||
```vue
|
||||
<j-date v-model="dateStr" :read-only="true"></j-date>
|
||||
```
|
||||
|
||||
备注:
|
||||
script内需引入jdate
|
||||
```vue
|
||||
<script>
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
export default {
|
||||
name: "demo",
|
||||
components: {
|
||||
JDate
|
||||
}
|
||||
//...
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
# JSuperQuery 高级查询 使用文档
|
||||
## 参数配置
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|--------------|---------|----|----------------------|
|
||||
| fieldList | array |✔| 需要查询的列集合示例如下,type类型有:date/datetime/string/int/number |
|
||||
| callback | array | | 回调函数名称(非必须)默认handleSuperQuery |
|
||||
|
||||
fieldList结构示例:
|
||||
```vue
|
||||
const superQueryFieldList=[{
|
||||
type:"date",
|
||||
value:"birthday",
|
||||
text:"生日"
|
||||
},{
|
||||
type:"string",
|
||||
value:"name",
|
||||
text:"用户名"
|
||||
},{
|
||||
type:"int",
|
||||
value:"age",
|
||||
text:"年龄"
|
||||
}]
|
||||
```
|
||||
页面代码概述:
|
||||
----
|
||||
1.import之后再components之内声明
|
||||
```vue
|
||||
import JSuperQuery from '@/components/jeecg/JSuperQuery.vue';
|
||||
export default {
|
||||
name: "JeecgDemoList",
|
||||
components: {
|
||||
JSuperQuery
|
||||
},
|
||||
|
||||
```
|
||||
2.页面引用
|
||||
```vue
|
||||
<!-- 高级查询区域 -->
|
||||
<j-super-query :fieldList="fieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
|
||||
```
|
||||
3.list页面data中需要定义三个属性:
|
||||
```vue
|
||||
fieldList:superQueryFieldList,
|
||||
superQueryFlag:false,
|
||||
superQueryParams:""
|
||||
```
|
||||
4.list页面声明回调事件handleSuperQuery(与组件的callback对应即可)
|
||||
```vue
|
||||
//高级查询方法
|
||||
handleSuperQuery(arg) {
|
||||
if(!arg){
|
||||
this.superQueryParams=''
|
||||
this.superQueryFlag = false
|
||||
}else{
|
||||
this.superQueryFlag = true
|
||||
this.superQueryParams=JSON.stringify(arg)
|
||||
}
|
||||
this.loadData()
|
||||
},
|
||||
```
|
||||
5.改造list页面方法
|
||||
```vue
|
||||
// 获取查询条件
|
||||
getQueryParams() {
|
||||
let sqp = {}
|
||||
if(this.superQueryParams){
|
||||
sqp['superQueryParams']=encodeURI(this.superQueryParams)
|
||||
}
|
||||
var param = Object.assign(sqp, this.queryParam, this.isorter);
|
||||
param.field = this.getQueryField();
|
||||
param.pageNo = this.ipagination.current;
|
||||
param.pageSize = this.ipagination.pageSize;
|
||||
return filterObj(param);
|
||||
},
|
||||
```
|
||||
6.打开弹框调用show方法:
|
||||
```vue
|
||||
this.$refs.superQueryModal.show();
|
||||
```
|
||||
|
||||
# JEllipsis 字符串超长截取省略号显示
|
||||
|
||||
###### 说明: 遇到超长文本展示,通过此标签可以截取省略号显示,鼠标放置会提示全文本
|
||||
## 参数配置
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|--------|---------|----|----------------|
|
||||
| value |string | 必填 | 字符串文本|
|
||||
| length | number | 非必填 | 默认25 |
|
||||
使用示例
|
||||
----
|
||||
1.组件带有v-model的使用方法
|
||||
```vue
|
||||
<j-ellipsis :value="text"/>
|
||||
|
||||
|
||||
# Modal弹框实现最大化功能
|
||||
|
||||
1.定义modal的宽度:
|
||||
```vue
|
||||
<a-modal
|
||||
:width="modalWidth"
|
||||
|
||||
|
||||
/>
|
||||
```
|
||||
2.自定义modal的title,居右显示切换图标
|
||||
```vue
|
||||
<template slot="title">
|
||||
<div style="width: 100%;">
|
||||
<span>{{ title }}</span>
|
||||
<span style="display:inline-block;width:calc(100% - 51px);padding-right:10px;text-align: right">
|
||||
<a-button @click="toggleScreen" icon="appstore" style="height:20px;width:20px;border:0px"></a-button>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
3.定义toggleScreen事件,用于切换modal宽度
|
||||
```vue
|
||||
toggleScreen(){
|
||||
if(this.modaltoggleFlag){
|
||||
this.modalWidth = window.innerWidth;
|
||||
}else{
|
||||
this.modalWidth = 800;
|
||||
}
|
||||
this.modaltoggleFlag = !this.modaltoggleFlag;
|
||||
},
|
||||
```
|
||||
4.data中声明上述用到的属性
|
||||
```vue
|
||||
data () {
|
||||
return {
|
||||
modalWidth:800,
|
||||
modaltoggleFlag:true,
|
||||
```
|
||||
|
||||
# <a-select/> 下拉选项滚动错位的解决方法
|
||||
|
||||
## 问题描述
|
||||
|
||||
当使用了 `a-modal` 或其他带有滚动条的组件时,使用`a-select`组件并打开下拉框时滚动滚动条,就会导致错位的问题产生。
|
||||
|
||||
## 解决方法
|
||||
|
||||
大多数情况下,在 `a-select` 上添加一个 `getPopupContainer` 属性,值为`node => node.parentNode`即可解决。
|
||||
但是如果遇到 `a-select` 标签层级过深的情况,可能仍然会显示异常,只需要多加几个`.parentNode` (例:node => node.parentNode.parentNode.parentNode)多尝试几次直到解决问题即可。
|
||||
|
||||
### 代码示例
|
||||
|
||||
```html
|
||||
<a-select
|
||||
placeholder="请选择展示模板"
|
||||
:options="dicts.displayTemplate"
|
||||
:getPopupContainer="node => node.parentNode"
|
||||
/>
|
||||
```
|
||||
|
||||
# JAsyncTreeList 异步数列表组件使用说明
|
||||
|
||||
## 引入组件
|
||||
|
||||
```js
|
||||
import JTreeTable from '@/components/jeecg/JTreeTable'
|
||||
export default {
|
||||
components: { JTreeTable }
|
||||
}
|
||||
```
|
||||
|
||||
## 所需参数
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|-------------|--------|--------|--------------------------------------------------------------|
|
||||
| rowKey | String | 非必填 | 表格行 key 的取值,默认为"id" |
|
||||
| columns | Array | 必填 | 表格列的配置描述,具体见Antd官方文档 |
|
||||
| url | String | 必填 | 数据查询url |
|
||||
| childrenUrl | String | 非必填 | 查询子级时的url,若不填则使用url参数查询子级 |
|
||||
| queryKey | String | 非必填 | 根据某个字段查询,如果传递 id 就根据 id 查询,默认为parentId |
|
||||
| queryParams | Object | 非必填 | 查询参数,当查询参数改变的时候会自动重新查询,默认为{} |
|
||||
| topValue | String | 非必填 | 查询顶级时的值,如果顶级为0,则传0,默认为null |
|
||||
| tableProps | Object | 非必填 | 自定义给内部table绑定的props |
|
||||
|
||||
## 代码示例
|
||||
|
||||
```html
|
||||
<template>
|
||||
<a-card :bordered="false">
|
||||
<j-tree-table :url="url" :columns="columns" :tableProps="tableProps"/>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JTreeTable from '@/components/jeecg/JTreeTable'
|
||||
|
||||
export default {
|
||||
name: 'AsyncTreeTable',
|
||||
components: { JTreeTable },
|
||||
data() {
|
||||
return {
|
||||
url: '/api/asynTreeList',
|
||||
columns: [
|
||||
{ title: '菜单名称', dataIndex: 'name' },
|
||||
{ title: '组件', dataIndex: 'component' },
|
||||
{ title: '排序', dataIndex: 'orderNum' }
|
||||
],
|
||||
selectedRowKeys: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
tableProps() {
|
||||
let _this = this
|
||||
return {
|
||||
// 列表项是否可选择
|
||||
// 配置项见:https://vue.ant.design/components/table-cn/#rowSelection
|
||||
rowSelection: {
|
||||
selectedRowKeys: _this.selectedRowKeys,
|
||||
onChange: (selectedRowKeys) => _this.selectedRowKeys = selectedRowKeys
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
# JCheckbox 使用文档
|
||||
|
||||
###### 说明: antd-vue checkbox组件处理的是数组,用起来不是很方便,特二次封装,使用时只需处理字符串即可
|
||||
## 参数配置
|
||||
| 参数 | 类型 | 必填 |说明|
|
||||
|--------------|---------|----|---------|
|
||||
| options |array |✔| checkbox需要配置的项,是个数组,数组中每个对象包含两个属性:label(用于显示)和value(用于存储) |
|
||||
|
||||
使用示例
|
||||
----
|
||||
```vue
|
||||
<template>
|
||||
<a-form :form="form">
|
||||
<a-form-item label="v-model式用法">
|
||||
<j-checkbox v-model="sport" :options="sportOptions"></j-checkbox><span>{{ sport }}</span>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="v-decorator式用法">
|
||||
<j-checkbox v-decorator="['sport']" :options="sportOptions"></j-checkbox><span>{{ getFormFieldValue('sport') }}</span>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JCheckbox from '@/components/jeecg/JCheckbox'
|
||||
export default {
|
||||
components: {JCheckbox},
|
||||
data() {
|
||||
return {
|
||||
form: this.$form.createForm(this),
|
||||
sport:'',
|
||||
sportOptions:[
|
||||
{
|
||||
label:"足球",
|
||||
value:"1"
|
||||
},{
|
||||
label:"篮球",
|
||||
value:"2"
|
||||
},{
|
||||
label:"乒乓球",
|
||||
value:"3"
|
||||
}]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getFormFieldValue(field){
|
||||
return this.form.getFieldValue(field)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
# JCodeEditor 使用文档
|
||||
|
||||
###### 说明: 一个简易版的代码编辑器,支持语法高亮
|
||||
## 参数配置
|
||||
| 参数 | 类型 | 必填 |说明|
|
||||
|--------------|---------|----|---------|
|
||||
| language |string | | 表示当前编写代码的类型 javascript/html/css/sql |
|
||||
| placeholder |string | | placeholder |
|
||||
| lineNumbers |Boolean | | 是否显示行号 |
|
||||
| fullScreen |Boolean | | 是否显示全屏按钮 |
|
||||
| zIndex |string | | 全屏以后的z-index |
|
||||
|
||||
使用示例
|
||||
----
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<j-code-editor
|
||||
language="javascript"
|
||||
v-model="editorValue"
|
||||
:fullScreen="true"
|
||||
style="min-height: 100px"/>
|
||||
{{ editorValue }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JCodeEditor from '@/components/jeecg/JCodeEditor'
|
||||
export default {
|
||||
components: {JCodeEditor},
|
||||
data() {
|
||||
return {
|
||||
form: this.$form.createForm(this),
|
||||
editorValue:'',
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
# JFormContainer 使用文档
|
||||
|
||||
###### 说明: 暂用于表单禁用
|
||||
|
||||
使用示例
|
||||
----
|
||||
```vue
|
||||
<!-- 在form下直接写这个组件,设置disabled为true就能将此form中的控件禁用 -->
|
||||
<a-form layout="inline" :form="form" >
|
||||
<j-form-container disabled>
|
||||
<!-- 表单内容省略..... -->
|
||||
</j-form-container>
|
||||
</a-form>
|
||||
```
|
||||
|
||||
# JImportModal 使用文档
|
||||
|
||||
###### 说明: 用于列表页面导入excel功能
|
||||
|
||||
使用示例
|
||||
----
|
||||
```vue
|
||||
|
||||
<template>
|
||||
<!-- 此处省略部分代码...... -->
|
||||
<a-button @click="handleImportXls" type="primary" icon="upload">导入</a-button>
|
||||
<!-- 此处省略部分代码...... -->
|
||||
<j-import-modal ref="importModal" :url="getImportUrl()" @ok="importOk"></j-import-modal>
|
||||
<!-- 此处省略部分代码...... -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JCodeEditor from '@/components/jeecg/JCodeEditor'
|
||||
export default {
|
||||
components: {JCodeEditor},
|
||||
data() {
|
||||
return {
|
||||
//省略代码......
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
//省略部分代码......
|
||||
handleImportXls(){
|
||||
this.$refs.importModal.show()
|
||||
},
|
||||
getImportUrl(){
|
||||
return '你自己处理上传业务的后台地址'
|
||||
},
|
||||
importOk(){
|
||||
this.loadData(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
# JSlider 滑块验证码
|
||||
|
||||
使用示例
|
||||
----
|
||||
```vue
|
||||
<template>
|
||||
<div style="width: 300px">
|
||||
<j-slider @onSuccess="sliderSuccess"></j-slider>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JSlider from '@/components/jeecg/JSlider'
|
||||
export default {
|
||||
components: {JSlider},
|
||||
data() {
|
||||
return {
|
||||
form: this.$form.createForm(this),
|
||||
editorValue:'',
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
sliderSuccess(){
|
||||
console.log("验证完成")
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
|
||||
# JTreeSelect 树形下拉组件
|
||||
异步加载的树形下拉组件
|
||||
|
||||
## 参数配置
|
||||
| 参数 | 类型 | 必填 |说明|
|
||||
|--------------|---------|----|---------|
|
||||
| placeholder |string | | placeholder |
|
||||
| dict |string | ✔| 表名,显示字段名,存储字段名拼接的字符串 |
|
||||
| pidField |string | ✔| 父ID的字段名 |
|
||||
| pidValue |string | | 根节点父ID的值 默认'0' 不可以设置为空,如果想使用此组件,而数据库根节点父ID为空,请修改之 |
|
||||
| multiple |boolean | |是否支持多选 |
|
||||
|
||||
使用示例
|
||||
----
|
||||
```vue
|
||||
<template>
|
||||
<a-form>
|
||||
<a-form-item label="树形下拉测试" style="width: 300px">
|
||||
<j-tree-select
|
||||
v-model="departId"
|
||||
placeholder="请选择部门"
|
||||
dict="sys_depart,depart_name,id"
|
||||
pidField="parent_id">
|
||||
</j-tree-select>
|
||||
{{ departId }}
|
||||
</a-form-item>
|
||||
</a-form >
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JTreeSelect from '@/components/jeecg/JTreeSelect'
|
||||
export default {
|
||||
components: {JTreeSelect},
|
||||
data() {
|
||||
return {
|
||||
departId:""
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,577 @@
|
||||
# JEditableTable 帮助文档
|
||||
|
||||
## 参数配置
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|--------------|---------|------|---------------------------------------------------------------------------------|
|
||||
| columns | array | ✔️ | 表格列的配置描述,具体项见下表 |
|
||||
| dataSource | array | ✔️ | 表格数据 |
|
||||
| loading | boolean | | 是否正在加载,加载中不会显示任何行,默认false |
|
||||
| actionButton | boolean | | 是否显示操作按钮,包括"新增"、"删除",默认false |
|
||||
| rowNumber | boolean | | 是否显示行号,默认false |
|
||||
| rowSelection | boolean | | 是否可选择行,默认false |
|
||||
| dragSort | boolean | | 是否可拖动排序,默认false |
|
||||
| dragSortKey | string | | 拖动排序存储的Key,无需定义在columns内也能在getValues()时获取到值,默认orderNum |
|
||||
| maxHeight | number | | 设定最大高度(px),默认400 |
|
||||
| disabledRows | object | | 设定禁用的行,被禁用的行无法被选择和编辑,配置方法可以查看示例 |
|
||||
| disabled | boolean | | 是否禁用所有行,默认false |
|
||||
|
||||
### columns 参数详解
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|---------------|---------|------|--------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| title | string | ✔️ | 表格列头显示的问题 |
|
||||
| key | string | ✔️ | 列数据在数据项中对应的 key,必须是唯一的 |
|
||||
| type | string | ✔️ | 表单的类型,可以通过`JEditableTableUtil.FormTypes`赋值 |
|
||||
| width | string | | 列的宽度,可以是百分比,也可以是`px`或其他单位,建议设置为百分比,且每一列的宽度加起来不应超过100%,否则可能会不能达到预期的效果。留空会自动计算百分比 |
|
||||
| placeholder | string | | 表单预期值的提示信息,可以使用`${...}`变量替换文本(详见`${...} 变量使用方式`) |
|
||||
| defaultValue | string | | 默认值,在新增一行时生效 |
|
||||
| validateRules | array | | 表单验证规则,配置方式见[validateRules 配置规则](#validaterules-配置规则) |
|
||||
| props | object | | 设置添加给表单元素的自定义属性,例如:`props:{title: 'show title'}` |
|
||||
| disabled | boolean | | 是否禁用当前列,默认false |
|
||||
|
||||
#### 当 type=checkbox 时所需的参数
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|----------------|---------|------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| defaultChecked | boolean | | 默认值是否选中 |
|
||||
| customValue | array | | 自定义值,checkbox需要的是boolean值,如果数据是其他值(例如`'Y' or 'N'`)时,就会导致错误,所以提供了该属性进行转换,例:`customValue: ['Y','N']`,会将`true`转换为`'Y'`,`false`转换为`'N'`,反之亦然 |
|
||||
|
||||
#### 当 type=select 时所需的参数
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|------------|---------|------|----------------------------------------------------|
|
||||
| options | array | ✔️ | 下拉选项列表,详见下表 |
|
||||
| allowInput | boolean | | 是否允许用户输入内容,并创建新的内容 |
|
||||
| dictCode | String | | 数据字典Code,若options也有值,则拼接在options后面 |
|
||||
|
||||
##### options 所需参数
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|-----------|------------|------|----------------------------------------------------------------------|
|
||||
| text | string | ✔️ | 显示标题 |
|
||||
| value | string | ✔️ | 真实值 |
|
||||
| ~~title~~ | ~~string~~ | | ~~显示标题(已废弃,若同时填写了 title 和 text 那么优先使用 text)~~ |
|
||||
|
||||
#### 当 type=upload 时所需的参数
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|--------------|---------|------|--------------------------------------------------------------------------------------|
|
||||
| action | string | ✔️ | 上传文件路径 |
|
||||
| token | boolean | | 上传的时候是否传递token |
|
||||
| responseName | string | ✔️ | 若要从上传成功后从response中取出返回的文件名,那么这里填后台返回的包含文件名的字段名 |
|
||||
|
||||
#### 当 type=slot 时所需的参数
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|----------|--------|------|------------|
|
||||
| slotName | string | ✔️ | slot的名称 |
|
||||
|
||||
### validateRules 配置规则
|
||||
|
||||
`validateRules` 需要的是一个数组,数组里每项都是一个规则,规则是object类型,规则的各个参数如下
|
||||
|
||||
- `required` 是否必填,可选值为`true`or`false`
|
||||
- `pattern` 正则表达式验证,只有成功匹配该正则的值才能成功通过验证
|
||||
- `handler` 自定义函数校验,使用方法请见[示例五](#示例五)
|
||||
- `message` 当验证未通过时显示的提示文本,可以使用`${...}`变量替换文本(详见`${...} 变量使用方式`)
|
||||
- 配置示例请看[示例二](#示例二)
|
||||
|
||||
## 事件
|
||||
|
||||
| 事件名 | 触发时机 | 参数 |
|
||||
|-----------------|----------------------------------------------------|--------------------------------------------------|
|
||||
| added | 当添加行操作完成后触发 | |
|
||||
| deleted | 当删除行操作完成后触发(批量删除操作只会触发一次) | `deleteIds` 被逻辑删除的id |
|
||||
| selectRowChange | 当行被选中或取消选中时触发 | `selectedRowIds` 被选中行的id |
|
||||
| valueChange | 当数据发生改变的时候触发的事件 | `{ type, row, column, value, target }` Event对象 |
|
||||
|
||||
## 方法
|
||||
|
||||
关于方法的如何调用的问题,请在**FAQ**中查看[方法如何调用](#方法如何调用)
|
||||
|
||||
### initialize
|
||||
|
||||
用于初始化表格(清空表格)
|
||||
|
||||
- `参数:` 无
|
||||
- `返回值:` 无
|
||||
|
||||
### resetScrollTop
|
||||
|
||||
重置滚动条Top位置
|
||||
|
||||
- `参数:`
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|--------|------|--------------------------------------------------------------------------------------------------------|
|
||||
| top | number | | 新top位置,留空则滚动到上次记录的位置,用于解决切换tab选项卡时导致白屏以及自动将滚动条滚动到顶部的问题 |
|
||||
|
||||
- `返回值:` 无
|
||||
|
||||
### add
|
||||
|
||||
主动添加行,默认情况下,当用户的滚动条已经在底部的时候,会将滚动条固定在底部,即添加后无需用户手动滚动,而会自动滚动到底部
|
||||
|
||||
- `参数:`
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|---------------------|---------|------|---------------------------------------------------------------------|
|
||||
| num | number | | 添加几行,默认为1 |
|
||||
| forceScrollToBottom | boolean | | 是否在添加后无论用户的滚动条在什么位置都强制滚动到底部,默认为false |
|
||||
|
||||
- `返回值:` 无
|
||||
|
||||
### removeRows
|
||||
|
||||
主动删除一行或多行
|
||||
|
||||
- `参数:`
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|-----------------|------|--------------------------------------------------------------------------------------------|
|
||||
| id | string 或 array | ✔️ | 被删除行的id。如果要删除一个,可以直接传id,如果要删除多个,需要将多个id封装成一个数组传入 |
|
||||
|
||||
- `返回值:` 无
|
||||
|
||||
### removeSelectedRows
|
||||
|
||||
主动删除被选中的行
|
||||
|
||||
- `参数:` 无
|
||||
- `返回值:` 无
|
||||
|
||||
### getValues
|
||||
|
||||
用于获取表格里所有表单的值,可进行表单验证
|
||||
|
||||
- `参数:`
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|----------|----------|------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| callback | function | ✔️ | 获取值的回调方法,会传入`error`和`values`两个参数。`error`:未通过验证的数量,当等于`0`时代表验证通过;`values`:获取的值(即使未通过验证该字段也有数据) |
|
||||
| validate | boolean | | 是否进行表单验证,默认为`true`,设为`false`则代表忽略表单验证 |
|
||||
| rowIds | array | | 默认返回所有行的数据,如果传入了`rowIds`,那么就会只返回与该`rowIds`相匹配的数据,如果没有匹配的数据,就会返回空数组 |
|
||||
|
||||
- `返回值:` 无
|
||||
|
||||
|
||||
### getValuesSync
|
||||
|
||||
`getValues`的同步版,会直接将获取到的数据返回
|
||||
|
||||
- `参数:`
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|---------|--------|------|------------------------|
|
||||
| options | object | | 选项,详见下方所需参数 |
|
||||
|
||||
- - `options` 所需参数
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|----------|---------|------|----------------------------------------------------------------------------------------------------------------------|
|
||||
| validate | boolean | | 是否进行表单验证,默认为`true`,设为`false`则代表忽略表单验证 |
|
||||
| rowIds | array | | 默认返回所有行的数据,如果传入了`rowIds`,那么就会只返回与该`rowIds`相匹配的数据,如果没有匹配的数据,就会返回空数组 |
|
||||
|
||||
- `返回值:` object
|
||||
- `error` 未通过验证的数量,当等于`0`时代表验证通过
|
||||
- `values` 获取的值(即使未通过验证该字段也有数据)
|
||||
|
||||
- `使用示例`
|
||||
|
||||
```js
|
||||
let { error, values } = this.$refs.editableTable.getValuesSync({ validate: true, rowIds: ['rowId1', 'rowId2'] })
|
||||
if (error === 0) {
|
||||
console.log('表单验证通过,数据:', values);
|
||||
} else {
|
||||
console.log('未通过表单验证,数据:', values);
|
||||
}
|
||||
```
|
||||
|
||||
### getValuesPromise
|
||||
|
||||
`getValues`的promise版,会在`resolve`中传入获取到的值,会在`reject`中传入失败原因,例如`VALIDATE_NO_PASSED`
|
||||
|
||||
- `参数:`
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|----------|---------|------|----------------------------------------------------------------------------------------------------------------------|
|
||||
| validate | boolean | | 同`getValues`的`validate`参数 |
|
||||
| rowIds | array | | 默认返回所有行的数据,如果传入了`rowIds`,那么就会只返回与该`rowIds`相匹配的数据,如果没有匹配的数据,就会返回空数组 |
|
||||
|
||||
- `返回值:` Promise
|
||||
|
||||
### getDeleteIds
|
||||
|
||||
用于获取被逻辑删除的行的id,返回一个数组,用户可将该数组传入后台,并进行批量删除
|
||||
|
||||
- `参数:` 无
|
||||
- `返回值:` array
|
||||
|
||||
### getAll
|
||||
|
||||
获取所有的数据,包括values、deleteIds
|
||||
会在`resolve`中传入获取到的值:`{values, deleteIds}`
|
||||
会在`reject`中传入失败原因,例如`VALIDATE_NO_PASSED`
|
||||
|
||||
- `参数:`
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|----------|---------|------|-------------------------------|
|
||||
| validate | boolean | | 同`getValues`的`validate`参数 |
|
||||
|
||||
- `返回值:` Promise
|
||||
|
||||
### setValues
|
||||
|
||||
主动设置表格中某行某列的值
|
||||
|
||||
- `参数:`
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|-------|------|------------------------------------------------------------|
|
||||
| values | array | | 传入一个数组,数组中的每项都是一行的新值,具体见下面的示例 |
|
||||
|
||||
- `返回值:` 无
|
||||
- `示例:`
|
||||
|
||||
```js
|
||||
setValues([
|
||||
{
|
||||
rowKey: id1, // 行的id
|
||||
values: { // 在这里 values 中的 name 是你 columns 中配置的 key
|
||||
'name': 'zhangsan',
|
||||
'age': '20'
|
||||
}
|
||||
},
|
||||
{
|
||||
rowKey: id2,
|
||||
values: {
|
||||
'name': 'lisi',
|
||||
'age': '23'
|
||||
}
|
||||
}
|
||||
])
|
||||
```
|
||||
### clearSelection
|
||||
|
||||
主动清空选择的行
|
||||
|
||||
- `参数:` 无
|
||||
- `返回值:` 无
|
||||
|
||||
## 内置插槽
|
||||
|
||||
| 插槽名 | 说明 |
|
||||
|--------------|------------------------------------------------------|
|
||||
| buttonBefore | 在操作按钮的**前面**插入插槽,不受`actionButton`属性的影响 |
|
||||
| buttonAfter | 在操作按钮的**后面**插入插槽,不受`actionButton`属性的影响 |
|
||||
|
||||
## ${...} 变量使用方式
|
||||
|
||||
在`placeholder`和`message`这两个属性中可以使用`${...}`变量来替换文本
|
||||
在[示例二](#示例二)中,配置了`title`为`名称`的一列,而`placeholder`配置成了`请输入${title}`,那么最终显示效果为`请输入名称`
|
||||
这就是`${...}`变量的使用方式,在`${}`中可以使用的变量有`title`、`key`、`defaultValue`这三个属性的值
|
||||
|
||||
## JEditableTableUtil 使用说明
|
||||
|
||||
在之前配置`columns`时提到过`JEditableTableUtil`这个工具类,那么如果想要知道详细的使用说明就请看这里
|
||||
|
||||
### export 的常量
|
||||
|
||||
#### FormTypes
|
||||
|
||||
这是配置`columns.type`时用到的常量值,其中包括
|
||||
|
||||
- `normal` 默认,直接显示值,不渲染表单
|
||||
- `input` 显示输入框
|
||||
- `inputNumber` 显示数字输入框
|
||||
- `checkbox` 显示多选框
|
||||
- `select` 显示选择器(下拉框)
|
||||
- `date` 日期选择器
|
||||
- `datetime` 日期时间选择器
|
||||
- `upload` 上传组件(文件域)
|
||||
- `slot` 自定义插槽
|
||||
|
||||
### VALIDATE_NO_PASSED
|
||||
|
||||
在判断表单验证是否通过时使用,如果 reject 的值 === VALIDATE_NO_PASSED 则代表表单验证未通过,你可以做相应的其他处理,反之则可能是发生了报错,可以使用 `console.error` 输出
|
||||
|
||||
### 封装的方法
|
||||
|
||||
#### validateTables
|
||||
|
||||
当你的页面中存在多个JEditableTable实例的时候,如果要获取每个实例的值、判断表单验证是否通过,就会让代码变得极其冗余、繁琐,于是我们就将该操作封装成了一个函数供你调用,它可以同时获取并验证多个JEditableTable实例的值,只有当所有实例的表单验证都通过后才会返回值,否则将会告诉你具体哪个实例没有通过验证。具体使用方法请看下面的示例
|
||||
|
||||
- `参数:`
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|-------|------|--------------------------------------------------------|
|
||||
| cases | array | | 传入一个数组,数组中的每项都是一个JEditableTable的实例 |
|
||||
|
||||
- `返回值:` Promise
|
||||
- `示例:`
|
||||
|
||||
```js
|
||||
import { validateTables, VALIDATE_NO_PASSED } from '@/utils/JEditableTableUtil'
|
||||
// 封装cases
|
||||
let cases = []
|
||||
cases.push(this.$refs.editableTable1)
|
||||
cases.push(this.$refs.editableTable2)
|
||||
cases.push(this.$refs.editableTable3)
|
||||
cases.push(this.$refs.editableTable4)
|
||||
cases.push(this.$refs.editableTable5)
|
||||
// 同时验证并获取多个实例的值
|
||||
validateTables(cases).then((all) => {
|
||||
// all 是一个数组,每项都对应传入cases的下标,包含values和deleteIds
|
||||
console.log('所有实例的值:', all)
|
||||
}).catch((e = {}) => {
|
||||
// 判断表单验证是否未通过
|
||||
if (e.error === VALIDATE_NO_PASSED) {
|
||||
console.log('未通过验证的实例下标:', e.index)
|
||||
} else {
|
||||
console.error('发生异常:', e)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## FAQ
|
||||
|
||||
### 方法如何调用?
|
||||
|
||||
在[示例一](#示例一)中,设定了一个 `ref="editableTable"` 的属性,那么在vue中就可以使用`this.$refs.editableTable`获取到该表格的实例,并调取其中的方法。
|
||||
假如我要调取`initialize`方法,就可以这么写:`this.$refs.editableTable.initialize()`
|
||||
|
||||
### 如何获取表单的值?
|
||||
|
||||
使用`getValue`方法进行获取,详见[示例三](#示例三)
|
||||
|
||||
### 如何进行表单验证?
|
||||
|
||||
在获取值的时候默认会进行表单验证操作,用户在输入的时候也会对正在输入的表单进行验证,只要配置好规则就可以了
|
||||
|
||||
### 如何添加或删除一行?
|
||||
|
||||
该功能已封装到组件中,你只需要将 `actionButton` 设置为 `true` 即可,当然你也可以在代码中主动调用新增方法或修改,具体见上方的方法介绍。
|
||||
|
||||
### 为什么使用了ATab组件后,切换选项卡会导致白屏或滚动条位置会归零?
|
||||
|
||||
在ATab组件中确实会导致滚动条位置归零,且不会触发`onscroll`方法,所以无法动态加载行,导致白屏的问题出现。
|
||||
解决方法是在ATab组件的`onChange`事件触发时执行实例提供的`resetScrollTop()`方法即可,但是需要注意的是:代码主动改变ATab的`activeKey`不会触发`onChange`事件,还需要你手动调用下。
|
||||
|
||||
- `示例`
|
||||
|
||||
```html
|
||||
<template>
|
||||
<a-tabs @change="handleChangeTab">
|
||||
<a-tab-pane tab="表格1" :forceRender="true" key="1">
|
||||
<j-editable-table
|
||||
ref="editableTable1"
|
||||
:loading="tab1.loading"
|
||||
:columns="tab1.columns"
|
||||
:dataSource="tab1.dataSource"/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="表格2" :forceRender="true" key="2">
|
||||
<j-editable-table
|
||||
ref="editableTable2"
|
||||
:loading="tab2.loading"
|
||||
:columns="tab2.columns"
|
||||
:dataSource="tab2.dataSource"/>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</template>
|
||||
```
|
||||
|
||||
```js
|
||||
/*--- 忽略部分代码片段 ---*/
|
||||
methods: {
|
||||
|
||||
/** 切换tab选项卡的时候重置editableTable的滚动条状态 */
|
||||
handleChangeTab(key) {
|
||||
this.$refs[`editableTable${key}`].resetScrollTop()
|
||||
}
|
||||
|
||||
}
|
||||
/*--- 忽略部分代码片段 ---*/
|
||||
```
|
||||
|
||||
### slot(自定义插槽)如何使用?
|
||||
|
||||
代码示例请看:[示例四(slot)](#示例四(slot))
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
## 示例一
|
||||
|
||||
```html
|
||||
<j-editable-table
|
||||
ref="editableTable"
|
||||
:loading="loading"
|
||||
:columns="columns"
|
||||
:dataSource="dataSource"
|
||||
:rowNumber="true"
|
||||
:rowSelection="true"
|
||||
:actionButton="true"
|
||||
style="margin-top: 8px;"
|
||||
@selectRowChange="handleSelectRowChange"/>
|
||||
```
|
||||
|
||||
## 示例二
|
||||
|
||||
```js
|
||||
|
||||
import { FormTypes } from '@/utils/JEditableTableUtil'
|
||||
|
||||
/*--- 忽略部分代码片断 ---*/
|
||||
columns: [
|
||||
{
|
||||
title: '名称',
|
||||
key: 'name',
|
||||
type: FormTypes.input,
|
||||
placeholder: '请输入${title}',
|
||||
defaultValue: '称名',
|
||||
// 表单验证规则
|
||||
validateRules: [
|
||||
{
|
||||
required: true, // 必填
|
||||
message: '${title}不能为空' // 提示的文本
|
||||
},
|
||||
{
|
||||
pattern: /^[a-z|A-Z][a-z|A-Z\d_-]{0,}$/, // 正则
|
||||
message: '${title}必须以字母开头,可包含数字、下划线、横杠'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '年龄',
|
||||
key: 'age',
|
||||
type: FormTypes.inputNumber,
|
||||
placeholder: '请输入${title}',
|
||||
defaultValue: 18,
|
||||
validateRules: [{required: true, message: '${title}不能为空'}]
|
||||
}
|
||||
]
|
||||
/*--- 忽略部分代码片断 ---*/
|
||||
```
|
||||
|
||||
## 示例三
|
||||
|
||||
```js
|
||||
// 获取被逻辑删除的字段id
|
||||
let deleteIds = this.$refs.editableTable.getDeleteIds();
|
||||
// 获取所有表单的值,并进行验证
|
||||
this.$refs.editableTable.getValues((error, values) => {
|
||||
// 错误数 = 0 则代表验证通过
|
||||
if (error === 0) {
|
||||
this.$message.success('验证通过')
|
||||
// 将通过后的数组提交到后台或自行进行其他处理
|
||||
console.log(deleteIds, values)
|
||||
} else {
|
||||
this.$message.error('验证未通过')
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## 示例四(slot)
|
||||
|
||||
```html
|
||||
<template>
|
||||
<j-editable-table :columns="columns" :dataSource="dataSource">
|
||||
<!-- 定义插槽 -->
|
||||
<!-- 这种定义插槽的写法是vue推荐的新版写法(https://cn.vuejs.org/v2/guide/components-slots.html#具名插槽),旧版已被废弃的写法不再支持 -->
|
||||
<!-- 若webstorm这样写报错,请看这篇文章:https://blog.csdn.net/lxq_9532/article/details/81870651 -->
|
||||
<template v-slot:action="props">
|
||||
<a @click="handleDelete(props)">删除</a>
|
||||
</template>
|
||||
</j-editable-table>
|
||||
</template>
|
||||
<script>
|
||||
import { FormTypes } from '@/utils/JEditableTableUtil'
|
||||
import JEditableTable from '@/components/jeecg/JEditableTable'
|
||||
export default {
|
||||
components: { JEditableTable },
|
||||
data() {
|
||||
return {
|
||||
columns: [
|
||||
// ...
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: '8%',
|
||||
type: FormTypes.slot, // 定义该列为 自定义插值列
|
||||
slotName: 'action' // slot 的名称,对应 v-slot 冒号后面和等号前面的内容
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/* a 标签的点击事件,删除当前选中的行 */
|
||||
handleDelete(props) {
|
||||
// 参数解释
|
||||
// props.index :当前行的下标
|
||||
// props.text :当前值,可能是defaultValue定义的值,也可能是从dataSource中取出的值
|
||||
// props.rowId :当前选中行的id,如果是新增行则是临时id
|
||||
// props.column :当前操作的列
|
||||
// props.getValue :这是一个function,执行后可以获取当前行的所有值(禁止在template中使用)
|
||||
// 例:const value = props.getValue()
|
||||
// props.target :触发当前事件的实例,可直接调用该实例内的方法(禁止在template中使用)
|
||||
// 例:target.add()
|
||||
|
||||
// 使用实例:删除当前操作的行
|
||||
let { rowId, target } = props
|
||||
target.removeRows(rowId)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## 示例五
|
||||
|
||||
```js
|
||||
// 该示例是自定义函数校验
|
||||
columns: [
|
||||
{
|
||||
title: '字段名称',
|
||||
key: 'dbFieldName',
|
||||
type: FormTypes.input,
|
||||
defaultValue: '',
|
||||
validateRules: [
|
||||
{
|
||||
// 自定义函数校验 handler
|
||||
handler(type, value, row, column, callback, target) {
|
||||
// type 触发校验的类型(input、change、blur)
|
||||
// value 当前校验的值
|
||||
// callback(flag, message) 方法必须执行且只能执行一次
|
||||
// flag = 是否通过了校验,不填写或者填写 null 代表不进行任何操作
|
||||
// message = 提示的类型,默认使用配置的 message
|
||||
// target 行编辑的实例对象
|
||||
|
||||
if (type === 'blur') {
|
||||
|
||||
if (value === 'abc') {
|
||||
callback(false, '${title}不能是abc') // false = 未通过,可以跟自定义提示
|
||||
return
|
||||
}
|
||||
|
||||
let { values } = target.getValuesSync({ validate: false })
|
||||
let count = 0
|
||||
for (let val of values) {
|
||||
if (val['dbFieldName'] === value) {
|
||||
if (++count >= 2) {
|
||||
callback(false, '${title}不能重复')
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
callback(true) // true = 通过验证
|
||||
} else {
|
||||
callback() // 不填写或者填写 null 代表不进行任何操作
|
||||
}
|
||||
},
|
||||
message: '${title}默认提示'
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
```
|
||||
@@ -0,0 +1,9 @@
|
||||
import JModal from './JModal'
|
||||
import JFormContainer from './JFormContainer.vue'
|
||||
|
||||
export default {
|
||||
install(Vue) {
|
||||
Vue.component('JFormContainer', JFormContainer)
|
||||
Vue.component(JModal.name, JModal)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-modal
|
||||
title="文件上传"
|
||||
:width="width"
|
||||
:visible="visible"
|
||||
@ok="ok"
|
||||
cancelText="取消"
|
||||
@cancel="close">
|
||||
<!--style="top: 20px;"-->
|
||||
<j-upload :file-type="fileType" :value="filePath" @change="handleChange" :disabled="disabled"></j-upload>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JUpload from '@/components/jeecg/JUpload'
|
||||
import { getFileAccessHttpUrl } from '@/api/manage';
|
||||
|
||||
const getFileName=(path)=>{
|
||||
if(path.lastIndexOf("\\")>=0){
|
||||
let reg=new RegExp("\\\\","g");
|
||||
path = path.replace(reg,"/");
|
||||
}
|
||||
return path.substring(path.lastIndexOf("/")+1);
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'JFilePop',
|
||||
components: { JUpload },
|
||||
props:{
|
||||
title:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
},
|
||||
position:{
|
||||
type:String,
|
||||
default:'right',
|
||||
required:false
|
||||
},
|
||||
height:{
|
||||
type:Number,
|
||||
default:200,
|
||||
required:false
|
||||
},
|
||||
width:{
|
||||
type:Number,
|
||||
default:520,
|
||||
required:false
|
||||
},
|
||||
|
||||
popContainer:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
},
|
||||
disabled:{
|
||||
type:Boolean,
|
||||
default:false,
|
||||
required:false
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
visible:false,
|
||||
filePath:'',
|
||||
id:'',
|
||||
fileType:'file'
|
||||
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
handleChange(value){
|
||||
this.filePath = value;
|
||||
},
|
||||
show(id,value,flag){
|
||||
this.id = id;
|
||||
this.filePath = value;
|
||||
this.visible=true
|
||||
if(flag === 'img'){
|
||||
this.fileType = 'image'
|
||||
}else{
|
||||
this.fileType = 'file'
|
||||
}
|
||||
|
||||
},
|
||||
ok(){
|
||||
if(!this.filePath){
|
||||
this.$message.error("未上传任何文件")
|
||||
return false;
|
||||
}
|
||||
let arr = this.filePath.split(",")
|
||||
let obj = {
|
||||
name:getFileName(arr[0]),
|
||||
url:getFileAccessHttpUrl(arr[0]),
|
||||
path:this.filePath,
|
||||
status: 'done',
|
||||
id:this.id
|
||||
}
|
||||
this.$emit('ok',obj)
|
||||
this.visible=false
|
||||
},
|
||||
close(){
|
||||
this.visible=false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<a-popover trigger="contextmenu" v-model="visible" :placement="position">
|
||||
<!--"(node) => node.parentNode.parentNode"-->
|
||||
<div slot="title">
|
||||
<span>{{ title }}</span>
|
||||
<span style="float: right" title="关闭">
|
||||
<a-icon type="close" @click="visible=false"/>
|
||||
</span>
|
||||
</div>
|
||||
<a-input :value="inputContent" @change="handleInputChange">
|
||||
<a-icon slot="suffix" type="fullscreen" @click.stop="pop" />
|
||||
</a-input>
|
||||
<div slot="content">
|
||||
<textarea :value="inputContent" @input="handleInputChange" :style="{ height: height + 'px', width: width + 'px' }"></textarea>
|
||||
</div>
|
||||
</a-popover>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'JInputPop',
|
||||
props:{
|
||||
title:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
},
|
||||
position:{
|
||||
type:String,
|
||||
default:'right',
|
||||
required:false
|
||||
},
|
||||
height:{
|
||||
type:Number,
|
||||
default:200,
|
||||
required:false
|
||||
},
|
||||
width:{
|
||||
type:Number,
|
||||
default:150,
|
||||
required:false
|
||||
},
|
||||
value:{
|
||||
type:String,
|
||||
required:false
|
||||
},
|
||||
popContainer:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
}
|
||||
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
visible:false,
|
||||
inputContent:''
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
watch:{
|
||||
value:{
|
||||
immediate:true,
|
||||
handler:function(){
|
||||
if(this.value && this.value.length>0){
|
||||
this.inputContent = this.value;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
},
|
||||
methods:{
|
||||
handleInputChange(event){
|
||||
this.inputContent = event.target.value
|
||||
this.$emit('change',this.inputContent)
|
||||
},
|
||||
pop(){
|
||||
this.visible=true
|
||||
},
|
||||
getPopupContainer(node){
|
||||
if(!this.popContainer){
|
||||
return node.parentNode
|
||||
}else{
|
||||
return document.getElementById(this.popContainer)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,928 @@
|
||||
<template>
|
||||
<a-modal
|
||||
title="corn表达式"
|
||||
:width="modalWidth"
|
||||
:visible="visible"
|
||||
:confirmLoading="confirmLoading"
|
||||
@ok="handleSubmit"
|
||||
@cancel="close"
|
||||
cancelText="关闭">
|
||||
<div class="card-container">
|
||||
<a-tabs type="card">
|
||||
<a-tab-pane key="1" type="card">
|
||||
<span slot="tab"><a-icon type="schedule" /> 秒</span>
|
||||
<a-radio-group v-model="result.second.cronEvery">
|
||||
<a-row>
|
||||
<a-radio value="1">每一秒钟</a-radio>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio value="2">每隔
|
||||
<a-input-number size="small" v-model="result.second.incrementIncrement" :min="1" :max="59"></a-input-number>
|
||||
秒执行 从
|
||||
<a-input-number size="small" v-model="result.second.incrementStart" :min="0" :max="59"></a-input-number>
|
||||
秒开始
|
||||
</a-radio>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio value="3">具体秒数(可多选)</a-radio>
|
||||
<a-select style="width:354px;" size="small" mode="multiple" v-model="result.second.specificSpecific">
|
||||
<a-select-option v-for="(val,index) in 60" :key="index" :value="index">{{ index }}</a-select-option>
|
||||
</a-select>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio value="4">周期从
|
||||
<a-input-number size="small" v-model="result.second.rangeStart" :min="1" :max="59"></a-input-number>
|
||||
到
|
||||
<a-input-number size="small" v-model="result.second.rangeEnd" :min="0" :max="59"></a-input-number>
|
||||
秒
|
||||
</a-radio>
|
||||
</a-row>
|
||||
</a-radio-group>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="2">
|
||||
<span slot="tab"><a-icon type="schedule" />分</span>
|
||||
<div class="tabBody">
|
||||
<a-radio-group v-model="result.minute.cronEvery">
|
||||
<a-row>
|
||||
<a-radio value="1">每一分钟</a-radio>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio value="2">每隔
|
||||
<a-input-number size="small" v-model="result.minute.incrementIncrement" :min="1" :max="60"></a-input-number>
|
||||
分执行 从
|
||||
<a-input-number size="small" v-model="result.minute.incrementStart" :min="0" :max="59"></a-input-number>
|
||||
分开始
|
||||
</a-radio>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio value="3">具体分钟数(可多选)</a-radio>
|
||||
<a-select style="width:340px;" size="small" mode="multiple" v-model="result.minute.specificSpecific">
|
||||
<a-select-option v-for="(val,index) in Array(60)" :key="index" :value="index"> {{ index }}</a-select-option>
|
||||
</a-select>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio value="4">周期从
|
||||
<a-input-number size="small" v-model="result.minute.rangeStart" :min="1" :max="60"></a-input-number>
|
||||
到
|
||||
<a-input-number size="small" v-model="result.minute.rangeEnd" :min="0" :max="59"></a-input-number>
|
||||
分
|
||||
</a-radio>
|
||||
</a-row>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="3">
|
||||
<span slot="tab"><a-icon type="schedule" /> 时</span>
|
||||
<div class="tabBody">
|
||||
<a-radio-group v-model="result.hour.cronEvery">
|
||||
<a-row>
|
||||
<a-radio value="1">每一小时</a-radio>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio value="2">每隔
|
||||
<a-input-number size="small" v-model="result.hour.incrementIncrement" :min="0" :max="23"></a-input-number>
|
||||
小时执行 从
|
||||
<a-input-number size="small" v-model="result.hour.incrementStart" :min="0" :max="23"></a-input-number>
|
||||
小时开始
|
||||
</a-radio>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio class="long" value="3">具体小时数(可多选)</a-radio>
|
||||
<a-select style="width:340px;" size="small" mode="multiple" v-model="result.hour.specificSpecific">
|
||||
<a-select-option v-for="(val,index) in Array(24)" :key="index" >{{ index }}</a-select-option>
|
||||
</a-select>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio value="4">周期从
|
||||
<a-input-number size="small" v-model="result.hour.rangeStart" :min="0" :max="23"></a-input-number>
|
||||
到
|
||||
<a-input-number size="small" v-model="result.hour.rangeEnd" :min="0" :max="23"></a-input-number>
|
||||
小时
|
||||
</a-radio>
|
||||
</a-row>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="4">
|
||||
<span slot="tab"><a-icon type="schedule" /> 天</span>
|
||||
<div class="tabBody">
|
||||
<a-radio-group v-model="result.day.cronEvery">
|
||||
<a-row>
|
||||
<a-radio value="1">每一天</a-radio>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio value="2">每隔
|
||||
<a-input-number size="small" v-model="result.week.incrementIncrement" :min="1" :max="7"></a-input-number>
|
||||
周执行 从
|
||||
<a-select size="small" v-model="result.week.incrementStart">
|
||||
<a-select-option v-for="(val,index) in Array(7)" :key="index" :value="index+1">{{ weekDays[index] }}</a-select-option>
|
||||
</a-select>
|
||||
开始
|
||||
</a-radio>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio value="3">每隔
|
||||
<a-input-number size="small" v-model="result.day.incrementIncrement" :min="1" :max="31"></a-input-number>
|
||||
天执行 从
|
||||
<a-input-number size="small" v-model="result.day.incrementStart" :min="1" :max="31"></a-input-number>
|
||||
天开始
|
||||
</a-radio>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio class="long" value="4">具体星期几(可多选)</a-radio>
|
||||
<a-select style="width:340px;" size="small" mode="multiple" v-model="result.week.specificSpecific">
|
||||
<a-select-option v-for="(val,index) in Array(7)" :key="index" :value="index+1">{{ weekDays[index] }}</a-select-option>
|
||||
</a-select>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio class="long" value="5">具体天数(可多选)</a-radio>
|
||||
<a-select style="width:354px;" size="small" mode="multiple" v-model="result.day.specificSpecific">
|
||||
<a-select-option v-for="(val,index) in Array(31)" :key="index" :value="index+1">{{ index+1 }}</a-select-option>
|
||||
</a-select>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio value="6">在这个月的最后一天</a-radio>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio value="7">在这个月的最后一个工作日</a-radio>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio value="8">在这个月的最后一个
|
||||
<a-select size="small" v-model="result.day.cronLastSpecificDomDay">
|
||||
<a-select-option v-for="(val,index) in Array(7)" :key="index" :value="index+1">{{ weekDays[index] }}</a-select-option>
|
||||
</a-select>
|
||||
</a-radio>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio value="9">
|
||||
在本月底前
|
||||
<a-input-number size="small" v-model="result.day.cronDaysBeforeEomMinus" :min="1" :max="31"></a-input-number>
|
||||
天
|
||||
</a-radio>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio value="10">最近的工作日(周一至周五)至本月
|
||||
<a-input-number size="small" v-model="result.day.cronDaysNearestWeekday" :min="1" :max="31"></a-input-number>
|
||||
日
|
||||
</a-radio>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio value="11">在这个月的第
|
||||
<a-input-number size="small" v-model="result.week.cronNthDayNth" :min="1" :max="5"></a-input-number>
|
||||
个
|
||||
<a-select size="small" v-model="result.week.cronNthDayDay">
|
||||
<a-select-option v-for="(val,index) in Array(7)" :key="index" :value="index+1">{{ weekDays[index] }}</a-select-option>
|
||||
</a-select>
|
||||
|
||||
</a-radio>
|
||||
</a-row>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="5">
|
||||
<span slot="tab"><a-icon type="schedule" /> 月</span>
|
||||
<div class="tabBody">
|
||||
<a-radio-group v-model="result.month.cronEvery">
|
||||
<a-row>
|
||||
<a-radio value="1">每一月</a-radio>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio value="2">每隔
|
||||
<a-input-number size="small" v-model="result.month.incrementIncrement" :min="0" :max="12"></a-input-number>
|
||||
月执行 从
|
||||
<a-input-number size="small" v-model="result.month.incrementStart" :min="0" :max="12"></a-input-number>
|
||||
月开始
|
||||
</a-radio>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio class="long" value="3">具体月数(可多选)</a-radio>
|
||||
<a-select style="width:354px;" size="small" filterable mode="multiple" v-model="result.month.specificSpecific">
|
||||
<a-select-option v-for="(val,index) in Array(12)" :key="index" :value="index+1">{{ index+1 }}</a-select-option>
|
||||
</a-select>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio value="4">从
|
||||
<a-input-number size="small" v-model="result.month.rangeStart" :min="1" :max="12"></a-input-number>
|
||||
到
|
||||
<a-input-number size="small" v-model="result.month.rangeEnd" :min="1" :max="12"></a-input-number>
|
||||
月之间的每个月
|
||||
</a-radio>
|
||||
</a-row>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="6">
|
||||
<span slot="tab"><a-icon type="schedule" /> 年</span>
|
||||
<div class="tabBody">
|
||||
<a-radio-group v-model="result.year.cronEvery">
|
||||
<a-row>
|
||||
<a-radio value="1">每一年</a-radio>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio value="2">每隔
|
||||
<a-input-number size="small" v-model="result.year.incrementIncrement" :min="1" :max="99"></a-input-number>
|
||||
年执行 从
|
||||
<a-input-number size="small" v-model="result.year.incrementStart" :min="2019" :max="2119"></a-input-number>
|
||||
年开始
|
||||
</a-radio>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio class="long" value="3">具体年份(可多选)</a-radio>
|
||||
<a-select style="width:354px;" size="small" filterable mode="multiple" v-model="result.year.specificSpecific">
|
||||
<a-select-option v-for="(val,index) in Array(100)" :key="index" :value="2019+index">{{ 2019+index }}</a-select-option>
|
||||
</a-select>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-radio value="4">从
|
||||
<a-input-number size="small" v-model="result.year.rangeStart" :min="2019" :max="2119"></a-input-number>
|
||||
到
|
||||
<a-input-number size="small" v-model="result.year.rangeEnd" :min="2019" :max="2119"></a-input-number>
|
||||
年之间的每一年
|
||||
</a-radio>
|
||||
</a-row>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
<div class="bottom">
|
||||
<span class="value">{{this.cron }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name:'VueCron',
|
||||
props:['data'],
|
||||
data(){
|
||||
return {
|
||||
visible: false,
|
||||
confirmLoading:false,
|
||||
size:'large',
|
||||
weekDays:['天','一','二','三','四','五','六'].map(val=>'星期'+val),
|
||||
result: {
|
||||
second:{},
|
||||
minute:{},
|
||||
hour:{},
|
||||
day:{},
|
||||
week:{},
|
||||
month:{},
|
||||
year:{}
|
||||
},
|
||||
defaultValue: {
|
||||
second:{
|
||||
cronEvery:'',
|
||||
incrementStart:3,
|
||||
incrementIncrement:5,
|
||||
rangeStart:1,
|
||||
rangeEnd:0,
|
||||
specificSpecific:[],
|
||||
},
|
||||
minute:{
|
||||
cronEvery:'',
|
||||
incrementStart:3,
|
||||
incrementIncrement:5,
|
||||
rangeStart:1,
|
||||
rangeEnd:'0',
|
||||
specificSpecific:[],
|
||||
},
|
||||
hour:{
|
||||
cronEvery:'',
|
||||
incrementStart:3,
|
||||
incrementIncrement:5,
|
||||
rangeStart:'0',
|
||||
rangeEnd:'0',
|
||||
specificSpecific:[],
|
||||
},
|
||||
day:{
|
||||
cronEvery:'',
|
||||
incrementStart:1,
|
||||
incrementIncrement:'1',
|
||||
rangeStart:'',
|
||||
rangeEnd:'',
|
||||
specificSpecific:[],
|
||||
cronLastSpecificDomDay:1,
|
||||
cronDaysBeforeEomMinus:1,
|
||||
cronDaysNearestWeekday:1,
|
||||
},
|
||||
week:{
|
||||
cronEvery:'',
|
||||
incrementStart:1,
|
||||
incrementIncrement:1,
|
||||
specificSpecific:[],
|
||||
cronNthDayDay:1,
|
||||
cronNthDayNth:1,
|
||||
},
|
||||
month:{
|
||||
cronEvery:'',
|
||||
incrementStart:3,
|
||||
incrementIncrement:5,
|
||||
rangeStart:1,
|
||||
rangeEnd:1,
|
||||
specificSpecific:[],
|
||||
},
|
||||
year:{
|
||||
cronEvery:'',
|
||||
incrementStart:2017,
|
||||
incrementIncrement:1,
|
||||
rangeStart:2019,
|
||||
rangeEnd: 2019,
|
||||
specificSpecific:[],
|
||||
},
|
||||
label:''
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
modalWidth(){
|
||||
return 608;
|
||||
},
|
||||
secondsText() {
|
||||
let seconds = '';
|
||||
let cronEvery=this.result.second.cronEvery||'';
|
||||
switch (cronEvery.toString()){
|
||||
case '1':
|
||||
seconds = '*';
|
||||
break;
|
||||
case '2':
|
||||
seconds = this.result.second.incrementStart+'/'+this.result.second.incrementIncrement;
|
||||
break;
|
||||
case '3':
|
||||
this.result.second.specificSpecific.map(val=> {seconds += val+','});
|
||||
seconds = seconds.slice(0, -1);
|
||||
break;
|
||||
case '4':
|
||||
seconds = this.result.second.rangeStart+'-'+this.result.second.rangeEnd;
|
||||
break;
|
||||
}
|
||||
return seconds;
|
||||
},
|
||||
minutesText() {
|
||||
let minutes = '';
|
||||
let cronEvery=this.result.minute.cronEvery||'';
|
||||
switch (cronEvery.toString()){
|
||||
case '1':
|
||||
minutes = '*';
|
||||
break;
|
||||
case '2':
|
||||
minutes = this.result.minute.incrementStart+'/'+this.result.minute.incrementIncrement;
|
||||
break;
|
||||
case '3':
|
||||
this.result.minute.specificSpecific.map(val=> {
|
||||
minutes += val+','
|
||||
});
|
||||
minutes = minutes.slice(0, -1);
|
||||
break;
|
||||
case '4':
|
||||
minutes = this.result.minute.rangeStart+'-'+this.result.minute.rangeEnd;
|
||||
break;
|
||||
}
|
||||
return minutes;
|
||||
},
|
||||
hoursText() {
|
||||
let hours = '';
|
||||
let cronEvery=this.result.hour.cronEvery||'';
|
||||
switch (cronEvery.toString()){
|
||||
case '1':
|
||||
hours = '*';
|
||||
break;
|
||||
case '2':
|
||||
hours = this.result.hour.incrementStart+'/'+this.result.hour.incrementIncrement;
|
||||
break;
|
||||
case '3':
|
||||
this.result.hour.specificSpecific.map(val=> {
|
||||
hours += val+','
|
||||
});
|
||||
hours = hours.slice(0, -1);
|
||||
break;
|
||||
case '4':
|
||||
hours = this.result.hour.rangeStart+'-'+this.result.hour.rangeEnd;
|
||||
break;
|
||||
}
|
||||
return hours;
|
||||
},
|
||||
daysText() {
|
||||
let days='';
|
||||
let cronEvery=this.result.day.cronEvery||'';
|
||||
switch (cronEvery.toString()){
|
||||
case '1':
|
||||
break;
|
||||
case '2':
|
||||
case '4':
|
||||
case '11':
|
||||
days = '?';
|
||||
break;
|
||||
case '3':
|
||||
days = this.result.day.incrementStart+'/'+this.result.day.incrementIncrement;
|
||||
break;
|
||||
case '5':
|
||||
this.result.day.specificSpecific.map(val=> {
|
||||
days += val+','
|
||||
});
|
||||
days = days.slice(0, -1);
|
||||
break;
|
||||
case '6':
|
||||
days = "L";
|
||||
break;
|
||||
case '7':
|
||||
days = "LW";
|
||||
break;
|
||||
case '8':
|
||||
days = this.result.day.cronLastSpecificDomDay + 'L';
|
||||
break;
|
||||
case '9':
|
||||
days = 'L-' + this.result.day.cronDaysBeforeEomMinus;
|
||||
break;
|
||||
case '10':
|
||||
days = this.result.day.cronDaysNearestWeekday+"W";
|
||||
break
|
||||
}
|
||||
return days;
|
||||
},
|
||||
weeksText() {
|
||||
let weeks = '';
|
||||
let cronEvery=this.result.day.cronEvery||'';
|
||||
switch (cronEvery.toString()){
|
||||
case '1':
|
||||
case '3':
|
||||
case '5':
|
||||
weeks = '?';
|
||||
break;
|
||||
case '2':
|
||||
weeks = this.result.week.incrementStart+'/'+this.result.week.incrementIncrement;
|
||||
break;
|
||||
case '4':
|
||||
this.result.week.specificSpecific.map(val=> {
|
||||
weeks += val+','
|
||||
});
|
||||
weeks = weeks.slice(0, -1);
|
||||
break;
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '10':
|
||||
weeks = "?";
|
||||
break;
|
||||
case '11':
|
||||
weeks = this.result.week.cronNthDayDay+"#"+this.result.week.cronNthDayNth;
|
||||
break;
|
||||
}
|
||||
return weeks;
|
||||
},
|
||||
monthsText() {
|
||||
let months = '';
|
||||
let cronEvery=this.result.month.cronEvery||'';
|
||||
switch (cronEvery.toString()){
|
||||
case '1':
|
||||
months = '*';
|
||||
break;
|
||||
case '2':
|
||||
months = this.result.month.incrementStart+'/'+this.result.month.incrementIncrement;
|
||||
break;
|
||||
case '3':
|
||||
this.result.month.specificSpecific.map(val=> {
|
||||
months += val+','
|
||||
});
|
||||
months = months.slice(0, -1);
|
||||
break;
|
||||
case '4':
|
||||
months = this.result.month.rangeStart+'-'+this.result.month.rangeEnd;
|
||||
break;
|
||||
}
|
||||
return months;
|
||||
},
|
||||
yearsText() {
|
||||
let years = '';
|
||||
let cronEvery=this.result.year.cronEvery||'';
|
||||
switch (cronEvery.toString()){
|
||||
case '1':
|
||||
years = '*';
|
||||
break;
|
||||
case '2':
|
||||
years = this.result.year.incrementStart+'/'+this.result.year.incrementIncrement;
|
||||
break;
|
||||
case '3':
|
||||
this.result.year.specificSpecific.map(val=> {
|
||||
years += val+','
|
||||
});
|
||||
years = years.slice(0, -1);
|
||||
break;
|
||||
case '4':
|
||||
years = this.result.year.rangeStart+'-'+this.result.year.rangeEnd;
|
||||
break;
|
||||
}
|
||||
return years;
|
||||
},
|
||||
cron(){
|
||||
return `${this.secondsText||'*'} ${this.minutesText||'*'} ${this.hoursText||'*'} ${this.daysText||'*'} ${this.monthsText||'*'} ${this.weeksText||'?'} ${this.yearsText||'*'}`
|
||||
},
|
||||
},
|
||||
watch:{
|
||||
visible:{
|
||||
handler() {
|
||||
// if(this.data){
|
||||
// //this. result = Object.keys(this.data.value).length>0?this.deepCopy(this.data.value):this.deepCopy(this.defaultValue);
|
||||
// //this.result = Object.keys(this.data.value).length>0?clone(this.data.value):clone(this.defaultValue);
|
||||
// //this.result = Object.keys(this.data.value).length>0?clone(JSON.parse(this.data.value)):clone(this.defaultValue);
|
||||
// this.result = Object.keys(this.data.value).length>0?JSON.parse(this.data.value):JSON.parse(JSON.stringify(this.defaultValue));
|
||||
// }else{
|
||||
// //this.result = this.deepCopy(this.defaultValue);
|
||||
// //this.result = clone(this.defaultValue);
|
||||
// this.result = JSON.parse(JSON.stringify(this.defaultValue));
|
||||
// }
|
||||
let label = this.data;
|
||||
if(label){
|
||||
this.secondsReverseExp(label)
|
||||
this.minutesReverseExp(label);
|
||||
this.hoursReverseExp(label);
|
||||
this.daysReverseExp(label);
|
||||
this.daysReverseExp(label);
|
||||
this.monthsReverseExp(label);
|
||||
this.yearReverseExp(label);
|
||||
JSON.parse(JSON.stringify(label));
|
||||
}else {
|
||||
this.result = JSON.parse(JSON.stringify(this.defaultValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
show(){
|
||||
this.visible = true;
|
||||
// console.log('secondsReverseExp',this.secondsReverseExp(this.data));
|
||||
// console.log('minutesReverseExp',this.minutesReverseExp(this.data));
|
||||
// console.log('hoursReverseExp',this.hoursReverseExp(this.data));
|
||||
// console.log('daysReverseExp',this.daysReverseExp(this.data));
|
||||
// console.log('monthsReverseExp',this.monthsReverseExp(this.data));
|
||||
// console.log('yearReverseExp',this.yearReverseExp(this.data));
|
||||
|
||||
},
|
||||
handleSubmit(){
|
||||
this.$emit('ok',this.cron);
|
||||
this.close();
|
||||
this.visible = false;
|
||||
},
|
||||
close(){
|
||||
this.visible = false;
|
||||
},
|
||||
secondsReverseExp(seconds) {
|
||||
let val = seconds.split(" ")[0];
|
||||
//alert(val);
|
||||
let second = {
|
||||
cronEvery:'',
|
||||
incrementStart:3,
|
||||
incrementIncrement:5,
|
||||
rangeStart:1,
|
||||
rangeEnd:0,
|
||||
specificSpecific:[]
|
||||
};
|
||||
switch (true) {
|
||||
case val.includes('*'):
|
||||
second.cronEvery = '1';
|
||||
break;
|
||||
case val.includes('/'):
|
||||
second.cronEvery = '2';
|
||||
second.incrementStart = val.split('/')[0];
|
||||
second.incrementIncrement = val.split('/')[1];
|
||||
break;
|
||||
case val.includes(','):
|
||||
second.cronEvery = '3';
|
||||
second.specificSpecific = val.split(',').map(Number).sort();
|
||||
break;
|
||||
case val.includes('-'):
|
||||
second.cronEvery = '4';
|
||||
second.rangeStart = val.split('-')[0];
|
||||
second.rangeEnd = val.split('-')[1];
|
||||
break;
|
||||
default:
|
||||
second.cronEvery = '1';
|
||||
}
|
||||
this.result.second = second;
|
||||
},
|
||||
minutesReverseExp(minutes) {
|
||||
let val = minutes.split(" ")[1];
|
||||
let minute = {
|
||||
cronEvery:'',
|
||||
incrementStart:3,
|
||||
incrementIncrement:5,
|
||||
rangeStart:1,
|
||||
rangeEnd:0,
|
||||
specificSpecific:[],
|
||||
}
|
||||
switch (true) {
|
||||
case val.includes('*'):
|
||||
minute.cronEvery = '1';
|
||||
break;
|
||||
case val.includes('/'):
|
||||
minute.cronEvery = '2';
|
||||
minute.incrementStart = val.split('/')[0];
|
||||
minute.incrementIncrement = val.split('/')[1];
|
||||
break;
|
||||
case val.includes(','):
|
||||
minute.cronEvery = '3';
|
||||
minute.specificSpecific = val.split(',').map(Number).sort();
|
||||
break;
|
||||
case val.includes('-'):
|
||||
minute.cronEvery = '4';
|
||||
minute.rangeStart = val.split('-')[0];
|
||||
minute.rangeEnd = val.split('-')[1];
|
||||
break;
|
||||
default:
|
||||
minute.cronEvery = '1';
|
||||
}
|
||||
this.result.minute = minute;
|
||||
},
|
||||
hoursReverseExp(hours) {
|
||||
let val = hours.split(" ")[2];
|
||||
let hour ={
|
||||
cronEvery:'',
|
||||
incrementStart:3,
|
||||
incrementIncrement:5,
|
||||
rangeStart:1,
|
||||
rangeEnd:'0',
|
||||
specificSpecific:[],
|
||||
};
|
||||
switch (true) {
|
||||
case val.includes('*'):
|
||||
hour.cronEvery = '1';
|
||||
break;
|
||||
case val.includes('/'):
|
||||
hour.cronEvery = '2';
|
||||
hour.incrementStart = val.split('/')[0];
|
||||
hour.incrementIncrement = val.split('/')[1];
|
||||
break;
|
||||
case val.includes(','):
|
||||
hour.cronEvery = '3';
|
||||
hour.specificSpecific = val.split(',').map(Number).sort();
|
||||
break;
|
||||
case val.includes('-'):
|
||||
hour.cronEvery = '4';
|
||||
hour.rangeStart = val.split('-')[0];
|
||||
hour.rangeEnd = val.split('-')[1];
|
||||
break;
|
||||
default:
|
||||
hour.cronEvery = '1';
|
||||
}
|
||||
this.result.hour = hour;
|
||||
},
|
||||
daysReverseExp(cron) {
|
||||
let days = cron.split(" ")[3];
|
||||
let weeks = cron.split(" ")[5];
|
||||
let day ={
|
||||
cronEvery:'',
|
||||
incrementStart:1,
|
||||
incrementIncrement:1,
|
||||
rangeStart:1,
|
||||
rangeEnd:1,
|
||||
specificSpecific:[],
|
||||
cronLastSpecificDomDay:1,
|
||||
cronDaysBeforeEomMinus:1,
|
||||
cronDaysNearestWeekday:1,
|
||||
};
|
||||
let week = {
|
||||
cronEvery:'',
|
||||
incrementStart:1,
|
||||
incrementIncrement:1,
|
||||
specificSpecific:[],
|
||||
cronNthDayDay:1,
|
||||
cronNthDayNth:'1',
|
||||
};
|
||||
if (!days.includes('?')) {
|
||||
switch (true) {
|
||||
case days.includes('*'):
|
||||
day.cronEvery = '1';
|
||||
break;
|
||||
case days.includes('?'):
|
||||
// 2、4、11
|
||||
break;
|
||||
case days.includes('/'):
|
||||
day.cronEvery = '3';
|
||||
day.incrementStart = days.split('/')[0];
|
||||
day.incrementIncrement = days.split('/')[1];
|
||||
break;
|
||||
case days.includes(','):
|
||||
day.cronEvery = '5';
|
||||
day.specificSpecific = days.split(',').map(Number).sort();
|
||||
// day.specificSpecific.forEach(function (value, index) {
|
||||
// day.specificSpecific[index] = value -1;
|
||||
// });
|
||||
break;
|
||||
case days.includes('LW'):
|
||||
day.cronEvery = '7';
|
||||
break;
|
||||
case days.includes('L-'):
|
||||
day.cronEvery = '9';
|
||||
day.cronDaysBeforeEomMinus = days.split('L-')[1];
|
||||
break;
|
||||
case days.includes('L'):
|
||||
|
||||
//alert(days);
|
||||
if(days.len == 1){
|
||||
day.cronEvery = '6';
|
||||
day.cronLastSpecificDomDay = '1';
|
||||
}
|
||||
else
|
||||
{
|
||||
day.cronEvery = '8';
|
||||
day.cronLastSpecificDomDay = Number(days.split('L')[0]);
|
||||
}
|
||||
break;
|
||||
case days.includes('W'):
|
||||
day.cronEvery = '10';
|
||||
day.cronDaysNearestWeekday = days.split('W')[0];
|
||||
break;
|
||||
default:
|
||||
day.cronEvery = '1';
|
||||
}
|
||||
}else {
|
||||
switch (true){
|
||||
case weeks.includes('/'):
|
||||
day.cronEvery = '2';
|
||||
week.incrementStart = weeks.split("/")[0];
|
||||
week.incrementIncrement = weeks.split("/")[1];
|
||||
break;
|
||||
case weeks.includes(','):
|
||||
day.cronEvery = '4';
|
||||
week.specificSpecific = weeks.split(',').map(Number).sort();
|
||||
break;
|
||||
case '#':
|
||||
day.cronEvery = '11';
|
||||
week.cronNthDayDay = weeks.split("#")[0];
|
||||
week.cronNthDayNth = weeks.split("#")[1];
|
||||
break;
|
||||
default:
|
||||
day.cronEvery = '1';
|
||||
week.cronEvery = '1';
|
||||
}
|
||||
}
|
||||
this.result.day = day;
|
||||
this.result.week = week;
|
||||
},
|
||||
monthsReverseExp(cron) {
|
||||
let months = cron.split(" ")[4];
|
||||
let month = {
|
||||
cronEvery:'',
|
||||
incrementStart:3,
|
||||
incrementIncrement:5,
|
||||
rangeStart:1,
|
||||
rangeEnd:1,
|
||||
specificSpecific:[],
|
||||
};
|
||||
switch (true){
|
||||
case months.includes('*'):
|
||||
month.cronEvery = '1';
|
||||
break;
|
||||
case months.includes('/'):
|
||||
month.cronEvery = '2';
|
||||
month.incrementStart = months.split('/')[0];
|
||||
month.incrementIncrement = months.split('/')[1];
|
||||
break;
|
||||
case months.includes(','):
|
||||
month.cronEvery = '3';
|
||||
month.specificSpecific = months.split(',').map(Number).sort();
|
||||
break;
|
||||
case months.includes('-'):
|
||||
month.cronEvery = '4';
|
||||
month.rangeStart = months.split('-')[0];
|
||||
month.rangeEnd = months.split('-')[1];
|
||||
break;
|
||||
default:
|
||||
month.cronEvery = '1';
|
||||
}
|
||||
this.result.month = month;
|
||||
},
|
||||
yearReverseExp(cron) {
|
||||
let years = cron.split(" ")[6];
|
||||
let year = {
|
||||
cronEvery:'',
|
||||
incrementStart:3,
|
||||
incrementIncrement:5,
|
||||
rangeStart:2019,
|
||||
rangeEnd:2019,
|
||||
specificSpecific:[],
|
||||
};
|
||||
switch (true){
|
||||
case years.includes('*'):
|
||||
year.cronEvery = '1';
|
||||
break;
|
||||
case years.includes('/'):
|
||||
year.cronEvery = '2';
|
||||
year.incrementStart = years.split('/')[0];
|
||||
year.incrementIncrement = years.split('/')[1];
|
||||
break;
|
||||
case years.includes(','):
|
||||
year.cronEvery = '3';
|
||||
year.specificSpecific = years.split(',').map(Number).sort();
|
||||
break;
|
||||
case years.includes('-'):
|
||||
year.cronEvery = '4';
|
||||
year.rangeStart = years.split('-')[0];
|
||||
year.rangeEnd = years.split('-')[1];
|
||||
break;
|
||||
default:
|
||||
year.cronEvery = '1';
|
||||
}
|
||||
this.result.year = year;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.card-container {
|
||||
background: #fff;
|
||||
overflow: hidden;
|
||||
padding: 12px;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
.ant-tabs{
|
||||
border:1px solid #e6ebf5;
|
||||
padding: 0;
|
||||
.ant-tabs-bar {
|
||||
margin: 0;
|
||||
outline: none;
|
||||
border-bottom: none;
|
||||
.ant-tabs-nav-container{
|
||||
margin: 0;
|
||||
.ant-tabs-tab {
|
||||
padding: 0 24px!important;
|
||||
background-color: #f5f7fa!important;
|
||||
margin-right: 0px!important;
|
||||
border-radius: 0;
|
||||
line-height: 38px;
|
||||
border: 1px solid transparent!important;
|
||||
border-bottom: 1px solid #e6ebf5!important;
|
||||
}
|
||||
.ant-tabs-tab-active.ant-tabs-tab{
|
||||
color: #409eff;
|
||||
background-color: #fff!important;
|
||||
border-right:1px solid #e6ebf5!important;
|
||||
border-left:1px solid #e6ebf5!important;
|
||||
border-bottom:1px solid #fff!important;
|
||||
font-weight: normal;
|
||||
transition:none!important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.ant-tabs-tabpane{
|
||||
padding: 15px;
|
||||
.ant-row{
|
||||
margin: 10px 0;
|
||||
}
|
||||
.ant-select,.ant-input-number{
|
||||
width: 100px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="less" scoped>
|
||||
.container-widthEn{
|
||||
width: 755px;
|
||||
}
|
||||
.container-widthCn{
|
||||
width: 608px;
|
||||
}
|
||||
.language{
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
right: 13px;
|
||||
top: 13px;
|
||||
border: 1px solid transparent;
|
||||
height: 40px;
|
||||
line-height: 38px;
|
||||
font-size: 16px;
|
||||
color: #409eff;
|
||||
z-index: 1;
|
||||
background: #f5f7fa;
|
||||
outline: none;
|
||||
width: 47px;
|
||||
border-bottom: 1px solid #e6ebf5;
|
||||
border-radius: 0;
|
||||
}
|
||||
.card-container{
|
||||
.bottom{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 10px 0 0 0;
|
||||
.cronButton{
|
||||
margin: 0 10px;
|
||||
line-height: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.tabBody{
|
||||
.a-row{
|
||||
margin: 10px 0;
|
||||
.long{
|
||||
.a-select{
|
||||
width:354px;
|
||||
}
|
||||
}
|
||||
.a-input-number{
|
||||
width: 110px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,334 @@
|
||||
<template>
|
||||
<a-modal
|
||||
centered
|
||||
:title="name + '选择'"
|
||||
:width="width"
|
||||
:visible="visible"
|
||||
@ok="handleOk"
|
||||
@cancel="close"
|
||||
cancelText="关闭">
|
||||
|
||||
<a-row :gutter="18">
|
||||
<a-col :span="16">
|
||||
<!-- 查询区域 -->
|
||||
<div class="table-page-search-wrapper">
|
||||
<a-form layout="inline">
|
||||
<a-row :gutter="24">
|
||||
|
||||
<a-col :span="14">
|
||||
<a-form-item :label="(queryParamText||name)">
|
||||
<a-input v-model="queryParam[queryParamCode||valueKey]" :placeholder="'请输入' + (queryParamText||name)" @pressEnter="searchQuery"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
|
||||
<a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
|
||||
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
|
||||
</span>
|
||||
</a-col>
|
||||
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
|
||||
<a-table
|
||||
size="small"
|
||||
bordered
|
||||
:rowKey="rowKey"
|
||||
:columns="innerColumns"
|
||||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:loading="loading"
|
||||
:scroll="{ y: 240 }"
|
||||
:rowSelection="{selectedRowKeys, onChange: onSelectChange, type: multiple ? 'checkbox':'radio'}"
|
||||
:customRow="customRowFn"
|
||||
@change="handleTableChange">
|
||||
</a-table>
|
||||
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-card :title="'已选' + name" :bordered="false" :head-style="{padding:0}" :body-style="{padding:0}">
|
||||
|
||||
<a-table size="small" :rowKey="rowKey" bordered v-bind="selectedTable">
|
||||
<span slot="action" slot-scope="text, record, index">
|
||||
<a @click="handleDeleteSelected(record, index)">删除</a>
|
||||
</span>
|
||||
</a-table>
|
||||
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getAction } from '@/api/manage'
|
||||
import Ellipsis from '@/components/Ellipsis'
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
import { cloneObject, pushIfNotExist } from '@/utils/util'
|
||||
|
||||
export default {
|
||||
name: 'JSelectBizComponentModal',
|
||||
mixins: [JeecgListMixin],
|
||||
components: { Ellipsis },
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
valueKey: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
width: {
|
||||
type: Number,
|
||||
default: 900
|
||||
},
|
||||
|
||||
name: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
listUrl: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: ''
|
||||
},
|
||||
// 根据 value 获取显示文本的地址,例如存的是 username,可以通过该地址获取到 realname
|
||||
valueUrl: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
displayKey: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
columns: {
|
||||
type: Array,
|
||||
required: true,
|
||||
default: () => []
|
||||
},
|
||||
// 查询条件Code
|
||||
queryParamCode: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
// 查询条件文字
|
||||
queryParamText: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
rowKey: {
|
||||
type: String,
|
||||
default: 'id'
|
||||
},
|
||||
// 过长裁剪长度,设置为 -1 代表不裁剪
|
||||
ellipsisLength: {
|
||||
type: Number,
|
||||
default: 12
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
innerValue: [],
|
||||
// 已选择列表
|
||||
selectedTable: {
|
||||
pagination: false,
|
||||
scroll: { y: 240 },
|
||||
columns: [
|
||||
{
|
||||
...this.columns[0],
|
||||
width: this.columns[0].widthRight || this.columns[0].width,
|
||||
},
|
||||
{ title: '操作', dataIndex: 'action', align: 'center', width: 60, scopedSlots: { customRender: 'action' }, }
|
||||
],
|
||||
dataSource: [],
|
||||
},
|
||||
renderEllipsis: (value) => (<ellipsis length={this.ellipsisLength}>{value}</ellipsis>),
|
||||
url: { list: this.listUrl },
|
||||
/* 分页参数 */
|
||||
ipagination: {
|
||||
current: 1,
|
||||
pageSize: 5,
|
||||
pageSizeOptions: ['5', '10', '20', '30'],
|
||||
showTotal: (total, range) => {
|
||||
return range[0] + '-' + range[1] + ' 共' + total + '条'
|
||||
},
|
||||
showQuickJumper: true,
|
||||
showSizeChanger: true,
|
||||
total: 0
|
||||
},
|
||||
options: [],
|
||||
dataSourceMap: {},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 表头
|
||||
innerColumns() {
|
||||
let columns = cloneObject(this.columns)
|
||||
columns.forEach(column => {
|
||||
// 给所有的列加上过长裁剪
|
||||
if (this.ellipsisLength !== -1) {
|
||||
column.customRender = (text) => this.renderEllipsis(text)
|
||||
}
|
||||
})
|
||||
return columns
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
deep: true,
|
||||
immediate: true,
|
||||
handler(val) {
|
||||
this.innerValue = cloneObject(val)
|
||||
this.selectedRowKeys = []
|
||||
this.valueWatchHandler(val)
|
||||
this.queryOptionsByValue(val)
|
||||
}
|
||||
},
|
||||
dataSource: {
|
||||
deep: true,
|
||||
handler(val) {
|
||||
this.emitOptions(val)
|
||||
this.valueWatchHandler(this.innerValue)
|
||||
}
|
||||
},
|
||||
selectedRowKeys: {
|
||||
immediate: true,
|
||||
deep: true,
|
||||
handler(val) {
|
||||
this.selectedTable.dataSource = val.map(key => {
|
||||
for (let data of this.dataSource) {
|
||||
if (data[this.rowKey] === key) {
|
||||
pushIfNotExist(this.innerValue, data[this.valueKey])
|
||||
return data
|
||||
}
|
||||
}
|
||||
for (let data of this.selectedTable.dataSource) {
|
||||
if (data[this.rowKey] === key) {
|
||||
pushIfNotExist(this.innerValue, data[this.valueKey])
|
||||
return data
|
||||
}
|
||||
}
|
||||
console.warn('未找到选择的行信息,key:' + key)
|
||||
return {}
|
||||
})
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
/** 关闭弹窗 */
|
||||
close() {
|
||||
this.$emit('update:visible', false)
|
||||
},
|
||||
|
||||
valueWatchHandler(val) {
|
||||
val.forEach(item => {
|
||||
this.dataSource.concat(this.selectedTable.dataSource).forEach(data => {
|
||||
if (data[this.valueKey] === item) {
|
||||
pushIfNotExist(this.selectedRowKeys, data[this.rowKey])
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
queryOptionsByValue(value) {
|
||||
if (!value || value.length === 0) {
|
||||
return
|
||||
}
|
||||
// 判断options是否存在value,如果已存在数据就不再请求后台了
|
||||
let notExist = false
|
||||
for (let val of value) {
|
||||
let find = false
|
||||
for (let option of this.options) {
|
||||
if (val === option.value) {
|
||||
find = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!find) {
|
||||
notExist = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!notExist) return
|
||||
getAction(this.valueUrl || this.listUrl, {
|
||||
// 这里最后加一个 , 的原因是因为无论如何都要使用 in 查询,防止后台进行了模糊匹配,导致查询结果不准确
|
||||
[this.valueKey]: value.join(',') + ',',
|
||||
pageNo: 1,
|
||||
pageSize: value.length
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
let dataSource = res.result
|
||||
if (!(dataSource instanceof Array)) {
|
||||
dataSource = res.result.records
|
||||
}
|
||||
this.emitOptions(dataSource, (data) => {
|
||||
pushIfNotExist(this.innerValue, data[this.valueKey])
|
||||
pushIfNotExist(this.selectedRowKeys, data[this.rowKey])
|
||||
pushIfNotExist(this.selectedTable.dataSource, data, this.rowKey)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
emitOptions(dataSource, callback) {
|
||||
dataSource.forEach(data => {
|
||||
let key = data[this.valueKey]
|
||||
this.dataSourceMap[key] = data
|
||||
pushIfNotExist(this.options, { label: data[this.displayKey || this.valueKey], value: key }, 'value')
|
||||
typeof callback === 'function' ? callback(data) : ''
|
||||
})
|
||||
this.$emit('options', this.options, this.dataSourceMap)
|
||||
},
|
||||
|
||||
/** 完成选择 */
|
||||
handleOk() {
|
||||
let value = this.selectedTable.dataSource.map(data => data[this.valueKey])
|
||||
this.$emit('input', value)
|
||||
this.close()
|
||||
},
|
||||
|
||||
/** 删除已选择的 */
|
||||
handleDeleteSelected(record, index) {
|
||||
this.selectedRowKeys.splice(this.selectedRowKeys.indexOf(record[this.rowKey]), 1)
|
||||
this.selectedTable.dataSource.splice(index, 1)
|
||||
},
|
||||
|
||||
customRowFn(record) {
|
||||
return {
|
||||
on: {
|
||||
click: () => {
|
||||
let key = record[this.rowKey]
|
||||
if (!this.multiple) {
|
||||
this.selectedRowKeys = [key]
|
||||
this.selectedTable.dataSource = [record]
|
||||
} else {
|
||||
let index = this.selectedRowKeys.indexOf(key)
|
||||
if (index === -1) {
|
||||
this.selectedRowKeys.push(key)
|
||||
this.selectedTable.dataSource.push(record)
|
||||
} else {
|
||||
this.handleDeleteSelected(record, index)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,36 @@
|
||||
# JSelectBizComponent
|
||||
|
||||
Jeecg 选择组件的公共可复用组件
|
||||
|
||||
## 引用方式
|
||||
|
||||
```js
|
||||
import JSelectBizComponent from '@/src/components/jeecgbiz/JSelectBizComponent'
|
||||
|
||||
export default {
|
||||
components: { JSelectBizComponent }
|
||||
}
|
||||
```
|
||||
|
||||
## 参数
|
||||
|
||||
### 配置参数
|
||||
|
||||
| 参数名 | 类型 | 必填 | 默认值 | 备注 |
|
||||
|-----------------------|---------|------|--------------|--------------------------------------------------------------------------------------|
|
||||
| rowKey | String | | "id" | 唯一标识的字段名 |
|
||||
| value(v-model) | String | | "" | 默认选择的数据,多个用半角逗号分割 |
|
||||
| name | String | | "" | 显示名字,例如选择用户就填写"用户" |
|
||||
| listUrl | String | 是 | | 数据请求地址,必须是封装了分页的地址 |
|
||||
| valueUrl | String | | "" | 获取显示文本的地址,例如存的是 username,可以通过该地址获取到 realname |
|
||||
| displayKey | String | | null | 显示在标签上的字段 key ,不传则直接显示数据 |
|
||||
| returnKeys | Array | | ['id', 'id'] | v-model 绑定的 keys,是个数组,默认使用第二项,当配置了 `returnId=true` 就返回第一项 |
|
||||
| returnId | Boolean | | false | 返回ID,设为true后将返回配置的 `returnKeys` 中的第一项 |
|
||||
| selectButtonText | String | | "选择" | 选择按钮的文字 |
|
||||
| queryParamText | String | | null | 查询条件显示文字,不传则使用 `name` |
|
||||
| columns | Array | 是 | | 列配置项,与antd的table的配置完全一致。列的第一项会被配置成右侧已选择的列表上 |
|
||||
| columns[0].widthRight | String | | null | 仅列的第一项可以应用此配置,表示右侧已选择列表的宽度,建议 `70%`,不传则应用`width` |
|
||||
| placeholder | String | | "请选择" | 占位符 |
|
||||
| disabled | Boolean | | false | 是否禁用 |
|
||||
| multiple | Boolean | | false | 是否可多选 |
|
||||
| buttons | Boolean | | true | 是否显示"选择"按钮,如果不显示,可以直接点击文本框打开选择界面 |
|
||||
@@ -0,0 +1,165 @@
|
||||
<template>
|
||||
<a-row class="j-select-biz-component-box" type="flex" :gutter="8">
|
||||
<a-col class="left" :class="{'full': !buttons}">
|
||||
<slot name="left">
|
||||
<a-select
|
||||
mode="multiple"
|
||||
:placeholder="placeholder"
|
||||
v-model="selectValue"
|
||||
:options="selectOptions"
|
||||
allowClear
|
||||
:disabled="disabled"
|
||||
:open="selectOpen"
|
||||
style="width: 100%;"
|
||||
@dropdownVisibleChange="handleDropdownVisibleChange"
|
||||
@click.native="visible=(buttons?visible:true)"
|
||||
/>
|
||||
</slot>
|
||||
</a-col>
|
||||
|
||||
<a-col v-if="buttons" class="right">
|
||||
<a-button type="primary" icon="search" :disabled="disabled" @click="visible=true">{{selectButtonText}}</a-button>
|
||||
</a-col>
|
||||
|
||||
<j-select-biz-component-modal
|
||||
v-model="selectValue"
|
||||
:visible.sync="visible"
|
||||
v-bind="modalProps"
|
||||
@options="handleOptions"
|
||||
/>
|
||||
</a-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JSelectBizComponentModal from './JSelectBizComponentModal'
|
||||
|
||||
export default {
|
||||
name: 'JSelectBizComponent',
|
||||
components: { JSelectBizComponentModal },
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
/** 是否返回 id,默认 false,返回 code */
|
||||
returnId: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请选择'
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 是否支持多选,默认 true
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 是否显示按钮,默认 true
|
||||
buttons: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 显示的 Key
|
||||
displayKey: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
// 返回的 key
|
||||
returnKeys: {
|
||||
type: Array,
|
||||
default: () => ['id', 'id']
|
||||
},
|
||||
// 选择按钮文字
|
||||
selectButtonText: {
|
||||
type: String,
|
||||
default: '选择'
|
||||
},
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectValue: [],
|
||||
selectOptions: [],
|
||||
dataSourceMap: {},
|
||||
visible: false,
|
||||
selectOpen: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
valueKey() {
|
||||
return this.returnId ? this.returnKeys[0] : this.returnKeys[1]
|
||||
},
|
||||
modalProps() {
|
||||
return Object.assign({
|
||||
valueKey: this.valueKey,
|
||||
multiple: this.multiple,
|
||||
returnKeys: this.returnKeys,
|
||||
displayKey: this.displayKey || this.valueKey
|
||||
}, this.$attrs)
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
immediate: true,
|
||||
handler(val) {
|
||||
if (val) {
|
||||
this.selectValue = val.split(',')
|
||||
} else {
|
||||
this.selectValue = []
|
||||
}
|
||||
}
|
||||
},
|
||||
selectValue: {
|
||||
deep: true,
|
||||
handler(val) {
|
||||
let rows = val.map(key => this.dataSourceMap[key])
|
||||
this.$emit('select', rows)
|
||||
let data = val.join(',')
|
||||
this.$emit('input', data)
|
||||
this.$emit('change', data)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleOptions(options, dataSourceMap) {
|
||||
this.selectOptions = options
|
||||
this.dataSourceMap = dataSourceMap
|
||||
},
|
||||
handleDropdownVisibleChange() {
|
||||
// 解决antdv自己的bug —— open 设置为 false 了,点击后还是添加了 open 样式,导致点击事件失效
|
||||
this.selectOpen = true
|
||||
this.$nextTick(() => {
|
||||
this.selectOpen = false
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.j-select-biz-component-box {
|
||||
|
||||
@width: 82px;
|
||||
|
||||
.left {
|
||||
width: calc(100% - @width - 8px);
|
||||
}
|
||||
|
||||
.right {
|
||||
width: @width;
|
||||
}
|
||||
|
||||
.full {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/deep/ .ant-select-search__field {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<div class="components-input-demo-presuffix">
|
||||
<!---->
|
||||
<a-input @click="openModal" placeholder="请点击选择部门" v-model="departNames" readOnly :disabled="disabled">
|
||||
<a-icon slot="prefix" type="cluster" title="部门选择控件"/>
|
||||
<a-icon v-if="departIds" slot="suffix" type="close-circle" @click="handleEmpty" title="清空"/>
|
||||
</a-input>
|
||||
|
||||
<j-select-depart-modal
|
||||
ref="innerDepartSelectModal"
|
||||
:modal-width="modalWidth"
|
||||
:multi="multi"
|
||||
:rootOpened="rootOpened"
|
||||
:depart-id="departIds"
|
||||
@ok="handleOK"
|
||||
@initComp="initComp"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JSelectDepartModal from './modal/JSelectDepartModal'
|
||||
export default {
|
||||
name: 'JSelectDepart',
|
||||
components:{
|
||||
JSelectDepartModal
|
||||
},
|
||||
props:{
|
||||
modalWidth:{
|
||||
type:Number,
|
||||
default:500,
|
||||
required:false
|
||||
},
|
||||
multi:{
|
||||
type:Boolean,
|
||||
default:false,
|
||||
required:false
|
||||
},
|
||||
rootOpened:{
|
||||
type:Boolean,
|
||||
default:true,
|
||||
required:false
|
||||
},
|
||||
value:{
|
||||
type:String,
|
||||
required:false
|
||||
},
|
||||
disabled:{
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
// 自定义返回字段,默认返回 id
|
||||
customReturnField: {
|
||||
type: String,
|
||||
default: 'id'
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
visible:false,
|
||||
confirmLoading:false,
|
||||
departNames:"",
|
||||
departIds:''
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
this.departIds = this.value
|
||||
},
|
||||
watch:{
|
||||
value(val){
|
||||
if (this.customReturnField === 'id') {
|
||||
this.departIds = val
|
||||
}
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
initComp(departNames){
|
||||
this.departNames = departNames
|
||||
},
|
||||
openModal(){
|
||||
this.$refs.innerDepartSelectModal.show()
|
||||
},
|
||||
handleOK(rows, idstr) {
|
||||
let value = ''
|
||||
if (!rows && rows.length <= 0) {
|
||||
this.departNames = ''
|
||||
this.departIds = ''
|
||||
} else {
|
||||
value = rows.map(row => row[this.customReturnField]).join(',')
|
||||
this.departNames = rows.map(row => row['departName']).join(',')
|
||||
this.departIds = idstr
|
||||
}
|
||||
this.$emit("change", value)
|
||||
},
|
||||
getDepartNames(){
|
||||
return this.departNames
|
||||
},
|
||||
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>
|
||||
@@ -0,0 +1,327 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- <a-input-search v-if="kind === 'material'" v-model="names" placeholder="请选择" @search="onSearch"></a-input-search> -->
|
||||
<a-select
|
||||
:value="value"
|
||||
v-if="kind === 'material'"
|
||||
placeholder="编码 名称"
|
||||
show-search
|
||||
style="width: 100px"
|
||||
dropdownClassName="drop-down-Style"
|
||||
option-label-prop="value"
|
||||
:dropdownMatchSelectWidth="false"
|
||||
:default-active-first-option="false"
|
||||
:show-arrow="false"
|
||||
:filter-option="false"
|
||||
:not-found-content="fetching ? undefined : null"
|
||||
@search="fetchUser"
|
||||
@change="handleChange"
|
||||
@focus="loadData()"
|
||||
>
|
||||
<div slot="notFoundContent">
|
||||
<a-spin v-if="fetching" size="small" />
|
||||
</div>
|
||||
<div slot="dropdownRender" slot-scope="menu">
|
||||
<v-nodes :vnodes="menu" />
|
||||
<a-divider style="margin: 4px 0" />
|
||||
<div
|
||||
@mousedown="(e) => e.preventDefault()"
|
||||
style="display: flex; justify-content: space-between; margin: 0 5px"
|
||||
>
|
||||
<a-pagination
|
||||
:default-current="6"
|
||||
:current.sync="queryParam.current"
|
||||
:pageSize.sync="queryParam.pageSize"
|
||||
@change="changeCurrent"
|
||||
:total="queryParam.total"
|
||||
style="margin-bottom: 4px"
|
||||
/>
|
||||
<a-button type="primary" @click="confirmSelected">确定</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<a-select-opt-group v-if="materailList.length">
|
||||
<span slot="label">
|
||||
<div class="select-option">
|
||||
<a-checkbox style="margin-right:5px" :indeterminate="indeterminate" :checked="checkAll" @change="onCheckAllChange">
|
||||
</a-checkbox>
|
||||
<span class="mr10" style="width: 100px; font-size: 16px">物料编码</span>
|
||||
<span class="mr10" style="width: 400px; font-size: 16px;">名称</span>
|
||||
<span class="mr10" style="width: 100px; font-size: 16px">类别</span>
|
||||
<span class="mr10" style="width: 100px; font-size: 16px">单位</span>
|
||||
<span class="mr10" style="width: 100px; font-size: 16px">多属性</span>
|
||||
<span class="mr10" style="width: 100px; font-size: 16px">库存</span>
|
||||
<span class="mr10" style="width: 100px; font-size: 16px">扩展信息</span>
|
||||
</div>
|
||||
</span>
|
||||
|
||||
<a-select-option
|
||||
style="width: 400px"
|
||||
:value="item.mBarCode"
|
||||
v-for="(item, index) in materailList"
|
||||
:key="item.id"
|
||||
>
|
||||
<div class="select-option">
|
||||
<div style="margin-left: -8px;">
|
||||
<a-checkbox
|
||||
style="margin-right:5px"
|
||||
:id="item.mBarCode"
|
||||
:key="index"
|
||||
:checked="checkedList.indexOf(item.mBarCode) !== -1"
|
||||
@change="(e) => onchange(e, item)"
|
||||
@click.stop.native="() => {}"
|
||||
>
|
||||
</a-checkbox>
|
||||
</div>
|
||||
<span class="mr10" style="width: 100px">{{ item.mBarCode }}</span>
|
||||
<span class="mr10" style="width: 400px;width-space:nowrap;text-overflow:ellipsis;overflow: hidden;white-space:nowrap;">{{ item.name }}</span>
|
||||
<span class="mr10" style="width: 100px">{{ item.categoryName }}</span>
|
||||
<span class="mr10" style="width: 100px">{{ item.unit }}</span>
|
||||
<span class="mr10" style="width: 100px">{{ item.sku }}</span>
|
||||
<span class="mr10" style="width: 100px">{{ item.stock }}</span>
|
||||
<span class="mr10" style="width: 100px">{{ item.expand }}</span>
|
||||
</div>
|
||||
</a-select-option>
|
||||
</a-select-opt-group>
|
||||
</a-select>
|
||||
<a-input-search
|
||||
v-if="kind === 'batch' || kind === 'sn'"
|
||||
v-model="names"
|
||||
placeholder="请选择"
|
||||
readOnly
|
||||
@search="onSearch"
|
||||
></a-input-search>
|
||||
<j-select-material-modal
|
||||
v-if="kind === 'material'"
|
||||
ref="selectModal"
|
||||
:modal-width="modalWidth"
|
||||
:rows="rows"
|
||||
:multi="multi"
|
||||
:bar-code="value"
|
||||
@ok="selectOK"
|
||||
@initComp="initComp"
|
||||
/>
|
||||
<j-select-batch-modal
|
||||
v-if="kind === 'batch'"
|
||||
ref="selectModal"
|
||||
:modal-width="modalWidth"
|
||||
:rows="rows"
|
||||
:multi="multi"
|
||||
:bar-code="value"
|
||||
@ok="selectOK"
|
||||
@initComp="initComp"
|
||||
/>
|
||||
<j-select-sn-modal
|
||||
v-if="kind === 'sn'"
|
||||
ref="selectModal"
|
||||
:modal-width="modalWidth"
|
||||
:rows="rows"
|
||||
:multi="multi"
|
||||
:bar-code="value"
|
||||
@ok="selectOK"
|
||||
@initComp="initComp"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JSelectMaterialModal from './modal/JSelectMaterialModal'
|
||||
import JSelectBatchModal from './modal/JSelectBatchModal'
|
||||
import JSelectSnModal from './modal/JSelectSnModal'
|
||||
import { filterObj, getMpListShort } from '@/utils/util'
|
||||
import { getMaterialByBarCode, getMaterialBySelect } from '@/api/api'
|
||||
import Vue from 'vue'
|
||||
|
||||
export default {
|
||||
name: 'JSelectList',
|
||||
components: {
|
||||
JSelectMaterialModal,
|
||||
JSelectBatchModal,
|
||||
JSelectSnModal,
|
||||
VNodes: {
|
||||
functional: true,
|
||||
render: (h, ctx) => ctx.props.vnodes,
|
||||
},
|
||||
},
|
||||
props: {
|
||||
modalWidth: {
|
||||
type: Number,
|
||||
default: 1300,
|
||||
required: false,
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
required: false,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
rows: {
|
||||
type: String,
|
||||
required: false,
|
||||
},
|
||||
kind: {
|
||||
type: String,
|
||||
required: false,
|
||||
},
|
||||
multi: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ids: '',
|
||||
names: '',
|
||||
materailList: [],
|
||||
fetching: false,
|
||||
queryParam: {
|
||||
q: '',
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
},
|
||||
checkedList: [],
|
||||
checkAll: false,
|
||||
indeterminate: false,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.ids = this.value
|
||||
// this.loadData()
|
||||
},
|
||||
watch: {
|
||||
value(val) {
|
||||
this.ids = val
|
||||
},
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change',
|
||||
},
|
||||
methods: {
|
||||
onCheckAllChange(e) {
|
||||
Object.assign(this, {
|
||||
checkedList: e.target.checked ? this.materailList.map((item) => item.mBarCode) : [],
|
||||
indeterminate: false,
|
||||
checkAll: e.target.checked,
|
||||
})
|
||||
},
|
||||
onchange(event, item) {
|
||||
let index = this.checkedList.indexOf(item.mBarCode)
|
||||
if (index !== -1) {
|
||||
this.checkedList.splice(index, 1)
|
||||
} else {
|
||||
this.checkedList.push(item.mBarCode)
|
||||
}
|
||||
this.indeterminate = !!this.checkedList.length && this.checkedList.length < this.materailList.length
|
||||
this.checkAll = this.checkedList.length === this.materailList.length
|
||||
},
|
||||
confirmSelected() {
|
||||
let ids = this.checkedList.join(',')
|
||||
this.$emit('change', ids)
|
||||
this.open = false
|
||||
this.loadData()
|
||||
},
|
||||
changeCurrent(current) {
|
||||
this.queryParam.current = current
|
||||
this.loadData()
|
||||
},
|
||||
fetchUser(value) {
|
||||
clearTimeout(this.timeout)
|
||||
this.timeout = setTimeout(() => {
|
||||
this.queryParam.q = value
|
||||
this.loadData(1)
|
||||
}, 800)
|
||||
},
|
||||
getQueryParams() {
|
||||
let param = {}
|
||||
param.mpList = getMpListShort(Vue.ls.get('materialPropertyList')) //扩展属性
|
||||
param.page = this.queryParam.current
|
||||
param.rows = this.queryParam.pageSize
|
||||
param.q = this.queryParam.q
|
||||
return filterObj(param)
|
||||
},
|
||||
async loadData(arg) {
|
||||
if (arg === 1) {
|
||||
this.queryParam.current = 1
|
||||
}
|
||||
this.fetching = true
|
||||
let params = this.getQueryParams() //查询条件
|
||||
await getMaterialBySelect(params)
|
||||
.then((res) => {
|
||||
if (res) {
|
||||
this.checkedList = []
|
||||
this.materailList = res.rows
|
||||
this.queryParam.total = res.total || 0
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.fetching = false
|
||||
})
|
||||
},
|
||||
initComp(name) {
|
||||
this.names = name
|
||||
},
|
||||
onSearch() {
|
||||
if (this.kind === 'material') {
|
||||
let param = {
|
||||
barCode: this.names,
|
||||
mpList: getMpListShort(Vue.ls.get('materialPropertyList')), //扩展属性
|
||||
prefixNo: this.prefixNo,
|
||||
}
|
||||
getMaterialByBarCode(param).then((res) => {
|
||||
if (res && res.code === 200) {
|
||||
let mList = res.data
|
||||
if (mList && mList.length === 1) {
|
||||
//如果条码可以查到商品,则直接加载,不用弹窗再选择
|
||||
this.$emit('change', this.names)
|
||||
} else {
|
||||
this.$refs.selectModal.showModal(this.names)
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$refs.selectModal.showModal()
|
||||
}
|
||||
},
|
||||
selectOK(rows, idstr) {
|
||||
console.log('选中id', idstr)
|
||||
if (!rows) {
|
||||
this.ids = ''
|
||||
} else {
|
||||
this.names = idstr
|
||||
this.ids = idstr
|
||||
}
|
||||
this.$emit('change', this.ids)
|
||||
},
|
||||
handleChange(value) {
|
||||
this.names = value
|
||||
this.$emit('change', value)
|
||||
},
|
||||
focus() {
|
||||
if (this.names) {
|
||||
this.queryParam.q = ''
|
||||
this.loadData()
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
/deep/ .drop-down-Style {
|
||||
width: auto;
|
||||
}
|
||||
.select-option {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding-top: 5px;
|
||||
width: 1000px;
|
||||
}
|
||||
.mr10 {
|
||||
margin-right: 10px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,87 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-input-search
|
||||
v-model="materialNames"
|
||||
placeholder="请选择商品"
|
||||
readOnly
|
||||
@search="onSearchMaterial">
|
||||
</a-input-search>
|
||||
<j-select-material-modal ref="selectModal" :modal-width="modalWidth" :multi="multi" :bar-code="value" @ok="selectOK" @initComp="initComp"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JSelectMaterialModal from './modal/JSelectMaterialModal'
|
||||
|
||||
export default {
|
||||
name: 'JSelectMaterial',
|
||||
components: {JSelectMaterialModal},
|
||||
props: {
|
||||
modalWidth: {
|
||||
type: Number,
|
||||
default: 1300,
|
||||
required: false
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
multi: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
required: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
materialIds: "",
|
||||
materialNames: "",
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.materialIds = this.value
|
||||
},
|
||||
watch: {
|
||||
value(val) {
|
||||
this.materialIds = val
|
||||
}
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
},
|
||||
methods: {
|
||||
initComp(barCode) {
|
||||
this.materialNames = barCode
|
||||
},
|
||||
onSearchMaterial() {
|
||||
this.$refs.selectModal.showModal()
|
||||
},
|
||||
selectOK(rows, idstr) {
|
||||
console.log("选中商品", rows)
|
||||
console.log("选中商品id", idstr)
|
||||
if (!rows) {
|
||||
this.materialNames = ''
|
||||
this.materialIds = ''
|
||||
} else {
|
||||
let temp = ''
|
||||
for (let item of rows) {
|
||||
temp += ',' + item.mBarCode
|
||||
}
|
||||
this.materialNames = temp.substring(1)
|
||||
this.materialIds = idstr
|
||||
}
|
||||
this.$emit("change", this.materialIds)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<!-- 定义在这里的参数都是不可在外部覆盖的,防止出现问题 -->
|
||||
<j-select-biz-component
|
||||
:value="value"
|
||||
:ellipsisLength="25"
|
||||
:listUrl="url.list"
|
||||
:columns="columns"
|
||||
v-on="$listeners"
|
||||
v-bind="attrs"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JSelectBizComponent from './JSelectBizComponent'
|
||||
|
||||
export default {
|
||||
name: 'JSelectMultiUser',
|
||||
components: { JSelectBizComponent },
|
||||
props: ['value'],
|
||||
data() {
|
||||
return {
|
||||
url: { list: '/sys/user/list' },
|
||||
columns: [
|
||||
{ title: '姓名', align: 'center', width: '25%', widthRight: '70%', dataIndex: 'realname' },
|
||||
{ title: '账号', align: 'center', width: '25%', dataIndex: 'username' },
|
||||
{ title: '电话', align: 'center', width: '20%', dataIndex: 'phone' },
|
||||
{ title: '出生日期', align: 'center', width: '20%', dataIndex: 'birthday' }
|
||||
],
|
||||
// 定义在这里的参数都是可以在外部传递覆盖的,可以更灵活的定制化使用的组件
|
||||
default: {
|
||||
name: '用户',
|
||||
width: 1200,
|
||||
displayKey: 'realname',
|
||||
returnKeys: ['id', 'username'],
|
||||
queryParamText: '账号',
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
attrs() {
|
||||
return Object.assign(this.default, this.$attrs)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
@@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<j-select-biz-component :width="1000" v-bind="configs" v-on="$listeners"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JSelectBizComponent from './JSelectBizComponent'
|
||||
|
||||
export default {
|
||||
name: 'JSelectPosition',
|
||||
components: { JSelectBizComponent },
|
||||
props: ['value'],
|
||||
data() {
|
||||
return {
|
||||
settings: {
|
||||
name: '职务',
|
||||
displayKey: 'name',
|
||||
returnKeys: ['id', 'code'],
|
||||
listUrl: '/sys/position/list',
|
||||
queryParamCode: 'name',
|
||||
queryParamText: '职务名称',
|
||||
columns: [
|
||||
{ title: '职务名称', dataIndex: 'name', align: 'center', width: '30%', widthRight: '70%' },
|
||||
{ title: '职务编码', dataIndex: 'code', align: 'center', width: '35%' },
|
||||
{ title: '职级', dataIndex: 'rank_dictText', align: 'center', width: '25%' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
configs() {
|
||||
return Object.assign({ value: this.value }, this.settings, this.$attrs)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<j-select-biz-component
|
||||
:value="value"
|
||||
|
||||
name="角色"
|
||||
displayKey="roleName"
|
||||
|
||||
:returnKeys="returnKeys"
|
||||
:listUrl="url.list"
|
||||
:columns="columns"
|
||||
queryParamText="角色编码"
|
||||
|
||||
v-on="$listeners"
|
||||
v-bind="$attrs"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JSelectBizComponent from './JSelectBizComponent'
|
||||
|
||||
export default {
|
||||
name: 'JSelectMultiUser',
|
||||
components: { JSelectBizComponent },
|
||||
props: ['value'],
|
||||
data() {
|
||||
return {
|
||||
returnKeys: ['id', 'roleCode'],
|
||||
url: { list: '/sys/role/list' },
|
||||
columns: [
|
||||
{ title: '角色名称', dataIndex: 'roleName', align: 'center', width: 120 },
|
||||
{ title: '角色编码', dataIndex: 'roleCode', align: 'center', width: 120 }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
@@ -0,0 +1,87 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-input-search
|
||||
v-model="materialNames"
|
||||
placeholder="请选择序列号商品"
|
||||
readOnly
|
||||
@search="onSearchMaterial">
|
||||
</a-input-search>
|
||||
<j-select-serial-material-modal ref="selectModal" :modal-width="modalWidth" :multi="multi" :bar-code="value" @ok="selectOK" @initComp="initComp"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JSelectSerialMaterialModal from './modal/JSelectSerialMaterialModal'
|
||||
|
||||
export default {
|
||||
name: 'JSelectSerialMaterial',
|
||||
components: {JSelectSerialMaterialModal},
|
||||
props: {
|
||||
modalWidth: {
|
||||
type: Number,
|
||||
default: 1100,
|
||||
required: false
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
multi: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
required: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
materialIds: "",
|
||||
materialNames: "",
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.materialIds = this.value
|
||||
},
|
||||
watch: {
|
||||
value(val) {
|
||||
this.materialIds = val
|
||||
}
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
},
|
||||
methods: {
|
||||
initComp(barCode) {
|
||||
this.materialNames = barCode
|
||||
},
|
||||
onSearchMaterial() {
|
||||
this.$refs.selectModal.showModal()
|
||||
},
|
||||
selectOK(rows, idstr) {
|
||||
console.log("选中序列号商品", rows)
|
||||
console.log("选中序列号商品id", idstr)
|
||||
if (!rows) {
|
||||
this.materialNames = ''
|
||||
this.materialIds = ''
|
||||
} else {
|
||||
let temp = ''
|
||||
for (let item of rows) {
|
||||
temp += ',' + item.mBarCode
|
||||
}
|
||||
this.materialNames = temp.substring(1)
|
||||
this.materialIds = idstr
|
||||
}
|
||||
this.$emit("change", this.materialIds)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-input-search
|
||||
v-model="userNames"
|
||||
placeholder="请先选择用户"
|
||||
readOnly
|
||||
unselectable="on"
|
||||
@search="onSearchDepUser">
|
||||
<a-button slot="enterButton" :disabled="disabled">选择用户</a-button>
|
||||
</a-input-search>
|
||||
<j-select-user-by-dep-modal ref="selectModal" :modal-width="modalWidth" :multi="multi" @ok="selectOK" :user-ids="value" @initComp="initComp"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JSelectUserByDepModal from './modal/JSelectUserByDepModal'
|
||||
|
||||
export default {
|
||||
name: 'JSelectUserByDep',
|
||||
components: {JSelectUserByDepModal},
|
||||
props: {
|
||||
modalWidth: {
|
||||
type: Number,
|
||||
default: 1250,
|
||||
required: false
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
multi: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
required: false
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
userIds: "",
|
||||
userNames: ""
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.userIds = this.value
|
||||
},
|
||||
watch: {
|
||||
value(val) {
|
||||
this.userIds = val
|
||||
}
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
},
|
||||
methods: {
|
||||
initComp(userNames) {
|
||||
this.userNames = userNames
|
||||
},
|
||||
onSearchDepUser() {
|
||||
this.$refs.selectModal.showModal()
|
||||
},
|
||||
selectOK(rows, idstr) {
|
||||
console.log("当前选中用户", rows)
|
||||
console.log("当前选中用户ID", idstr)
|
||||
if (!rows) {
|
||||
this.userNames = ''
|
||||
this.userIds = ''
|
||||
} else {
|
||||
let temp = ''
|
||||
for (let item of rows) {
|
||||
temp += ',' + item.realname
|
||||
}
|
||||
this.userNames = temp.substring(1)
|
||||
this.userIds = idstr
|
||||
}
|
||||
this.$emit("change", this.userIds)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,137 @@
|
||||
# JSelectDepart 部门选择组件
|
||||
选择部门组件,存储部门ID,显示部门名称
|
||||
|
||||
## 参数配置
|
||||
| 参数 | 类型 | 必填 |说明|
|
||||
|--------------|---------|----|---------|
|
||||
| modalWidth |Number | | 弹框宽度 默认500 |
|
||||
| multi |Boolean | | 是否多选 默认false |
|
||||
| rootOpened |Boolean | | 是否展开根节点 默认true |
|
||||
| disabled |Boolean | | 是否禁用 默认false|
|
||||
|
||||
使用示例
|
||||
----
|
||||
```vue
|
||||
<template>
|
||||
<a-form :form="form">
|
||||
<a-form-item label="部门选择v-decorator" style="width: 300px">
|
||||
<j-select-depart v-decorator="['bumen']"/>
|
||||
{{ getFormFieldValue('bumen') }}
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="部门选择v-model" style="width: 300px">
|
||||
<j-select-depart v-model="bumen"/>
|
||||
{{ bumen }}
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="部门多选v-model" style="width: 300px">
|
||||
<j-select-depart v-model="bumens" :multi="true"/>
|
||||
{{ bumens }}
|
||||
</a-form-item>
|
||||
|
||||
</a-form >
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JSelectDepart from '@/components/jeecgbiz/JSelectDepart'
|
||||
export default {
|
||||
components: {JSelectDepart},
|
||||
data() {
|
||||
return {
|
||||
form: this.$form.createForm(this),
|
||||
bumen:"",
|
||||
bumens:""
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
getFormFieldValue(field){
|
||||
return this.form.getFieldValue(field)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
# JSelectMultiUser 用户多选组件
|
||||
|
||||
使用示例
|
||||
----
|
||||
```vue
|
||||
<template>
|
||||
<a-form :form="form">
|
||||
<a-form-item label="用户选择v-decorator" style="width: 500px">
|
||||
<j-select-multi-user v-decorator="['users']"/>
|
||||
{{ getFormFieldValue('users') }}
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="用户选择v-model" style="width: 500px">
|
||||
<j-select-multi-user v-model="users" ></j-select-multi-user>
|
||||
{{ users }}
|
||||
</a-form-item>
|
||||
|
||||
</a-form >
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JSelectMultiUser from '@/components/jeecgbiz/JSelectMultiUser'
|
||||
export default {
|
||||
components: {JSelectMultiUser},
|
||||
data() {
|
||||
return {
|
||||
form: this.$form.createForm(this),
|
||||
users:"",
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
getFormFieldValue(field){
|
||||
return this.form.getFieldValue(field)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
# JSelectUserByDep 根据部门选择用户
|
||||
|
||||
## 参数配置
|
||||
| 参数 | 类型 | 必填 |说明|
|
||||
|--------------|---------|----|---------|
|
||||
| modalWidth |Number | | 弹框宽度 默认1250 |
|
||||
| disabled |Boolean | | 是否禁用 |
|
||||
|
||||
使用示例
|
||||
----
|
||||
```vue
|
||||
<template>
|
||||
<a-form :form="form">
|
||||
<a-form-item label="用户选择v-decorator" style="width: 500px">
|
||||
<j-select-user-by-dep v-decorator="['users']"/>
|
||||
{{ getFormFieldValue('users') }}
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="用户选择v-model" style="width: 500px">
|
||||
<j-select-user-by-dep v-model="users" ></j-select-user-by-dep>
|
||||
{{ users }}
|
||||
</a-form-item>
|
||||
|
||||
</a-form >
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JSelectUserByDep from '@/components/jeecgbiz/JSelectUserByDep'
|
||||
export default {
|
||||
components: {JSelectUserByDep},
|
||||
data() {
|
||||
return {
|
||||
form: this.$form.createForm(this),
|
||||
users:"",
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
getFormFieldValue(field){
|
||||
return this.form.getFieldValue(field)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
<template>
|
||||
<a-modal
|
||||
:width="modalWidth"
|
||||
:visible="visible"
|
||||
:title="title"
|
||||
@ok="handleSubmit"
|
||||
@cancel="close"
|
||||
cancelText="关闭"
|
||||
style="top:5%;height: 100%;overflow-y: hidden"
|
||||
wrapClassName="ant-modal-cust-warp"
|
||||
>
|
||||
<a-row :gutter="10" style="padding: 10px; margin: -10px">
|
||||
<a-col :md="24" :sm="24">
|
||||
<!-- 查询区域 -->
|
||||
<div class="table-page-search-wrapper">
|
||||
<!-- 搜索区域 -->
|
||||
<a-form layout="inline" @keyup.enter.native="onSearch">
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="6" :sm="8">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="批号">
|
||||
<a-input placeholder="请输入批号" v-model="queryParam.name"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-button type="primary" @click="onSearch">查询</a-button>
|
||||
<a-button style="margin-left: 8px" @click="searchReset(1)">重置</a-button>
|
||||
</a-col>
|
||||
</span>
|
||||
</a-row>
|
||||
</a-form>
|
||||
<a-table
|
||||
ref="table"
|
||||
:scroll="scrollTrigger"
|
||||
size="middle"
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:dataSource="dataSource"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange,type: getType}"
|
||||
:loading="loading"
|
||||
:customRow="rowAction">
|
||||
</a-table>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getAction } from '@/api/manage'
|
||||
import {getBatchNumberList} from '@/api/api'
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
|
||||
export default {
|
||||
name: 'JSelectBatchModal',
|
||||
mixins:[JeecgListMixin],
|
||||
components: {},
|
||||
props: ['modalWidth', 'rows', 'multi', 'barCode'],
|
||||
data() {
|
||||
return {
|
||||
queryParam: {
|
||||
name: "",
|
||||
depotId: '',
|
||||
barCode: ''
|
||||
},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 5 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
categoryTree:[],
|
||||
columns: [
|
||||
{dataIndex: 'batchNumber', title: '批号', width: 100, align: 'left'},
|
||||
{dataIndex: 'barCode', title: '物料编码', width: 100},
|
||||
{dataIndex: 'name', title: '名称', width: 100},
|
||||
{dataIndex: 'standard', title: '规格', width: 80},
|
||||
{dataIndex: 'model', title: '型号', width: 80},
|
||||
{dataIndex: 'expirationDateStr', title: '有效期至', width: 80},
|
||||
{dataIndex: 'totalNum', title: '库存', width: 80}
|
||||
],
|
||||
scrollTrigger: {},
|
||||
dataSource: [],
|
||||
selectedRowKeys: [],
|
||||
selectRows: [],
|
||||
selectIds: [],
|
||||
title: '选择批号',
|
||||
isorter: {
|
||||
column: 'createTime',
|
||||
order: 'desc'
|
||||
},
|
||||
departTree: [],
|
||||
depotList: [],
|
||||
visible: false,
|
||||
form: this.$form.createForm(this),
|
||||
loading: false,
|
||||
expandedKeys: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 计算属性的 getter
|
||||
getType: function () {
|
||||
return this.multi == true ? 'checkbox' : 'radio';
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
barCode: {
|
||||
immediate: true,
|
||||
handler() {
|
||||
this.initBarCode()
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.loadData()
|
||||
},
|
||||
methods: {
|
||||
initBarCode() {
|
||||
if (this.barCode) {
|
||||
this.$emit('initComp', this.barCode)
|
||||
} else {
|
||||
// JSelectUserByDep组件bug issues/I16634
|
||||
this.$emit('initComp', '')
|
||||
}
|
||||
},
|
||||
async loadData(arg) {
|
||||
if(this.rows) {
|
||||
if(JSON.parse(this.rows).depotId && JSON.parse(this.rows).barCode ){
|
||||
this.queryParam.depotId = JSON.parse(this.rows).depotId-0
|
||||
this.queryParam.barCode = JSON.parse(this.rows).barCode
|
||||
}
|
||||
}
|
||||
if (arg === 1) {
|
||||
this.ipagination.current = 1;
|
||||
}
|
||||
this.loading = true
|
||||
let params = this.getQueryParams()//查询条件
|
||||
await getBatchNumberList(params).then((res) => {
|
||||
if (res && res.code === 200) {
|
||||
this.dataSource = res.data.rows
|
||||
this.ipagination.total = res.data.total
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
showModal() {
|
||||
this.visible = true;
|
||||
this.loadData();
|
||||
this.form.resetFields();
|
||||
},
|
||||
getQueryParams() {
|
||||
let param = Object.assign({}, this.queryParam, this.isorter);
|
||||
return param;
|
||||
},
|
||||
getQueryField() {
|
||||
let str = 'id,';
|
||||
for (let a = 0; a < this.columns.length; a++) {
|
||||
str += ',' + this.columns[a].dataIndex;
|
||||
}
|
||||
return str;
|
||||
},
|
||||
searchReset(num) {
|
||||
let that = this;
|
||||
if (num !== 0) {
|
||||
if(this.rows) {
|
||||
this.queryParam.name=''
|
||||
if(JSON.parse(this.rows).depotId && JSON.parse(this.rows).barCode ){
|
||||
this.queryParam.depotId = JSON.parse(this.rows).depotId-0
|
||||
this.queryParam.barCode = JSON.parse(this.rows).barCode
|
||||
}
|
||||
}
|
||||
that.loadData(1);
|
||||
}
|
||||
that.selectedRowKeys = [];
|
||||
that.selectIds = [];
|
||||
},
|
||||
close() {
|
||||
this.searchReset(0);
|
||||
this.visible = false;
|
||||
},
|
||||
handleSubmit() {
|
||||
let that = this;
|
||||
this.getSelectRows();
|
||||
that.$emit('ok', that.selectRows, that.selectIds);
|
||||
that.searchReset(0)
|
||||
that.close();
|
||||
},
|
||||
//获取选择信息
|
||||
getSelectRows(rowId) {
|
||||
let dataSource = this.dataSource;
|
||||
let ids = "";
|
||||
this.selectRows = [];
|
||||
for (let i = 0, len = dataSource.length; i < len; i++) {
|
||||
if (this.selectedRowKeys.includes(dataSource[i].id)) {
|
||||
this.selectRows.push(dataSource[i]);
|
||||
ids = ids + "," + dataSource[i].batchNumber
|
||||
}
|
||||
}
|
||||
this.selectIds = ids.substring(1);
|
||||
},
|
||||
onSelectChange(selectedRowKeys, selectionRows) {
|
||||
this.selectedRowKeys = selectedRowKeys;
|
||||
this.selectionRows = selectionRows;
|
||||
},
|
||||
onSearch() {
|
||||
this.loadData(1);
|
||||
},
|
||||
modalFormOk() {
|
||||
this.loadData();
|
||||
},
|
||||
rowAction(record, index) {
|
||||
return {
|
||||
on: {
|
||||
click: () => {
|
||||
let arr = []
|
||||
arr.push(record.id)
|
||||
this.selectedRowKeys = arr
|
||||
},
|
||||
dblclick: () => {
|
||||
let arr = []
|
||||
arr.push(record.id)
|
||||
this.selectedRowKeys = arr
|
||||
this.handleSubmit()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ant-table-tbody .ant-table-row td {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
#components-layout-demo-custom-trigger .trigger {
|
||||
font-size: 18px;
|
||||
line-height: 64px;
|
||||
padding: 0 24px;
|
||||
cursor: pointer;
|
||||
transition: color .3s;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,241 @@
|
||||
<template>
|
||||
<a-modal
|
||||
title="选择部门"
|
||||
:width="modalWidth"
|
||||
:visible="visible"
|
||||
:confirmLoading="confirmLoading"
|
||||
@ok="handleSubmit"
|
||||
@cancel="handleCancel"
|
||||
cancelText="关闭">
|
||||
<a-spin tip="Loading..." :spinning="false">
|
||||
<a-input-search style="margin-bottom: 1px" placeholder="请输入部门名称按回车进行搜索" @search="onSearch" />
|
||||
<a-tree
|
||||
checkable
|
||||
:treeData="treeData"
|
||||
:checkStrictly="true"
|
||||
@check="onCheck"
|
||||
@select="onSelect"
|
||||
@expand="onExpand"
|
||||
:autoExpandParent="autoExpandParent"
|
||||
:expandedKeys="expandedKeys"
|
||||
:checkedKeys="checkedKeys">
|
||||
|
||||
<template slot="title" slot-scope="{title}">
|
||||
<span v-if="title.indexOf(searchValue) > -1">
|
||||
{{title.substr(0, title.indexOf(searchValue))}}
|
||||
<span style="color: #f50">{{searchValue}}</span>
|
||||
{{title.substr(title.indexOf(searchValue) + searchValue.length)}}
|
||||
</span>
|
||||
<span v-else>{{title}}</span>
|
||||
</template>
|
||||
</a-tree>
|
||||
|
||||
</a-spin>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { queryDepartTreeList } from '@/api/api'
|
||||
export default {
|
||||
name: 'JSelectDepartModal',
|
||||
props:['modalWidth','multi','rootOpened','departId'],
|
||||
data(){
|
||||
return {
|
||||
visible:false,
|
||||
confirmLoading:false,
|
||||
treeData:[],
|
||||
autoExpandParent:true,
|
||||
expandedKeys:[],
|
||||
dataList:[],
|
||||
checkedKeys:[],
|
||||
checkedRows:[],
|
||||
searchValue:""
|
||||
}
|
||||
},
|
||||
created(){
|
||||
this.loadDepart();
|
||||
},
|
||||
watch:{
|
||||
departId(){
|
||||
this.initDepartComponent()
|
||||
},
|
||||
visible: {
|
||||
handler() {
|
||||
if (this.departId) {
|
||||
this.checkedKeys = this.departId.split(",");
|
||||
// console.log('this.departId', this.departId)
|
||||
} else {
|
||||
this.checkedKeys = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
show(){
|
||||
this.visible=true
|
||||
this.checkedRows=[]
|
||||
this.checkedKeys=[]
|
||||
},
|
||||
loadDepart(){
|
||||
queryDepartTreeList().then(res=>{
|
||||
if(res.success){
|
||||
let arr = [...res.result]
|
||||
this.reWriterWithSlot(arr)
|
||||
this.treeData = arr
|
||||
this.initDepartComponent()
|
||||
if(this.rootOpened){
|
||||
this.initExpandedKeys(res.result)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
initDepartComponent(){
|
||||
let names = ''
|
||||
if(this.departId){
|
||||
let currDepartId = this.departId
|
||||
for(let item of this.dataList){
|
||||
if(currDepartId.indexOf(item.key)>=0){
|
||||
names+=","+item.title
|
||||
}
|
||||
}
|
||||
if(names){
|
||||
names = names.substring(1)
|
||||
}
|
||||
}
|
||||
this.$emit("initComp",names)
|
||||
},
|
||||
reWriterWithSlot(arr){
|
||||
for(let item of arr){
|
||||
if(item.children && item.children.length>0){
|
||||
this.reWriterWithSlot(item.children)
|
||||
let temp = Object.assign({},item)
|
||||
temp.children = {}
|
||||
this.dataList.push(temp)
|
||||
}else{
|
||||
this.dataList.push(item)
|
||||
item.scopedSlots={ title: 'title' }
|
||||
}
|
||||
}
|
||||
},
|
||||
initExpandedKeys(arr){
|
||||
if(arr && arr.length>0){
|
||||
let keys = []
|
||||
for(let item of arr){
|
||||
if(item.children && item.children.length>0){
|
||||
keys.push(item.id)
|
||||
}
|
||||
}
|
||||
this.expandedKeys=[...keys]
|
||||
}else{
|
||||
this.expandedKeys=[]
|
||||
}
|
||||
},
|
||||
onCheck (checkedKeys,info) {
|
||||
if(!this.multi){
|
||||
let arr = checkedKeys.checked.filter(item => this.checkedKeys.indexOf(item) < 0)
|
||||
this.checkedKeys = [...arr]
|
||||
this.checkedRows = (this.checkedKeys.length === 0) ? [] : [info.node.dataRef]
|
||||
}else{
|
||||
this.checkedKeys = checkedKeys.checked
|
||||
this.checkedRows = this.getCheckedRows(this.checkedKeys)
|
||||
}
|
||||
},
|
||||
onSelect(selectedKeys,info) {
|
||||
let keys = []
|
||||
keys.push(selectedKeys[0])
|
||||
if(!this.checkedKeys || this.checkedKeys.length===0 || !this.multi){
|
||||
this.checkedKeys = [...keys]
|
||||
this.checkedRows=[info.node.dataRef]
|
||||
}else{
|
||||
let currKey = info.node.dataRef.key
|
||||
if(this.checkedKeys.indexOf(currKey)>=0){
|
||||
this.checkedKeys = this.checkedKeys.filter(item=> item !==currKey)
|
||||
}else{
|
||||
this.checkedKeys.push(...keys)
|
||||
}
|
||||
}
|
||||
this.checkedRows = this.getCheckedRows(this.checkedKeys)
|
||||
},
|
||||
onExpand (expandedKeys) {
|
||||
this.expandedKeys = expandedKeys
|
||||
this.autoExpandParent = false
|
||||
},
|
||||
handleSubmit(){
|
||||
if(!this.checkedKeys || this.checkedKeys.length==0){
|
||||
this.$emit("ok",'')
|
||||
}else{
|
||||
this.$emit("ok",this.checkedRows,this.checkedKeys.join(","))
|
||||
}
|
||||
this.handleClear()
|
||||
},
|
||||
handleCancel(){
|
||||
this.handleClear()
|
||||
},
|
||||
handleClear(){
|
||||
this.visible=false
|
||||
this.checkedKeys=[]
|
||||
},
|
||||
getParentKey(currKey,treeData){
|
||||
let parentKey
|
||||
for (let i = 0; i < treeData.length; i++) {
|
||||
const node = treeData[i]
|
||||
if (node.children) {
|
||||
if (node.children.some(item => item.key === currKey)) {
|
||||
parentKey = node.key
|
||||
} else if (this.getParentKey(currKey, node.children)) {
|
||||
parentKey = this.getParentKey(currKey, node.children)
|
||||
}
|
||||
}
|
||||
}
|
||||
return parentKey
|
||||
},
|
||||
onSearch(value){
|
||||
const expandedKeys = this.dataList.map((item) => {
|
||||
if (item.title.indexOf(value) > -1) {
|
||||
return this.getParentKey(item.key,this.treeData)
|
||||
}
|
||||
return null
|
||||
}).filter((item, i, self) => item && self.indexOf(item) === i)
|
||||
|
||||
Object.assign(this, {
|
||||
expandedKeys,
|
||||
searchValue: value,
|
||||
autoExpandParent: true,
|
||||
})
|
||||
|
||||
|
||||
},
|
||||
// 根据 checkedKeys 获取 rows
|
||||
getCheckedRows(checkedKeys) {
|
||||
const forChildren = (list, key) => {
|
||||
for (let item of list) {
|
||||
if (item.id === key) {
|
||||
return item
|
||||
}
|
||||
if (item.children instanceof Array) {
|
||||
let value = forChildren(item.children, key)
|
||||
if (value != null) {
|
||||
return value
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
let rows = []
|
||||
for (let key of checkedKeys) {
|
||||
let row = forChildren(this.treeData, key)
|
||||
if (row != null) {
|
||||
rows.push(row)
|
||||
}
|
||||
}
|
||||
return rows
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,370 @@
|
||||
<template>
|
||||
<a-modal
|
||||
:width="modalWidth"
|
||||
:visible="visible"
|
||||
:title="title"
|
||||
@ok="handleSubmit"
|
||||
@cancel="close"
|
||||
cancelText="关闭"
|
||||
style="top:5%;height: 100%;overflow-y: hidden"
|
||||
wrapClassName="ant-modal-cust-warp"
|
||||
>
|
||||
<a-row :gutter="10" style="padding: 10px; margin: -10px">
|
||||
<a-col :md="24" :sm="24">
|
||||
<!-- 查询区域 -->
|
||||
<div class="table-page-search-wrapper">
|
||||
<!-- 搜索区域 -->
|
||||
<a-form layout="inline" @keyup.enter.native="onSearch">
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="6" :sm="8">
|
||||
<a-form-item label="商品" :labelCol="{span: 5}" :wrapperCol="{span: 18, offset: 1}">
|
||||
<a-input ref="material" placeholder="物料编码、名称、规格、型号" v-model="queryParam.q"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="8">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="类别">
|
||||
<a-tree-select style="width:100%" :dropdownStyle="{maxHeight:'200px',overflow:'auto'}" allow-clear
|
||||
:treeData="categoryTree" v-model="queryParam.categoryId" placeholder="请选择类别">
|
||||
</a-tree-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="8">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="仓库">
|
||||
<a-select placeholder="选择仓库" v-model="queryParam.depotId" @change="onDepotChange"
|
||||
:dropdownMatchSelectWidth="false" showSearch optionFilterProp="children" allow-clear>
|
||||
<a-select-option v-for="(item,index) in depotList" :key="index" :value="item.id">
|
||||
{{ item.depotName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-button type="primary" @click="loadData(1)">查询</a-button>
|
||||
<a-button style="margin-left: 8px" @click="searchReset(1)">重置</a-button>
|
||||
</a-col>
|
||||
</span>
|
||||
</a-row>
|
||||
</a-form>
|
||||
<a-table
|
||||
ref="table"
|
||||
:scroll="scrollTrigger"
|
||||
size="middle"
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange,type: getType}"
|
||||
:loading="loading"
|
||||
:customRow="rowAction"
|
||||
@change="handleTableChange">
|
||||
<template slot="customRenderEnableSerialNumber" slot-scope="enableSerialNumber">
|
||||
<a-tag v-if="enableSerialNumber==1" color="green">有</a-tag>
|
||||
<a-tag v-if="enableSerialNumber==0" color="orange">无</a-tag>
|
||||
</template>
|
||||
<template slot="customRenderEnableBatchNumber" slot-scope="enableBatchNumber">
|
||||
<a-tag v-if="enableBatchNumber==1" color="green">有</a-tag>
|
||||
<a-tag v-if="enableBatchNumber==0" color="orange">无</a-tag>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { httpAction, getAction } from '@/api/manage'
|
||||
import {filterObj, getMpListShort} from '@/utils/util'
|
||||
import {getMaterialBySelect, queryMaterialCategoryTreeList} from '@/api/api'
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
import Vue from 'vue'
|
||||
|
||||
export default {
|
||||
name: 'JSelectMaterialModal',
|
||||
mixins:[JeecgListMixin],
|
||||
components: {},
|
||||
props: ['modalWidth', 'rows', 'multi', 'barCode'],
|
||||
data() {
|
||||
return {
|
||||
queryParam: {
|
||||
q: '',
|
||||
depotId: ''
|
||||
},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 5 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
categoryTree:[],
|
||||
columns: [
|
||||
{dataIndex: 'mBarCode', title: '物料编码', width: 100, align: 'left'},
|
||||
{dataIndex: 'name', title: '名称', width: 120, ellipsis:true},
|
||||
{dataIndex: 'categoryName', title: '类别', width: 80},
|
||||
{dataIndex: 'standard', title: '规格', width: 80},
|
||||
{dataIndex: 'model', title: '型号', width: 80},
|
||||
{dataIndex: 'color', title: '颜色', width: 80},
|
||||
{dataIndex: 'unit', title: '单位', width: 70, ellipsis:true},
|
||||
{dataIndex: 'sku', title: '多属性', width: 80},
|
||||
{dataIndex: 'stock', title: '库存', width: 60},
|
||||
{dataIndex: 'expand', title: '扩展信息', width: 80, ellipsis:true},
|
||||
{dataIndex: 'enableSerialNumber', title: '序列号', width: 60, align: "center",
|
||||
scopedSlots: { customRender: 'customRenderEnableSerialNumber' }
|
||||
},
|
||||
{dataIndex: 'enableBatchNumber', title: '批号', width: 50, align: "center",
|
||||
scopedSlots: { customRender: 'customRenderEnableBatchNumber' }
|
||||
}
|
||||
],
|
||||
scrollTrigger: {},
|
||||
dataSource: [],
|
||||
selectedRowKeys: [],
|
||||
selectMaterialRows: [],
|
||||
selectMaterialIds: [],
|
||||
title: '选择商品',
|
||||
ipagination: {
|
||||
current: 1,
|
||||
pageSize: 2,
|
||||
pageSizeOptions: ['10', '20', '30'],
|
||||
showTotal: (total, range) => {
|
||||
return range[0] + '-' + range[1] + ' 共' + total + '条'
|
||||
},
|
||||
showQuickJumper: true,
|
||||
showSizeChanger: true,
|
||||
total: 0
|
||||
},
|
||||
isorter: {
|
||||
column: 'createTime',
|
||||
order: 'desc'
|
||||
},
|
||||
departTree: [],
|
||||
depotList: [],
|
||||
visible: false,
|
||||
form: this.$form.createForm(this),
|
||||
loading: false,
|
||||
expandedKeys: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 计算属性的 getter
|
||||
getType: function () {
|
||||
return this.multi == true ? 'checkbox' : 'radio';
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
barCode: {
|
||||
immediate: true,
|
||||
handler() {
|
||||
this.initBarCode()
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
// 该方法触发屏幕自适应
|
||||
this.resetScreenSize()
|
||||
// this.loadTreeData()
|
||||
// this.getDepotList()
|
||||
},
|
||||
methods: {
|
||||
initBarCode() {
|
||||
if (this.barCode) {
|
||||
this.$emit('initComp', this.barCode)
|
||||
} else {
|
||||
// JSelectUserByDep组件bug issues/I16634
|
||||
this.$emit('initComp', '')
|
||||
}
|
||||
},
|
||||
async loadData(arg) {
|
||||
if (arg === 1) {
|
||||
this.ipagination.current = 1;
|
||||
}
|
||||
this.loading = true
|
||||
let params = this.getQueryParams()//查询条件
|
||||
if(this.visible) {
|
||||
await getMaterialBySelect(params).then((res) => {
|
||||
if (res) {
|
||||
this.dataSource = res.rows
|
||||
this.ipagination.total = res.total
|
||||
if(res.total ===1) {
|
||||
this.title = '选择商品【再次回车可以直接选中】'
|
||||
this.$nextTick(() =>{
|
||||
this.$refs.material.focus()
|
||||
});
|
||||
} else {
|
||||
this.title = '选择商品'
|
||||
}
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
loadTreeData(){
|
||||
let that = this;
|
||||
let params = {};
|
||||
params.id='';
|
||||
queryMaterialCategoryTreeList(params).then((res)=>{
|
||||
if(res){
|
||||
that.categoryTree = [];
|
||||
for (let i = 0; i < res.length; i++) {
|
||||
let temp = res[i];
|
||||
that.categoryTree.push(temp);
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
// 触发屏幕自适应
|
||||
resetScreenSize() {
|
||||
let screenWidth = document.body.clientWidth;
|
||||
if (screenWidth < 500) {
|
||||
this.scrollTrigger = {x: 800};
|
||||
} else {
|
||||
this.scrollTrigger = {};
|
||||
}
|
||||
},
|
||||
showModal(barCode) {
|
||||
this.visible = true;
|
||||
this.title = '选择商品'
|
||||
this.queryParam.q = barCode
|
||||
this.$nextTick(() => this.$refs.material.focus());
|
||||
this.initDepotSelect()
|
||||
this.loadData();
|
||||
this.loadTreeData()
|
||||
this.getDepotList()
|
||||
this.form.resetFields();
|
||||
},
|
||||
getQueryParams() {
|
||||
let param = Object.assign({}, this.queryParam, this.isorter);
|
||||
param.mpList = getMpListShort(Vue.ls.get('materialPropertyList')) //扩展属性
|
||||
param.page = this.ipagination.current;
|
||||
param.rows = this.ipagination.pageSize;
|
||||
return filterObj(param);
|
||||
},
|
||||
getQueryField() {
|
||||
let str = 'id,';
|
||||
for (let a = 0; a < this.columns.length; a++) {
|
||||
str += ',' + this.columns[a].dataIndex;
|
||||
}
|
||||
return str;
|
||||
},
|
||||
searchReset(num) {
|
||||
let that = this;
|
||||
if (num !== 0) {
|
||||
that.queryParam = {};
|
||||
that.loadData(1);
|
||||
}
|
||||
that.selectedRowKeys = [];
|
||||
that.selectMaterialIds = [];
|
||||
},
|
||||
close() {
|
||||
this.searchReset(0);
|
||||
this.visible = false;
|
||||
},
|
||||
handleTableChange(pagination, filters, sorter) {
|
||||
if (Object.keys(sorter).length > 0) {
|
||||
this.isorter.column = sorter.field;
|
||||
this.isorter.order = 'ascend' === sorter.order ? 'asc' : 'desc';
|
||||
}
|
||||
this.ipagination = pagination;
|
||||
this.loadData();
|
||||
},
|
||||
handleSubmit() {
|
||||
let that = this;
|
||||
this.getSelectMaterialRows();
|
||||
that.$emit('ok', that.selectMaterialRows, that.selectMaterialIds);
|
||||
that.searchReset(0)
|
||||
that.close();
|
||||
},
|
||||
//获取选择信息
|
||||
getSelectMaterialRows(rowId) {
|
||||
let dataSource = this.dataSource;
|
||||
let materialIds = "";
|
||||
this.selectMaterialRows = [];
|
||||
for (let i = 0, len = dataSource.length; i < len; i++) {
|
||||
if (this.selectedRowKeys.includes(dataSource[i].id)) {
|
||||
this.selectMaterialRows.push(dataSource[i]);
|
||||
materialIds = materialIds + "," + dataSource[i].mBarCode
|
||||
}
|
||||
}
|
||||
this.selectMaterialIds = materialIds.substring(1);
|
||||
},
|
||||
getDepotList() {
|
||||
let that = this;
|
||||
getAction('/depot/findDepotByCurrentUser').then((res) => {
|
||||
if(res.code === 200){
|
||||
that.depotList = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
initDepotSelect() {
|
||||
if(this.rows) {
|
||||
if(JSON.parse(this.rows).depotId){
|
||||
this.queryParam.depotId = JSON.parse(this.rows).depotId-0
|
||||
}
|
||||
}
|
||||
},
|
||||
onDepotChange(value) {
|
||||
this.queryParam.depotId = value
|
||||
},
|
||||
onSelectChange(selectedRowKeys, selectionRows) {
|
||||
this.selectedRowKeys = selectedRowKeys;
|
||||
this.selectionRows = selectionRows;
|
||||
},
|
||||
onSearch() {
|
||||
if(this.dataSource && this.dataSource.length===1) {
|
||||
if(this.queryParam.q === this.dataSource[0].mBarCode||
|
||||
this.queryParam.q === this.dataSource[0].name||
|
||||
this.queryParam.q === this.dataSource[0].standard||
|
||||
this.queryParam.q === this.dataSource[0].model) {
|
||||
let arr = []
|
||||
arr.push(this.dataSource[0].id)
|
||||
this.selectedRowKeys = arr
|
||||
this.handleSubmit()
|
||||
} else {
|
||||
this.loadData(1)
|
||||
}
|
||||
} else {
|
||||
this.loadData(1)
|
||||
}
|
||||
},
|
||||
modalFormOk() {
|
||||
this.loadData()
|
||||
},
|
||||
rowAction(record, index) {
|
||||
return {
|
||||
on: {
|
||||
click: () => {
|
||||
let arr = []
|
||||
arr.push(record.id)
|
||||
this.selectedRowKeys = arr
|
||||
},
|
||||
dblclick: () => {
|
||||
let arr = []
|
||||
arr.push(record.id)
|
||||
this.selectedRowKeys = arr
|
||||
this.handleSubmit()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ant-table-tbody .ant-table-row td {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
#components-layout-demo-custom-trigger .trigger {
|
||||
font-size: 18px;
|
||||
line-height: 64px;
|
||||
padding: 0 24px;
|
||||
cursor: pointer;
|
||||
transition: color .3s;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,262 @@
|
||||
<template>
|
||||
<a-modal
|
||||
:width="modalWidth"
|
||||
:visible="visible"
|
||||
:title="title"
|
||||
@ok="handleSubmit"
|
||||
@cancel="close"
|
||||
cancelText="关闭"
|
||||
style="margin-top: -70px"
|
||||
wrapClassName="ant-modal-cust-warp"
|
||||
>
|
||||
<a-row :gutter="10" style="padding: 10px; margin: -10px">
|
||||
<a-col :md="24" :sm="24">
|
||||
<!-- 查询区域 -->
|
||||
<div class="table-page-search-wrapper">
|
||||
<!-- 搜索区域 -->
|
||||
<a-form layout="inline" @keyup.enter.native="onSearch">
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="12" :sm="12">
|
||||
<a-form-item label="商品信息" :labelCol="{span: 5}" :wrapperCol="{span: 18, offset: 1}">
|
||||
<a-input placeholder="请输入条码、名称、规格、型号" v-model="queryParam.q"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
|
||||
<a-col :md="12" :sm="12">
|
||||
<a-button type="primary" @click="onSearch">查询</a-button>
|
||||
<a-button style="margin-left: 8px" @click="searchReset(1)">重置</a-button>
|
||||
</a-col>
|
||||
</span>
|
||||
</a-row>
|
||||
</a-form>
|
||||
<a-table
|
||||
ref="table"
|
||||
:scroll="scrollTrigger"
|
||||
size="middle"
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange,type: getType}"
|
||||
:loading="loading"
|
||||
:customRow="rowAction"
|
||||
@change="handleTableChange">
|
||||
</a-table>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {filterObj} from '@/utils/util'
|
||||
import {getSerialMaterialBySelect} from '@/api/api'
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
|
||||
export default {
|
||||
name: 'JSelectSerialMaterialModal',
|
||||
mixins:[JeecgListMixin],
|
||||
components: {},
|
||||
props: ['modalWidth', 'multi', 'barCode'],
|
||||
data() {
|
||||
return {
|
||||
queryParam: {
|
||||
q: ''
|
||||
},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 5 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
columns: [
|
||||
{dataIndex: 'mBarCode', title: '物料编码', width: 100, align: 'left'},
|
||||
{dataIndex: 'name', title: '名称', width: 100},
|
||||
{dataIndex: 'standard', title: '规格', width: 80},
|
||||
{dataIndex: 'model', title: '型号', width: 80}
|
||||
],
|
||||
scrollTrigger: {},
|
||||
dataSource: [],
|
||||
selectedRowKeys: [],
|
||||
selectMaterialRows: [],
|
||||
selectMaterialIds: [],
|
||||
title: '选择序列号商品',
|
||||
ipagination: {
|
||||
current: 1,
|
||||
pageSize: 5,
|
||||
pageSizeOptions: ['5', '10', '20', '30'],
|
||||
showTotal: (total, range) => {
|
||||
return range[0] + '-' + range[1] + ' 共' + total + '条'
|
||||
},
|
||||
showQuickJumper: true,
|
||||
showSizeChanger: true,
|
||||
total: 0
|
||||
},
|
||||
isorter: {
|
||||
column: 'createTime',
|
||||
order: 'desc'
|
||||
},
|
||||
visible: false,
|
||||
form: this.$form.createForm(this),
|
||||
loading: false,
|
||||
expandedKeys: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 计算属性的 getter
|
||||
getType: function () {
|
||||
return this.multi == true ? 'checkbox' : 'radio';
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
barCode: {
|
||||
immediate: true,
|
||||
handler() {
|
||||
this.initBarCode()
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
// 该方法触发屏幕自适应
|
||||
this.resetScreenSize()
|
||||
this.loadData()
|
||||
},
|
||||
methods: {
|
||||
initBarCode() {
|
||||
if (this.barCode) {
|
||||
this.$emit('initComp', this.barCode)
|
||||
} else {
|
||||
// JSelectUserByDep组件bug issues/I16634
|
||||
this.$emit('initComp', '')
|
||||
}
|
||||
},
|
||||
async loadData(arg) {
|
||||
if (arg === 1) {
|
||||
this.ipagination.current = 1;
|
||||
}
|
||||
this.loading = true
|
||||
let params = this.getQueryParams()//查询条件
|
||||
await getSerialMaterialBySelect(params).then((res) => {
|
||||
if (res) {
|
||||
this.dataSource = res.rows
|
||||
this.ipagination.total = res.total
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
// 触发屏幕自适应
|
||||
resetScreenSize() {
|
||||
let screenWidth = document.body.clientWidth;
|
||||
if (screenWidth < 500) {
|
||||
this.scrollTrigger = {x: 800};
|
||||
} else {
|
||||
this.scrollTrigger = {};
|
||||
}
|
||||
},
|
||||
showModal() {
|
||||
this.visible = true;
|
||||
this.loadData();
|
||||
this.form.resetFields();
|
||||
},
|
||||
getQueryParams() {
|
||||
let param = Object.assign({}, this.queryParam, this.isorter);
|
||||
param.page = this.ipagination.current;
|
||||
param.rows = this.ipagination.pageSize;
|
||||
return filterObj(param);
|
||||
},
|
||||
getQueryField() {
|
||||
let str = 'id,';
|
||||
for (let a = 0; a < this.columns.length; a++) {
|
||||
str += ',' + this.columns[a].dataIndex;
|
||||
}
|
||||
return str;
|
||||
},
|
||||
searchReset(num) {
|
||||
let that = this;
|
||||
if (num !== 0) {
|
||||
that.queryParam = {};
|
||||
that.loadData(1);
|
||||
}
|
||||
that.selectedRowKeys = [];
|
||||
that.selectMaterialIds = [];
|
||||
},
|
||||
close() {
|
||||
this.searchReset(0);
|
||||
this.visible = false;
|
||||
},
|
||||
handleTableChange(pagination, filters, sorter) {
|
||||
if (Object.keys(sorter).length > 0) {
|
||||
this.isorter.column = sorter.field;
|
||||
this.isorter.order = 'ascend' === sorter.order ? 'asc' : 'desc';
|
||||
}
|
||||
this.ipagination = pagination;
|
||||
this.loadData();
|
||||
},
|
||||
handleSubmit() {
|
||||
let that = this;
|
||||
this.getSelectMaterialRows();
|
||||
that.$emit('ok', that.selectMaterialRows, that.selectMaterialIds);
|
||||
that.searchReset(0)
|
||||
that.close();
|
||||
},
|
||||
//获取选择信息
|
||||
getSelectMaterialRows(rowId) {
|
||||
let dataSource = this.dataSource;
|
||||
let materialIds = "";
|
||||
this.selectMaterialRows = [];
|
||||
for (let i = 0, len = dataSource.length; i < len; i++) {
|
||||
if (this.selectedRowKeys.includes(dataSource[i].id)) {
|
||||
this.selectMaterialRows.push(dataSource[i]);
|
||||
materialIds = materialIds + "," + dataSource[i].mBarCode
|
||||
}
|
||||
}
|
||||
this.selectMaterialIds = materialIds.substring(1);
|
||||
},
|
||||
onSelectChange(selectedRowKeys, selectionRows) {
|
||||
this.selectedRowKeys = selectedRowKeys;
|
||||
this.selectionRows = selectionRows;
|
||||
},
|
||||
onSearch() {
|
||||
this.loadData(1);
|
||||
},
|
||||
modalFormOk() {
|
||||
this.loadData();
|
||||
},
|
||||
rowAction(record, index) {
|
||||
return {
|
||||
on: {
|
||||
click: () => {
|
||||
let arr = []
|
||||
arr.push(record.id)
|
||||
this.selectedRowKeys = arr
|
||||
},
|
||||
dblclick: () => {
|
||||
let arr = []
|
||||
arr.push(record.id)
|
||||
this.selectedRowKeys = arr
|
||||
this.handleSubmit()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ant-table-tbody .ant-table-row td {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
#components-layout-demo-custom-trigger .trigger {
|
||||
font-size: 18px;
|
||||
line-height: 64px;
|
||||
padding: 0 24px;
|
||||
cursor: pointer;
|
||||
transition: color .3s;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,265 @@
|
||||
<template>
|
||||
<a-modal
|
||||
:width="modalWidth"
|
||||
:visible="visible"
|
||||
:title="title"
|
||||
@ok="handleSubmit"
|
||||
@cancel="close"
|
||||
cancelText="关闭"
|
||||
style="top:5%;height: 100%;overflow-y: hidden"
|
||||
wrapClassName="ant-modal-cust-warp"
|
||||
>
|
||||
<a-row :gutter="10" style="padding: 10px; margin: -10px">
|
||||
<a-col :md="24" :sm="24">
|
||||
<!-- 查询区域 -->
|
||||
<div class="table-page-search-wrapper">
|
||||
<!-- 搜索区域 -->
|
||||
<a-form layout="inline" @keyup.enter.native="onSearch">
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="6" :sm="8">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="序列号">
|
||||
<a-input placeholder="请输入序列号" v-model="queryParam.name"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-button type="primary" @click="onSearch">查询</a-button>
|
||||
<a-button style="margin-left: 8px" @click="searchReset(1)">重置</a-button>
|
||||
</a-col>
|
||||
</span>
|
||||
</a-row>
|
||||
</a-form>
|
||||
<a-table
|
||||
ref="table"
|
||||
:scroll="scrollTrigger"
|
||||
size="middle"
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange,type: getType}"
|
||||
:loading="loading"
|
||||
:customRow="rowAction"
|
||||
@change="handleTableChange">
|
||||
</a-table>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getAction } from '@/api/manage'
|
||||
import {getEnableSerialNumberList} from '@/api/api'
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
|
||||
export default {
|
||||
name: 'JSelectSnModal',
|
||||
mixins:[JeecgListMixin],
|
||||
components: {},
|
||||
props: ['modalWidth', 'rows', 'multi', 'barCode'],
|
||||
data() {
|
||||
return {
|
||||
queryParam: {
|
||||
name: "",
|
||||
depotId: '',
|
||||
barCode: ''
|
||||
},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 5 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
categoryTree:[],
|
||||
columns: [
|
||||
{dataIndex: 'serialNumber', title: '序列号', width: 100, align: 'left'}
|
||||
],
|
||||
scrollTrigger: {},
|
||||
dataSource: [],
|
||||
selectedRowKeys: [],
|
||||
selectRows: [],
|
||||
selectIds: [],
|
||||
title: '选择序列号',
|
||||
ipagination: {
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
pageSizeOptions: ['10', '20', '30', '100', '200'],
|
||||
showTotal: (total, range) => {
|
||||
return range[0] + '-' + range[1] + ' 共' + total + '条'
|
||||
},
|
||||
showQuickJumper: true,
|
||||
showSizeChanger: true,
|
||||
total: 0
|
||||
},
|
||||
isorter: {
|
||||
column: 'createTime',
|
||||
order: 'desc'
|
||||
},
|
||||
departTree: [],
|
||||
depotList: [],
|
||||
visible: false,
|
||||
form: this.$form.createForm(this),
|
||||
loading: false,
|
||||
expandedKeys: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 计算属性的 getter
|
||||
getType: function () {
|
||||
return this.multi == true ? 'checkbox' : 'radio';
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
barCode: {
|
||||
immediate: true,
|
||||
handler() {
|
||||
this.initBarCode()
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.loadData()
|
||||
},
|
||||
methods: {
|
||||
initBarCode() {
|
||||
if (this.barCode) {
|
||||
this.$emit('initComp', this.barCode)
|
||||
} else {
|
||||
// JSelectUserByDep组件bug issues/I16634
|
||||
this.$emit('initComp', '')
|
||||
}
|
||||
},
|
||||
async loadData(arg) {
|
||||
if(this.rows) {
|
||||
if(JSON.parse(this.rows).depotId && JSON.parse(this.rows).barCode ){
|
||||
this.queryParam.depotId = JSON.parse(this.rows).depotId-0
|
||||
this.queryParam.barCode = JSON.parse(this.rows).barCode
|
||||
}
|
||||
}
|
||||
if (arg === 1) {
|
||||
this.ipagination.current = 1;
|
||||
}
|
||||
this.loading = true
|
||||
let params = this.getQueryParams()//查询条件
|
||||
await getEnableSerialNumberList(params).then((res) => {
|
||||
if (res && res.code === 200) {
|
||||
this.dataSource = res.data.rows
|
||||
this.ipagination.total = res.data.total
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
showModal() {
|
||||
this.visible = true;
|
||||
this.loadData();
|
||||
this.form.resetFields();
|
||||
},
|
||||
getQueryParams() {
|
||||
let param = Object.assign({}, this.queryParam, this.isorter);
|
||||
param.page = this.ipagination.current;
|
||||
param.rows = this.ipagination.pageSize;
|
||||
return param;
|
||||
},
|
||||
getQueryField() {
|
||||
let str = 'id,';
|
||||
for (let a = 0; a < this.columns.length; a++) {
|
||||
str += ',' + this.columns[a].dataIndex;
|
||||
}
|
||||
return str;
|
||||
},
|
||||
searchReset(num) {
|
||||
let that = this;
|
||||
if (num !== 0) {
|
||||
if(this.rows) {
|
||||
this.queryParam.name=''
|
||||
if(JSON.parse(this.rows).depotId && JSON.parse(this.rows).barCode ){
|
||||
this.queryParam.depotId = JSON.parse(this.rows).depotId-0
|
||||
this.queryParam.barCode = JSON.parse(this.rows).barCode
|
||||
}
|
||||
}
|
||||
that.loadData(1);
|
||||
}
|
||||
that.selectedRowKeys = [];
|
||||
that.selectIds = [];
|
||||
},
|
||||
close() {
|
||||
this.searchReset(0);
|
||||
this.visible = false;
|
||||
},
|
||||
handleTableChange(pagination, filters, sorter) {
|
||||
if (Object.keys(sorter).length > 0) {
|
||||
this.isorter.column = sorter.field;
|
||||
this.isorter.order = 'ascend' === sorter.order ? 'asc' : 'desc';
|
||||
}
|
||||
this.ipagination = pagination;
|
||||
this.loadData();
|
||||
},
|
||||
handleSubmit() {
|
||||
let that = this;
|
||||
this.getSelectRows();
|
||||
that.$emit('ok', that.selectRows, that.selectIds);
|
||||
that.searchReset(0)
|
||||
that.close();
|
||||
},
|
||||
//获取选择信息
|
||||
getSelectRows(rowId) {
|
||||
let dataSource = this.dataSource;
|
||||
let ids = "";
|
||||
this.selectRows = [];
|
||||
for (let i = 0, len = dataSource.length; i < len; i++) {
|
||||
if (this.selectedRowKeys.includes(dataSource[i].id)) {
|
||||
this.selectRows.push(dataSource[i]);
|
||||
ids = ids + "," + dataSource[i].serialNumber
|
||||
}
|
||||
}
|
||||
this.selectIds = ids.substring(1);
|
||||
},
|
||||
onSelectChange(selectedRowKeys, selectionRows) {
|
||||
this.selectedRowKeys = selectedRowKeys;
|
||||
this.selectionRows = selectionRows;
|
||||
},
|
||||
onSearch() {
|
||||
this.loadData(1);
|
||||
},
|
||||
modalFormOk() {
|
||||
this.loadData();
|
||||
},
|
||||
rowAction(record, index) {
|
||||
return {
|
||||
on: {
|
||||
click: () => {
|
||||
let arr = []
|
||||
arr.push(record.id)
|
||||
this.selectedRowKeys = arr
|
||||
},
|
||||
dblclick: () => {
|
||||
let arr = []
|
||||
arr.push(record.id)
|
||||
this.selectedRowKeys = arr
|
||||
this.handleSubmit()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ant-table-tbody .ant-table-row td {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
#components-layout-demo-custom-trigger .trigger {
|
||||
font-size: 18px;
|
||||
line-height: 64px;
|
||||
padding: 0 24px;
|
||||
cursor: pointer;
|
||||
transition: color .3s;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,329 @@
|
||||
<template>
|
||||
<a-modal
|
||||
:width="modalWidth"
|
||||
:visible="visible"
|
||||
:title="title"
|
||||
@ok="handleSubmit"
|
||||
@cancel="close"
|
||||
cancelText="关闭"
|
||||
style="margin-top: -70px"
|
||||
wrapClassName="ant-modal-cust-warp"
|
||||
>
|
||||
<a-row :gutter="10" style="background-color: #ececec; padding: 10px; margin: -10px">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-card :bordered="false">
|
||||
<!--组织机构-->
|
||||
<a-directory-tree
|
||||
selectable
|
||||
:selectedKeys="selectedDepIds"
|
||||
:checkStrictly="true"
|
||||
:dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
|
||||
:treeData="departTree"
|
||||
:expandAction="false"
|
||||
:expandedKeys.sync="expandedKeys"
|
||||
@select="onDepSelect"
|
||||
/>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :md="18" :sm="24">
|
||||
<a-card :bordered="false">
|
||||
用户账号:
|
||||
<a-input-search
|
||||
:style="{width:'150px',marginBottom:'15px'}"
|
||||
placeholder="请输入账号"
|
||||
v-model="queryParam.username"
|
||||
@search="onSearch"
|
||||
></a-input-search>
|
||||
<a-button @click="searchReset(1)" style="margin-left: 20px" icon="redo">重置</a-button>
|
||||
<!--用户列表-->
|
||||
<a-table
|
||||
ref="table"
|
||||
:scroll="scrollTrigger"
|
||||
size="middle"
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange,type: getType}"
|
||||
:loading="loading"
|
||||
@change="handleTableChange">
|
||||
</a-table>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {filterObj} from '@/utils/util'
|
||||
import {queryDepartTreeList, getUserList, queryUserByDepId} from '@/api/api'
|
||||
|
||||
export default {
|
||||
name: 'JSelectUserByDepModal',
|
||||
components: {},
|
||||
props: ['modalWidth', 'multi', 'userIds'],
|
||||
data() {
|
||||
return {
|
||||
queryParam: {
|
||||
username: "",
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: '用户账号',
|
||||
align: 'center',
|
||||
dataIndex: 'username'
|
||||
},
|
||||
{
|
||||
title: '用户姓名',
|
||||
align: 'center',
|
||||
dataIndex: 'realname'
|
||||
},
|
||||
{
|
||||
title: '性别',
|
||||
align: 'center',
|
||||
dataIndex: 'sex',
|
||||
customRender: function (text) {
|
||||
if (text === 1) {
|
||||
return '男'
|
||||
} else if (text === 2) {
|
||||
return '女'
|
||||
} else {
|
||||
return text
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '手机',
|
||||
align: 'center',
|
||||
dataIndex: 'phone'
|
||||
},
|
||||
{
|
||||
title: '部门',
|
||||
align: 'center',
|
||||
dataIndex: 'orgCode'
|
||||
}
|
||||
],
|
||||
scrollTrigger: {},
|
||||
dataSource: [],
|
||||
selectedRowKeys: [],
|
||||
selectUserRows: [],
|
||||
selectUserIds: [],
|
||||
title: '根据部门选择用户',
|
||||
ipagination: {
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
pageSizeOptions: ['10', '20', '30'],
|
||||
showTotal: (total, range) => {
|
||||
return range[0] + '-' + range[1] + ' 共' + total + '条'
|
||||
},
|
||||
showQuickJumper: true,
|
||||
showSizeChanger: true,
|
||||
total: 0
|
||||
},
|
||||
isorter: {
|
||||
column: 'createTime',
|
||||
order: 'desc'
|
||||
},
|
||||
selectedDepIds: [],
|
||||
departTree: [],
|
||||
visible: false,
|
||||
form: this.$form.createForm(this),
|
||||
loading: false,
|
||||
expandedKeys: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 计算属性的 getter
|
||||
getType: function () {
|
||||
return this.multi == true ? 'checkbox' : 'radio';
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
userIds: {
|
||||
immediate: true,
|
||||
handler() {
|
||||
this.initUserNames()
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
// 该方法触发屏幕自适应
|
||||
this.resetScreenSize();
|
||||
this.loadData()
|
||||
},
|
||||
methods: {
|
||||
initUserNames() {
|
||||
if (this.userIds) {
|
||||
// 这里最后加一个 , 的原因是因为无论如何都要使用 in 查询,防止后台进行了模糊匹配,导致查询结果不准确
|
||||
let values = this.userIds.split(',') + ','
|
||||
getUserList({
|
||||
username: values,
|
||||
pageNo: 1,
|
||||
pageSize: values.length
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
let selectedRowKeys = []
|
||||
let realNames = []
|
||||
res.result.records.forEach(user => {
|
||||
realNames.push(user['realname'])
|
||||
selectedRowKeys.push(user['id'])
|
||||
})
|
||||
this.selectedRowKeys = selectedRowKeys
|
||||
this.$emit('initComp', realNames.join(','))
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// JSelectUserByDep组件bug issues/I16634
|
||||
this.$emit('initComp', '')
|
||||
}
|
||||
},
|
||||
async loadData(arg) {
|
||||
if (arg === 1) {
|
||||
this.ipagination.current = 1;
|
||||
}
|
||||
if (this.selectedDepIds && this.selectedDepIds.length > 0) {
|
||||
await this.initQueryUserByDepId(this.selectedDepIds)
|
||||
} else {
|
||||
this.loading = true
|
||||
let params = this.getQueryParams()//查询条件
|
||||
await getUserList(params).then((res) => {
|
||||
if (res.success) {
|
||||
this.dataSource = res.result.records
|
||||
this.ipagination.total = res.result.total
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
// 触发屏幕自适应
|
||||
resetScreenSize() {
|
||||
let screenWidth = document.body.clientWidth;
|
||||
if (screenWidth < 500) {
|
||||
this.scrollTrigger = {x: 800};
|
||||
} else {
|
||||
this.scrollTrigger = {};
|
||||
}
|
||||
},
|
||||
showModal() {
|
||||
this.visible = true;
|
||||
this.queryDepartTree();
|
||||
this.initUserNames()
|
||||
this.loadData();
|
||||
this.form.resetFields();
|
||||
},
|
||||
getQueryParams() {
|
||||
let param = Object.assign({}, this.queryParam, this.isorter);
|
||||
param.field = this.getQueryField();
|
||||
param.pageNo = this.ipagination.current;
|
||||
param.pageSize = this.ipagination.pageSize;
|
||||
return filterObj(param);
|
||||
},
|
||||
getQueryField() {
|
||||
let str = 'id,';
|
||||
for (let a = 0; a < this.columns.length; a++) {
|
||||
str += ',' + this.columns[a].dataIndex;
|
||||
}
|
||||
return str;
|
||||
},
|
||||
searchReset(num) {
|
||||
let that = this;
|
||||
if (num !== 0) {
|
||||
that.queryParam = {};
|
||||
that.loadData(1);
|
||||
}
|
||||
that.selectedRowKeys = [];
|
||||
that.selectUserIds = [];
|
||||
that.selectedDepIds = [];
|
||||
},
|
||||
close() {
|
||||
this.searchReset(0);
|
||||
this.visible = false;
|
||||
},
|
||||
handleTableChange(pagination, filters, sorter) {
|
||||
//TODO 筛选
|
||||
if (Object.keys(sorter).length > 0) {
|
||||
this.isorter.column = sorter.field;
|
||||
this.isorter.order = 'ascend' === sorter.order ? 'asc' : 'desc';
|
||||
}
|
||||
this.ipagination = pagination;
|
||||
this.loadData();
|
||||
},
|
||||
handleSubmit() {
|
||||
let that = this;
|
||||
this.getSelectUserRows();
|
||||
that.$emit('ok', that.selectUserRows, that.selectUserIds);
|
||||
that.searchReset(0)
|
||||
that.close();
|
||||
},
|
||||
//获取选择用户信息
|
||||
getSelectUserRows(rowId) {
|
||||
let dataSource = this.dataSource;
|
||||
let userIds = "";
|
||||
this.selectUserRows = [];
|
||||
for (let i = 0, len = dataSource.length; i < len; i++) {
|
||||
if (this.selectedRowKeys.includes(dataSource[i].id)) {
|
||||
this.selectUserRows.push(dataSource[i]);
|
||||
userIds = userIds + "," + dataSource[i].username
|
||||
}
|
||||
}
|
||||
this.selectUserIds = userIds.substring(1);
|
||||
},
|
||||
// 点击树节点,筛选出对应的用户
|
||||
onDepSelect(selectedDepIds) {
|
||||
if (selectedDepIds[0] != null) {
|
||||
this.initQueryUserByDepId(selectedDepIds); // 调用方法根据选选择的id查询用户信息
|
||||
if (this.selectedDepIds[0] !== selectedDepIds[0]) {
|
||||
this.selectedDepIds = [selectedDepIds[0]];
|
||||
}
|
||||
}
|
||||
},
|
||||
onSelectChange(selectedRowKeys, selectionRows) {
|
||||
this.selectedRowKeys = selectedRowKeys;
|
||||
this.selectionRows = selectionRows;
|
||||
},
|
||||
onSearch() {
|
||||
this.loadData(1);
|
||||
},
|
||||
// 根据选择的id来查询用户信息
|
||||
initQueryUserByDepId(selectedDepIds) {
|
||||
this.loading = true
|
||||
return queryUserByDepId({id: selectedDepIds.toString()}).then((res) => {
|
||||
if (res.success) {
|
||||
this.dataSource = res.result;
|
||||
this.ipagination.total = res.result.length;
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
queryDepartTree() {
|
||||
queryDepartTreeList().then((res) => {
|
||||
if (res.success) {
|
||||
this.departTree = res.result;
|
||||
// 默认展开父节点
|
||||
this.expandedKeys = this.departTree.map(item => item.id)
|
||||
}
|
||||
})
|
||||
},
|
||||
modalFormOk() {
|
||||
this.loadData();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ant-table-tbody .ant-table-row td {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
#components-layout-demo-custom-trigger .trigger {
|
||||
font-size: 18px;
|
||||
line-height: 64px;
|
||||
padding: 0 24px;
|
||||
cursor: pointer;
|
||||
transition: color .3s;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<a-modal
|
||||
title="用户列表"
|
||||
:width="1000"
|
||||
:visible="visible"
|
||||
:confirmLoading="confirmLoading"
|
||||
@ok="handleSubmit"
|
||||
@cancel="handleCancel">
|
||||
|
||||
<a-table
|
||||
ref="table"
|
||||
bordered
|
||||
size="middle"
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:loading="loading"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"></a-table>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getUserList} from '@/api/api'
|
||||
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
|
||||
|
||||
export default {
|
||||
name: "SelectUserListModal",
|
||||
mixins: [JeecgListMixin],
|
||||
data() {
|
||||
return {
|
||||
title: "操作",
|
||||
visible: false,
|
||||
model: {},
|
||||
confirmLoading: false,
|
||||
url: {
|
||||
add: "/act/model/create",
|
||||
list: "/sys/user/list"
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: '用户账号',
|
||||
align: "center",
|
||||
dataIndex: 'username',
|
||||
fixed: 'left',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: '用户姓名',
|
||||
align: "center",
|
||||
dataIndex: 'realname',
|
||||
},
|
||||
{
|
||||
title: '性别',
|
||||
align: "center",
|
||||
dataIndex: 'sex_dictText'
|
||||
},
|
||||
{
|
||||
title: '手机号码',
|
||||
align: "center",
|
||||
dataIndex: 'phone'
|
||||
},
|
||||
{
|
||||
title: '邮箱',
|
||||
align: "center",
|
||||
dataIndex: 'email'
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
align: "center",
|
||||
dataIndex: 'status_dictText'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
//Step.2 加载用户数据
|
||||
getUserList().then((res) => {
|
||||
if (res.success) {
|
||||
this.dataSource = res.result.records;
|
||||
this.ipagination.total = res.result.total;
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
open() {
|
||||
this.visible = true;
|
||||
|
||||
//Step.1 清空选中用户
|
||||
this.selectedRowKeys = []
|
||||
this.selectedRows = []
|
||||
},
|
||||
close() {
|
||||
this.$emit('close');
|
||||
this.visible = false;
|
||||
},
|
||||
handleChange(info) {
|
||||
let file = info.file;
|
||||
if (file.response.success) {
|
||||
this.$message.success(file.response.message);
|
||||
this.$emit('ok');
|
||||
this.close()
|
||||
} else {
|
||||
this.$message.warn(file.response.message);
|
||||
this.close()
|
||||
}
|
||||
|
||||
},
|
||||
handleCancel() {
|
||||
this.close()
|
||||
},
|
||||
handleSubmit() {
|
||||
this.$emit('ok', this.selectionRows);
|
||||
this.close()
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<component
|
||||
:is="comp"
|
||||
:formData="formData"
|
||||
ref="compModel"
|
||||
v-if="comp">
|
||||
</component>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'DynamicNotice',
|
||||
data () {
|
||||
return {
|
||||
compName: this.path
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
comp: function () {
|
||||
if(!this.path){
|
||||
return null;
|
||||
}
|
||||
return () => import(`@/views/${this.path}.vue`)
|
||||
}
|
||||
},
|
||||
props: ['path','formData'],
|
||||
methods: {
|
||||
detail () {
|
||||
setTimeout(() => {
|
||||
if(this.path){
|
||||
this.$refs.compModel.view(this.formData);
|
||||
}
|
||||
}, 200)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<j-modal
|
||||
:title="title"
|
||||
:width="modelStyle.width"
|
||||
:visible="visible"
|
||||
:bodyStyle ="bodyStyle"
|
||||
:switchFullscreen="switchFullscreen"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<template slot="footer">
|
||||
<a-button key="back" @click="handleCancel">关闭</a-button>
|
||||
<a-button v-if="record.openType==='url'" type="primary" @click="toHandle">去处理</a-button>
|
||||
</template>
|
||||
<a-card class="daily-article" :loading="loading">
|
||||
<a-card-meta
|
||||
:title="record.titile"
|
||||
:description="'标题:'+record.msgTitle">
|
||||
</a-card-meta>
|
||||
<a-divider />
|
||||
<span v-html="record.msgContent" class="article-content"></span>
|
||||
</a-card>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "SysAnnouncementModal",
|
||||
components: {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
title:"通知消息",
|
||||
record: {},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 5 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
visible: false,
|
||||
switchFullscreen: true,
|
||||
loading: false,
|
||||
bodyStyle:{
|
||||
padding: "0",
|
||||
height:(window.innerHeight*0.6)+"px",
|
||||
"overflow-y":"auto",
|
||||
|
||||
},
|
||||
modelStyle:{
|
||||
width: '60%',
|
||||
style: { top: '20px' },
|
||||
fullScreen: false
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
},
|
||||
methods: {
|
||||
detail (record) {
|
||||
this.visible = true;
|
||||
this.record = record;
|
||||
},
|
||||
handleCancel () {
|
||||
this.visible = false;
|
||||
},
|
||||
/** 切换全屏显示 */
|
||||
handleClickToggleFullScreen() {
|
||||
let mode = !this.modelStyle.fullScreen
|
||||
if (mode) {
|
||||
this.modelStyle.width = '100%'
|
||||
this.modelStyle.style.top = '20px'
|
||||
} else {
|
||||
this.modelStyle.width = '60%'
|
||||
this.modelStyle.style.top = '50px'
|
||||
}
|
||||
this.modelStyle.fullScreen = mode
|
||||
},
|
||||
toHandle(){
|
||||
if(this.record.openType==='url'){
|
||||
this.visible = false;
|
||||
//链接跳转
|
||||
this.$router.push({path: this.record.openPage})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.announcementCustomModal{
|
||||
.ant-modal-header {
|
||||
border: none;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
right: 56px;
|
||||
padding: 0;
|
||||
.ant-modal-title{
|
||||
.custom-btn{
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.daily-article{
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style scoped lang="less">
|
||||
.daily-article {
|
||||
.article-button {
|
||||
font-size: 1.2rem !important;
|
||||
}
|
||||
.ant-card-body {
|
||||
padding: 18px !important;
|
||||
}
|
||||
.ant-card-head {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
.ant-card-meta {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.article-content {
|
||||
p {
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
text-overflow: initial;
|
||||
white-space: normal;
|
||||
font-size: .9rem !important;
|
||||
margin-bottom: .8rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
+14
-1
@@ -4,7 +4,7 @@ import Cookies from 'js-cookie'
|
||||
|
||||
import Element from 'element-ui'
|
||||
import './assets/styles/element-variables.scss'
|
||||
|
||||
import Storage from 'vue-ls'
|
||||
import '@/assets/styles/index.scss' // global css
|
||||
import '@/assets/styles/ruoyi.scss' // ruoyi css
|
||||
import App from './App'
|
||||
@@ -16,6 +16,11 @@ import plugins from './plugins' // plugins
|
||||
// 权限指令
|
||||
import permission from './components/Permission'
|
||||
|
||||
import Antd from 'ant-design-vue'
|
||||
import JeecgComponents from '@/components/jeecg/index'
|
||||
// import Viser from 'viser-vue'
|
||||
import 'ant-design-vue/dist/antd.less'; // or 'ant-design-vue/dist/antd.less'
|
||||
|
||||
import './assets/icons' // icon
|
||||
import './permission' // permission control
|
||||
// import './tongji' // 百度统计
|
||||
@@ -43,6 +48,12 @@ Vue.prototype.getDictDataLabel = getDictDataLabel
|
||||
Vue.prototype.DICT_TYPE = DICT_TYPE
|
||||
Vue.prototype.handleTree = handleTree
|
||||
|
||||
Vue.use(Storage, {
|
||||
namespace: 'pro__', // key prefix
|
||||
name: 'ls', // name variable Vue.[ls] or this.[$ls],
|
||||
storage: 'local', // storage name session, local, memory
|
||||
})
|
||||
|
||||
// 全局组件挂载
|
||||
Vue.component('DictTag', DictTag)
|
||||
Vue.component('DocAlert', DocAlert)
|
||||
@@ -54,10 +65,12 @@ import DocAlert from '@/components/DocAlert'
|
||||
// 头部标签插件
|
||||
import VueMeta from 'vue-meta'
|
||||
|
||||
Vue.use(Antd)
|
||||
Vue.use(directive)
|
||||
Vue.use(plugins)
|
||||
Vue.use(VueMeta)
|
||||
Vue.use(permission)
|
||||
Vue.use(JeecgComponents);
|
||||
// Vue.use(hljs.vuePlugin);
|
||||
|
||||
// bpmnProcessDesigner 需要引入
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
import JEditableTable from '@/components/jeecg/JEditableTable'
|
||||
import { VALIDATE_NO_PASSED, getRefPromise, validateFormAndTables } from '@/utils/JEditableTableUtil'
|
||||
import { httpAction, getAction } from '@/api/manage'
|
||||
|
||||
export const JEditableTableMixin = {
|
||||
components: {
|
||||
JEditableTable
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
title: '操作',
|
||||
visible: false,
|
||||
form: this.$form.createForm(this),
|
||||
confirmLoading: false,
|
||||
model: {},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 6 }
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 18 }
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
/** 获取所有的editableTable实例 */
|
||||
getAllTable() {
|
||||
if (!(this.refKeys instanceof Array)) {
|
||||
throw this.throwNotArray('refKeys')
|
||||
}
|
||||
let values = this.refKeys.map(key => getRefPromise(this, key))
|
||||
return Promise.all(values)
|
||||
},
|
||||
|
||||
/** 遍历所有的JEditableTable实例 */
|
||||
eachAllTable(callback) {
|
||||
// 开始遍历
|
||||
this.getAllTable().then(tables => {
|
||||
tables.forEach((item, index) => {
|
||||
if (typeof callback === 'function') {
|
||||
callback(item, index)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
/** 当点击新增按钮时调用此方法 */
|
||||
add() {
|
||||
// addBefore 没有地方用到
|
||||
if (typeof this.addBefore === 'function') this.addBefore()
|
||||
// 默认新增空数据
|
||||
let rowNum = this.addDefaultRowNum
|
||||
if (typeof rowNum !== 'number') {
|
||||
rowNum = 1
|
||||
console.warn('由于你没有在 data 中定义 addDefaultRowNum 或 addDefaultRowNum 不是数字,所以默认添加一条空数据,如果不想默认添加空数据,请将定义 addDefaultRowNum 为 0')
|
||||
}
|
||||
this.eachAllTable((item) => {
|
||||
item.add(rowNum)
|
||||
})
|
||||
if (typeof this.addAfter === 'function') this.addAfter(this.model)
|
||||
this.edit({})
|
||||
},
|
||||
/** 当点击了编辑(修改)按钮时调用此方法 */
|
||||
edit(record) {
|
||||
if (typeof this.editBefore === 'function') this.editBefore(record)
|
||||
this.visible = true
|
||||
this.activeKey = this.refKeys[0]
|
||||
this.form.resetFields()
|
||||
this.model = Object.assign({}, record)
|
||||
if (typeof this.editAfter === 'function') this.editAfter(this.model)
|
||||
},
|
||||
/** 关闭弹窗,并将所有JEditableTable实例回归到初始状态 */
|
||||
close() {
|
||||
this.visible = false
|
||||
this.eachAllTable((item) => {
|
||||
item.initialize()
|
||||
})
|
||||
this.$emit('close')
|
||||
},
|
||||
|
||||
/** 查询某个tab的数据 */
|
||||
requestSubTableData(url, params, tab, success) {
|
||||
tab.loading = true
|
||||
getAction(url, params).then(res => {
|
||||
if(res && res.code === 200){
|
||||
tab.dataSource = res.data.rows
|
||||
typeof success === 'function' ? success(res) : ''
|
||||
}
|
||||
}).finally(() => {
|
||||
tab.loading = false
|
||||
})
|
||||
},
|
||||
/** 发起请求,自动判断是执行新增还是修改操作 */
|
||||
request(formData) {
|
||||
let url = this.url.add, method = 'post'
|
||||
if (this.model.id) {
|
||||
url = this.url.edit
|
||||
method = 'put'
|
||||
}
|
||||
this.confirmLoading = true
|
||||
httpAction(url, formData, method).then((res) => {
|
||||
if(res.code === 200){
|
||||
this.$emit('ok')
|
||||
this.confirmLoading = false
|
||||
this.close()
|
||||
} else {
|
||||
this.$message.warning(res.msg);
|
||||
this.confirmLoading = false
|
||||
}
|
||||
}).finally(() => {
|
||||
})
|
||||
},
|
||||
|
||||
/* --- handle 事件 --- */
|
||||
|
||||
/** ATab 选项卡切换事件 */
|
||||
handleChangeTabs(key) {
|
||||
// 自动重置scrollTop状态,防止出现白屏
|
||||
getRefPromise(this, key).then(editableTable => {
|
||||
editableTable.resetScrollTop()
|
||||
})
|
||||
},
|
||||
/** 关闭按钮点击事件 */
|
||||
handleCancel() {
|
||||
this.close()
|
||||
},
|
||||
/** 确定按钮点击事件 */
|
||||
handleOk() {
|
||||
/** 触发表单验证 */
|
||||
this.getAllTable().then(tables => {
|
||||
let inputValues = tables[0].inputValues
|
||||
let ids = []
|
||||
inputValues.forEach((item) => {
|
||||
if(!item.barCode && !item.operNumber) {
|
||||
ids.push(item.id)
|
||||
}
|
||||
})
|
||||
tables[0].removeRows(ids)
|
||||
/** 一次性验证主表和所有的次表 */
|
||||
return validateFormAndTables(this.form, tables)
|
||||
}).then(allValues => {
|
||||
if (typeof this.classifyIntoFormData !== 'function') {
|
||||
throw this.throwNotFunction('classifyIntoFormData')
|
||||
}
|
||||
let formData = this.classifyIntoFormData(allValues)
|
||||
// 发起请求
|
||||
return this.request(formData)
|
||||
}).catch(e => {
|
||||
if (e.error === VALIDATE_NO_PASSED) {
|
||||
// 如果有未通过表单验证的子表,就自动跳转到它所在的tab
|
||||
this.activeKey = e.index == null ? this.activeKey : this.refKeys[e.index]
|
||||
} else {
|
||||
console.error(e)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
/* --- throw --- */
|
||||
|
||||
/** not a function */
|
||||
throwNotFunction(name) {
|
||||
return `${name} 未定义或不是一个函数`
|
||||
},
|
||||
|
||||
/** not a array */
|
||||
throwNotArray(name) {
|
||||
return `${name} 未定义或不是一个数组`
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,438 @@
|
||||
/**
|
||||
* 新增修改完成调用 modalFormOk方法 编辑弹框组件ref定义为modalForm
|
||||
* 高级查询按钮调用 superQuery方法 高级查询组件ref定义为superQueryModal
|
||||
* data中url定义 list为查询列表 delete为删除单条记录 deleteBatch为批量删除
|
||||
*/
|
||||
import { filterObj } from '@/utils/util';
|
||||
import { deleteAction, getAction, postAction, downFile, getFileAccessHttpUrl } from '@/api/manage'
|
||||
import Vue from 'vue'
|
||||
import {mixinDevice} from '@/utils/mixin.js'
|
||||
|
||||
export const JeecgListMixin = {
|
||||
mixins: [mixinDevice],
|
||||
data(){
|
||||
return {
|
||||
//token header
|
||||
tokenHeader: {'X-Access-Token': ""},
|
||||
/*卡片样式 */
|
||||
cardStyle: '',
|
||||
/* 查询条件-请不要在queryParam中声明非字符串值的属性 */
|
||||
queryParam: {},
|
||||
/* 数据源 */
|
||||
dataSource:[],
|
||||
/* 分页参数 */
|
||||
ipagination:{
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
pageSizeOptions: ['10', '20', '30', '50', '100'],
|
||||
showTotal: (total, range) => {
|
||||
return range[0] + "-" + range[1] + " 共" + total + "条"
|
||||
},
|
||||
showQuickJumper: true,
|
||||
showSizeChanger: true,
|
||||
total: 0
|
||||
},
|
||||
/* 控制table高度 */
|
||||
scroll: {
|
||||
x:1300
|
||||
},
|
||||
/* 排序参数 */
|
||||
isorter:{
|
||||
column: 'createTime',
|
||||
order: 'desc',
|
||||
},
|
||||
/* 筛选参数 */
|
||||
filters: {},
|
||||
/* table加载状态 */
|
||||
loading:false,
|
||||
/* table选中keys*/
|
||||
selectedRowKeys: [],
|
||||
/* table选中records*/
|
||||
selectionRows: [],
|
||||
/* 查询折叠 */
|
||||
toggleSearchStatus:false,
|
||||
/* 高级查询条件生效状态 */
|
||||
superQueryFlag:false,
|
||||
/* 高级查询条件 */
|
||||
superQueryParams: '',
|
||||
/** 高级查询拼接方式 */
|
||||
superQueryMatchType: 'and',
|
||||
/** 是否加载时就执行 */
|
||||
disableMixinCreated: false,
|
||||
/* 按钮权限 */
|
||||
btnEnableList: ''
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if(this.isDesktop()) {
|
||||
this.cardStyle = 'height:' + (document.documentElement.clientHeight-125) + 'px'
|
||||
}
|
||||
if(!this.disableMixinCreated){
|
||||
//console.log(' -- mixin created -- ')
|
||||
this.loadData();
|
||||
//初始化字典配置 在自己页面定义
|
||||
this.initDictConfig();
|
||||
//初始化按钮权限
|
||||
this.initActiveBtnStr();
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.initScroll()
|
||||
},
|
||||
methods:{
|
||||
loadData(arg) {
|
||||
if(!this.url.list){
|
||||
this.$message.error("请设置url.list属性!")
|
||||
return
|
||||
}
|
||||
//加载数据 若传入参数1则加载第一页的内容
|
||||
if (arg === 1) {
|
||||
this.ipagination.current = 1;
|
||||
}
|
||||
var params = this.getQueryParams();//查询条件
|
||||
this.loading = true;
|
||||
getAction(this.url.list, params).then((res) => {
|
||||
if (res.code===200) {
|
||||
this.dataSource = res.data.rows;
|
||||
this.ipagination.total = Number(res.data.total);
|
||||
this.tableAddTotalRow(this.columns, this.dataSource)
|
||||
}
|
||||
if(res.code===510){
|
||||
this.$message.warning(res.data)
|
||||
}
|
||||
this.loading = false;
|
||||
})
|
||||
},
|
||||
initDictConfig(){
|
||||
//console.log("--这是一个假的方法!")
|
||||
},
|
||||
handleSuperQuery(params, matchType) {
|
||||
//高级查询方法
|
||||
if(!params){
|
||||
this.superQueryParams=''
|
||||
this.superQueryFlag = false
|
||||
}else{
|
||||
this.superQueryFlag = true
|
||||
this.superQueryParams=JSON.stringify(params)
|
||||
this.superQueryMatchType = matchType
|
||||
}
|
||||
this.loadData(1)
|
||||
},
|
||||
getQueryParams() {
|
||||
//获取查询条件
|
||||
let sqp = {}
|
||||
if(this.superQueryParams){
|
||||
sqp['superQueryParams']=encodeURI(this.superQueryParams)
|
||||
sqp['superQueryMatchType'] = this.superQueryMatchType
|
||||
}
|
||||
let searchObj = {}
|
||||
searchObj.search = JSON.stringify(this.queryParam);
|
||||
var param = Object.assign(sqp, searchObj, this.isorter ,this.filters);
|
||||
param.field = this.getQueryField();
|
||||
param.currentPage = this.ipagination.current;
|
||||
param.pageSize = this.ipagination.pageSize;
|
||||
return filterObj(param);
|
||||
},
|
||||
getQueryField() {
|
||||
var str = "id,";
|
||||
this.columns.forEach(function (value) {
|
||||
str += "," + value.dataIndex;
|
||||
});
|
||||
return str;
|
||||
},
|
||||
|
||||
onSelectChange(selectedRowKeys, selectionRows) {
|
||||
this.selectedRowKeys = selectedRowKeys;
|
||||
this.selectionRows = selectionRows;
|
||||
},
|
||||
onClearSelected() {
|
||||
this.selectedRowKeys = [];
|
||||
this.selectionRows = [];
|
||||
},
|
||||
searchQuery() {
|
||||
this.loadData(1);
|
||||
},
|
||||
superQuery() {
|
||||
this.$refs.superQueryModal.show();
|
||||
},
|
||||
searchReset() {
|
||||
this.queryParam = {}
|
||||
this.loadData(1);
|
||||
},
|
||||
batchSetStatus: function (status) {
|
||||
if(!this.url.batchSetStatusUrl){
|
||||
this.$message.error("请设置url.batchSetStatusUrl属性!")
|
||||
return
|
||||
}
|
||||
if (this.selectedRowKeys.length <= 0) {
|
||||
this.$message.warning('请选择一条记录!');
|
||||
return;
|
||||
} else {
|
||||
var ids = "";
|
||||
for (var a = 0; a < this.selectedRowKeys.length; a++) {
|
||||
ids += this.selectedRowKeys[a] + ",";
|
||||
}
|
||||
var that = this;
|
||||
this.$confirm({
|
||||
title: "确认操作",
|
||||
content: "是否操作选中数据?",
|
||||
onOk: function () {
|
||||
that.loading = true;
|
||||
postAction(that.url.batchSetStatusUrl, {status: status, ids: ids}).then((res) => {
|
||||
if(res.code === 200){
|
||||
that.loadData();
|
||||
that.onClearSelected();
|
||||
} else {
|
||||
that.$message.warning(res.msg);
|
||||
}
|
||||
}).finally(() => {
|
||||
that.loading = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
batchDel: function () {
|
||||
if(!this.url.deleteBatch){
|
||||
this.$message.error("请设置url.deleteBatch属性!")
|
||||
return
|
||||
}
|
||||
if (this.selectedRowKeys.length <= 0) {
|
||||
this.$message.warning('请选择一条记录!');
|
||||
return;
|
||||
} else {
|
||||
var ids = "";
|
||||
for (var a = 0; a < this.selectedRowKeys.length; a++) {
|
||||
ids += this.selectedRowKeys[a] + ",";
|
||||
}
|
||||
var that = this;
|
||||
this.$confirm({
|
||||
title: "确认删除",
|
||||
content: "是否删除选中数据?",
|
||||
onOk: function () {
|
||||
that.loading = true;
|
||||
deleteAction(that.url.deleteBatch, {ids: ids}).then((res) => {
|
||||
if(res.code === 200){
|
||||
that.loadData();
|
||||
that.onClearSelected();
|
||||
} else {
|
||||
that.$message.warning(res.msg);
|
||||
}
|
||||
}).finally(() => {
|
||||
that.loading = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
handleDelete: function (id) {
|
||||
if(!this.url.delete){
|
||||
this.$message.error("请设置url.delete属性!")
|
||||
return
|
||||
}
|
||||
var that = this;
|
||||
deleteAction(that.url.delete, {id: id}).then((res) => {
|
||||
if(res.code === 200){
|
||||
that.loadData();
|
||||
} else {
|
||||
that.$message.warning(res.msg);
|
||||
}
|
||||
});
|
||||
},
|
||||
handleEdit: function (record) {
|
||||
this.$refs.modalForm.edit(record);
|
||||
this.$refs.modalForm.title = "编辑";
|
||||
this.$refs.modalForm.disableSubmit = false;
|
||||
},
|
||||
handleAdd: function () {
|
||||
this.$refs.modalForm.add();
|
||||
this.$refs.modalForm.title = "新增";
|
||||
this.$refs.modalForm.disableSubmit = false;
|
||||
},
|
||||
handleTableChange(pagination, filters, sorter) {
|
||||
//分页、排序、筛选变化时触发
|
||||
if (Object.keys(sorter).length > 0) {
|
||||
this.isorter.column = sorter.field;
|
||||
this.isorter.order = "ascend" == sorter.order ? "asc" : "desc"
|
||||
}
|
||||
if(pagination && pagination.current) {
|
||||
this.ipagination = pagination;
|
||||
}
|
||||
this.loadData();
|
||||
},
|
||||
handleToggleSearch(){
|
||||
this.toggleSearchStatus = !this.toggleSearchStatus;
|
||||
},
|
||||
// 给popup查询使用(查询区域不支持回填多个字段,限制只返回一个字段)
|
||||
getPopupField(fields){
|
||||
return fields.split(',')[0]
|
||||
},
|
||||
modalFormOk() {
|
||||
// 新增/修改 成功时,重载列表
|
||||
this.loadData();
|
||||
},
|
||||
handleDetail:function(record, type){
|
||||
this.$refs.modalDetail.show(record, type);
|
||||
this.$refs.modalDetail.title=type+"-详情";
|
||||
},
|
||||
/* 导出 */
|
||||
handleExportXls2(){
|
||||
let paramsStr = encodeURI(JSON.stringify(this.getQueryParams()));
|
||||
let url = `${window._CONFIG['domianURL']}/${this.url.exportXlsUrl}?paramsStr=${paramsStr}`;
|
||||
window.location.href = url;
|
||||
},
|
||||
handleExportXls(fileName){
|
||||
if(!fileName || typeof fileName != "string"){
|
||||
fileName = "导出文件"
|
||||
}
|
||||
let param = {...this.queryParam};
|
||||
if(this.selectedRowKeys && this.selectedRowKeys.length>0){
|
||||
param['selections'] = this.selectedRowKeys.join(",")
|
||||
}
|
||||
console.log("导出参数",param)
|
||||
downFile(this.url.exportXlsUrl,param).then((data)=>{
|
||||
if (!data) {
|
||||
this.$message.warning("文件下载失败")
|
||||
return
|
||||
}
|
||||
if (typeof window.navigator.msSaveBlob !== 'undefined') {
|
||||
window.navigator.msSaveBlob(new Blob([data],{type: 'application/vnd.ms-excel'}), fileName+'.xls')
|
||||
}else{
|
||||
let url = window.URL.createObjectURL(new Blob([data],{type: 'application/vnd.ms-excel'}))
|
||||
let link = document.createElement('a')
|
||||
link.style.display = 'none'
|
||||
link.href = url
|
||||
link.setAttribute('download', fileName+'.xls')
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link); //下载完成移除元素
|
||||
window.URL.revokeObjectURL(url); //释放掉blob对象
|
||||
}
|
||||
})
|
||||
},
|
||||
/* 导入 */
|
||||
handleImportExcel(info){
|
||||
console.log(info,'info')
|
||||
if (info.file.status !== 'uploading') {
|
||||
console.log(info.file, info.fileList);
|
||||
}
|
||||
if (info.file.status === 'done') {
|
||||
if (info.file.response) {
|
||||
// this.$message.success(`${info.file.name} 文件上传成功`);
|
||||
if (info.file.response.code === 200) {
|
||||
this.$message.success(info.file.response.data || `${info.file.name} 文件上传成功`)
|
||||
} else {
|
||||
this.$message.warning(info.file.response.data)
|
||||
}
|
||||
this.loadData()
|
||||
} else {
|
||||
this.$message.error(`${info.file.name} ${info.file.response.data}.`);
|
||||
}
|
||||
} else if (info.file.status === 'error') {
|
||||
this.$message.error(`文件上传失败: ${info.file.msg} `);
|
||||
}
|
||||
},
|
||||
/* 图片预览 */
|
||||
getImgView(text){
|
||||
if(text && text.indexOf(",")>0){
|
||||
text = text.substring(0,text.indexOf(","))
|
||||
}
|
||||
return getFileAccessHttpUrl(text)
|
||||
},
|
||||
/* 文件下载 */
|
||||
uploadFile(text){
|
||||
if(!text){
|
||||
this.$message.warning("未知的文件")
|
||||
return;
|
||||
}
|
||||
if(text.indexOf(",")>0){
|
||||
text = text.substring(0,text.indexOf(","))
|
||||
}
|
||||
let url = getFileAccessHttpUrl(text)
|
||||
window.open(url);
|
||||
},
|
||||
/* 按钮权限 */
|
||||
initActiveBtnStr() {
|
||||
let funId = Vue.ls.get('funId'); //功能id
|
||||
let btnStrList = Vue.ls.get('winBtnStrList'); //按钮功能列表 JSON字符串
|
||||
this.btnEnableList = [1,2,3,4,5,,6,7]; //按钮列表
|
||||
if (funId && btnStrList) {
|
||||
for (let i = 0; i < btnStrList.length; i++) {
|
||||
if (btnStrList[i].funId == funId) {
|
||||
if (btnStrList[i].btnStr) {
|
||||
this.btnEnableList = btnStrList[i].btnStr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
/* 初始化表格横向或纵向滚动 */
|
||||
initScroll() {
|
||||
if (this.isMobile()) {
|
||||
this.scroll.y = ''
|
||||
} else {
|
||||
let basicLength = 274
|
||||
let searchWrapperDomLen=0, operatorDomLen=0
|
||||
//搜索区域
|
||||
let searchWrapperDom = document.getElementsByClassName('table-page-search-wrapper')
|
||||
//操作按钮区域
|
||||
let operatorDom = document.getElementsByClassName('table-operator')
|
||||
if(searchWrapperDom && searchWrapperDom[0]) {
|
||||
searchWrapperDomLen = searchWrapperDom[0].offsetHeight
|
||||
}
|
||||
if(operatorDom && operatorDom[0]) {
|
||||
operatorDomLen = operatorDom[0].offsetHeight+10
|
||||
}
|
||||
this.scroll.y = document.documentElement.clientHeight-searchWrapperDomLen-operatorDomLen-basicLength
|
||||
}
|
||||
},
|
||||
/** 表格增加合计行 */
|
||||
tableAddTotalRow(columns, dataSource) {
|
||||
if(dataSource.length>0 && this.ipagination.pageSize%10===1) {
|
||||
//分页条数为11、21、31等的时候增加合计行
|
||||
let numKey = 'rowIndex'
|
||||
let totalRow = { [numKey]: '合计' }
|
||||
//需要合计的列
|
||||
let parseCols = 'initialStock,currentStock,currentStockPrice,initialAmount,thisMonthAmount,currentAmount,inSum,inSumPrice,inOutSumPrice,' +
|
||||
'outSum,outSumPrice,outInSumPrice,operNumber,allPrice,numSum,priceSum,prevSum,thisSum,thisAllPrice,billMoney,changeAmount,' +
|
||||
'allPrice,currentNumber,lowSafeStock,highSafeStock,lowCritical,highCritical,initialPrice,intoPrice,intoStock,outPrice,outStock'
|
||||
columns.forEach(column => {
|
||||
let { key, dataIndex } = column
|
||||
if (![key, dataIndex].includes(numKey)) {
|
||||
let total = 0
|
||||
dataSource.forEach(data => {
|
||||
if(parseCols.indexOf(dataIndex)>-1) {
|
||||
if(data[dataIndex]) {
|
||||
total += Number.parseFloat(data[dataIndex])
|
||||
} else {
|
||||
total += 0
|
||||
}
|
||||
} else {
|
||||
total = '-'
|
||||
}
|
||||
})
|
||||
if (total !== '-') {
|
||||
total = total.toFixed(2)
|
||||
}
|
||||
totalRow[dataIndex] = total
|
||||
}
|
||||
})
|
||||
dataSource.push(totalRow)
|
||||
//总数要增加合计的行数,每页都有一行合计,所以总数要加上
|
||||
let size = Math.ceil(this.ipagination.total/(this.ipagination.pageSize-1))
|
||||
this.ipagination.total = this.ipagination.total + size
|
||||
}
|
||||
},
|
||||
paginationChange(page, pageSize) {
|
||||
this.ipagination.current = page
|
||||
this.ipagination.pageSize = pageSize
|
||||
this.loadData(this.ipagination.current);
|
||||
},
|
||||
paginationShowSizeChange(current, size) {
|
||||
this.ipagination.current = current
|
||||
this.ipagination.pageSize = size
|
||||
this.loadData(this.ipagination.current);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
//mixins/tableDragResize.js
|
||||
import Vue from 'vue'
|
||||
import VueDraggableResizable from 'vue-draggable-resizable'
|
||||
Vue.component('vue-draggable-resizable', VueDraggableResizable)
|
||||
/**
|
||||
* @param { 表格columns } tbCols
|
||||
*/
|
||||
function initDrag(tbCols) {
|
||||
const draggingMap = {}
|
||||
tbCols.forEach((col) => {
|
||||
const key = col.dataIndex || col.key//这儿要求表格数据中要有这两个属性
|
||||
draggingMap[key] = col.width || 0
|
||||
})
|
||||
const draggingState = Vue.observable(draggingMap)
|
||||
return (h, props, children) => {
|
||||
let thDom = null
|
||||
const { key, ...restProps } = props
|
||||
let col
|
||||
if (key === 'selection-column') {
|
||||
//表格加了复选框,不加这个判断col会是undefided
|
||||
col = {}
|
||||
} else {
|
||||
col = tbCols.find((item) => {
|
||||
const k = item.dataIndex || item.key
|
||||
return k === key
|
||||
})
|
||||
}
|
||||
if (!col.width) {//这儿要求表格数据中要有宽width属性,若是没有是不会执行下面的拖拽的
|
||||
return <th {...restProps}>{children}</th>
|
||||
}
|
||||
|
||||
const onDrag = (x) => {
|
||||
draggingState[key] = 0
|
||||
col.width = Math.max(x, 1)
|
||||
}
|
||||
const onDragstop = () => {
|
||||
draggingState[key] = thDom.getBoundingClientRect().width
|
||||
}
|
||||
|
||||
return (
|
||||
<th
|
||||
{...restProps}
|
||||
v-ant-ref={(r) => {
|
||||
thDom = r
|
||||
}}
|
||||
width={draggingState[key]}
|
||||
class="resize-table-th"
|
||||
>
|
||||
{children}
|
||||
<vue-draggable-resizable
|
||||
key={col.dataIndex || col.key}
|
||||
class="table-draggable-handle"
|
||||
w={10}
|
||||
x={col.width || draggingState[key]}
|
||||
z={1}
|
||||
axis="x"
|
||||
draggable={true}
|
||||
resizable={false}
|
||||
onDragging={onDrag}
|
||||
onDragstop={onDragstop}
|
||||
></vue-draggable-resizable>
|
||||
</th>
|
||||
)
|
||||
}
|
||||
}
|
||||
export default {
|
||||
methods: {
|
||||
/**
|
||||
* https://github.com/mauricius/vue-draggable-resizable
|
||||
* 表格列可拖拽
|
||||
* 表格上使用::components="drag(columns)"
|
||||
* tips:columns中需包含dataIndex或者key和width(Number)
|
||||
*/
|
||||
drag(columns) {
|
||||
return {
|
||||
header: {
|
||||
cell: initDrag(columns),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
const FormTypes = {
|
||||
normal: 'normal',
|
||||
input: 'input',
|
||||
inputNumber: 'inputNumber',
|
||||
checkbox: 'checkbox',
|
||||
select: 'select',
|
||||
date: 'date',
|
||||
datetime: 'datetime',
|
||||
upload: 'upload',
|
||||
file: 'file',
|
||||
image: 'image',
|
||||
popup:'popup',
|
||||
popupJsh:'popupJsh',
|
||||
list_multi:"list_multi",
|
||||
sel_search:"sel_search",
|
||||
radio:'radio',
|
||||
checkbox_meta:"checkbox_meta",
|
||||
input_pop:'input_pop',
|
||||
slot: 'slot',
|
||||
hidden: 'hidden'
|
||||
}
|
||||
const VALIDATE_NO_PASSED = Symbol()
|
||||
export { FormTypes, VALIDATE_NO_PASSED }
|
||||
|
||||
/**
|
||||
* 获取指定的 $refs 对象
|
||||
* 有时候可能会遇到组件未挂载到页面中的情况,导致无法获取 $refs 中的某个对象
|
||||
* 这个方法可以等待挂载完成之后再返回 $refs 的对象,避免报错
|
||||
* @author sunjianlei
|
||||
**/
|
||||
export function getRefPromise(vm, name) {
|
||||
return new Promise((resolve) => {
|
||||
(function next() {
|
||||
let ref = vm.$refs[name]
|
||||
if (ref) {
|
||||
resolve(ref)
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
next()
|
||||
}, 10)
|
||||
}
|
||||
})()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 一次性验证主表单和所有的次表单
|
||||
* @param form 主表单 form 对象
|
||||
* @param cases 接收一个数组,每项都是一个JEditableTable实例
|
||||
* @returns {Promise<any>}
|
||||
* @author sunjianlei
|
||||
*/
|
||||
export function validateFormAndTables(form, cases) {
|
||||
|
||||
if (!(form && typeof form.validateFields === 'function')) {
|
||||
throw `form 参数需要的是一个form对象,而传入的却是${typeof form}`
|
||||
}
|
||||
|
||||
let options = {}
|
||||
return new Promise((resolve, reject) => {
|
||||
// 验证主表表单
|
||||
form.validateFields((err, values) => {
|
||||
err ? reject({ error: VALIDATE_NO_PASSED }) : resolve(values)
|
||||
})
|
||||
}).then(values => {
|
||||
Object.assign(options, { formValue: values })
|
||||
// 验证所有子表的表单
|
||||
return validateTables(cases)
|
||||
}).then(all => {
|
||||
Object.assign(options, { tablesValue: all })
|
||||
return Promise.resolve(options)
|
||||
}).catch(error => {
|
||||
return Promise.reject(error)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证并获取一个或多个表格的所有值
|
||||
* @param cases 接收一个数组,每项都是一个JEditableTable实例
|
||||
* @param deleteTempId 是否删除临时ID,如果设为true,行编辑就不返回新增行的ID,ID需要后台生成
|
||||
* @author sunjianlei
|
||||
*/
|
||||
export function validateTables(cases, deleteTempId) {
|
||||
if (!(cases instanceof Array)) {
|
||||
throw `'validateTables'函数的'cases'参数需要的是一个数组,而传入的却是${typeof cases}`
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
let tables = []
|
||||
let index = 0;
|
||||
if(!cases || cases.length==0){
|
||||
resolve()
|
||||
}
|
||||
(function next() {
|
||||
let vm = cases[index]
|
||||
vm.getAll(true, deleteTempId).then(all => {
|
||||
tables[index] = all
|
||||
// 判断校验是否全部完成,完成返回成功,否则继续进行下一步校验
|
||||
if (++index === cases.length) {
|
||||
resolve(tables)
|
||||
} else (
|
||||
next()
|
||||
)
|
||||
}, error => {
|
||||
// 出现未验证通过的表单,不再进行下一步校验,直接返回失败并跳转到该表格
|
||||
if (error === VALIDATE_NO_PASSED) {
|
||||
reject({ error: VALIDATE_NO_PASSED, index })
|
||||
}
|
||||
reject(error)
|
||||
})
|
||||
})()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 一次性验证主表单和所有的次表单-只校验单号
|
||||
* @param form 主表单 form 对象
|
||||
* @param cases 接收一个数组,每项都是一个JEditableTable实例
|
||||
* @returns {Promise<any>}
|
||||
* @author sunjianlei
|
||||
*/
|
||||
export function getListData(form, cases) {
|
||||
let options = {}
|
||||
return new Promise((resolve, reject) => {
|
||||
// 验证主表表单
|
||||
form.validateFields(['number'],(err, values) => {
|
||||
err ? reject({ error: VALIDATE_NO_PASSED }) : resolve(values)
|
||||
})
|
||||
}).then(values => {
|
||||
Object.assign(options, { formValue: values })
|
||||
// 验证所有子表的表单
|
||||
return getListTables(cases)
|
||||
}).then(all => {
|
||||
Object.assign(options, { tablesValue: all })
|
||||
return Promise.resolve(options)
|
||||
}).catch(error => {
|
||||
return Promise.reject(error)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 不验证直接获取一个或多个表格的所有值
|
||||
* @param cases 接收一个数组,每项都是一个JEditableTable实例
|
||||
* @param deleteTempId 是否删除临时ID,如果设为true,行编辑就不返回新增行的ID,ID需要后台生成
|
||||
* @author sunjianlei
|
||||
*/
|
||||
export function getListTables(cases, deleteTempId) {
|
||||
if (!(cases instanceof Array)) {
|
||||
throw `'validateTables'函数的'cases'参数需要的是一个数组,而传入的却是${typeof cases}`
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
let tables = []
|
||||
let index = 0;
|
||||
if(!cases || cases.length==0){
|
||||
resolve()
|
||||
}
|
||||
(function next() {
|
||||
let vm = cases[index]
|
||||
vm.getAll(false, deleteTempId).then(all => {
|
||||
tables[index] = all
|
||||
// 判断校验是否全部完成,完成返回成功,否则继续进行下一步校验
|
||||
if (++index === cases.length) {
|
||||
resolve(tables)
|
||||
} else (
|
||||
next()
|
||||
)
|
||||
}, error => {
|
||||
// 出现未验证通过的表单,不再进行下一步校验,直接返回失败并跳转到该表格
|
||||
if (error === VALIDATE_NO_PASSED) {
|
||||
reject({ error: VALIDATE_NO_PASSED, index })
|
||||
}
|
||||
reject(error)
|
||||
})
|
||||
})()
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// import Vue from 'vue'
|
||||
import { mapState } from "vuex";
|
||||
|
||||
// const mixinsComputed = Vue.config.optionMergeStrategies.computed
|
||||
// const mixinsMethods = Vue.config.optionMergeStrategies.methods
|
||||
|
||||
const mixin = {
|
||||
computed: {
|
||||
...mapState({
|
||||
layoutMode: state => state.app.layout,
|
||||
navTheme: state => state.app.theme,
|
||||
primaryColor: state => state.app.color,
|
||||
colorWeak: state => state.app.weak,
|
||||
multipage: state => state.app.multipage,//多页签设置
|
||||
fixedHeader: state => state.app.fixedHeader,
|
||||
fixSiderbar: state => state.app.fixSiderbar,
|
||||
contentWidth: state => state.app.contentWidth,
|
||||
autoHideHeader: state => state.app.autoHideHeader,
|
||||
sidebarOpened: state => state.app.sidebar.opened
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const mixinDevice = {
|
||||
computed: {
|
||||
...mapState({
|
||||
device: state => state.app.device,
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
isMobile () {
|
||||
return this.device === 'mobile'
|
||||
},
|
||||
isDesktop () {
|
||||
return this.device === 'desktop'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { mixin, mixinDevice }
|
||||
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* 该文件截取自 "ant-design-vue/es/_util/props-util.js" 文件,并对其做出特殊修改
|
||||
*/
|
||||
function classNames() {
|
||||
let classes = []
|
||||
|
||||
for (let i = 0; i < arguments.length; i++) {
|
||||
let arg = arguments[i]
|
||||
if (!arg) continue
|
||||
|
||||
let argType = typeof arg
|
||||
|
||||
if (argType === 'string' || argType === 'number') {
|
||||
classes.push(arg)
|
||||
} else if (Array.isArray(arg) && arg.length) {
|
||||
let inner = classNames.apply(null, arg)
|
||||
if (inner) {
|
||||
classes.push(inner)
|
||||
}
|
||||
} else if (argType === 'object') {
|
||||
for (let key in arg) {
|
||||
if (arg.hasOwnProperty(key) && arg[key]) {
|
||||
classes.push(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return classes.join(' ')
|
||||
}
|
||||
|
||||
const camelizeRE = /-(\w)/g
|
||||
|
||||
function camelize(str) {
|
||||
return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''))
|
||||
}
|
||||
|
||||
|
||||
function objectCamelize(obj) {
|
||||
let res = {}
|
||||
Object.keys(obj).forEach(k => (res[camelize(k)] = obj[k]))
|
||||
return res
|
||||
}
|
||||
|
||||
function parseStyleText(cssText = '', camel) {
|
||||
const res = {}
|
||||
const listDelimiter = /;(?![^(]*\))/g
|
||||
const propertyDelimiter = /:(.+)/
|
||||
cssText.split(listDelimiter).forEach(function (item) {
|
||||
if (item) {
|
||||
const tmp = item.split(propertyDelimiter)
|
||||
if (tmp.length > 1) {
|
||||
const k = camel ? camelize(tmp[0].trim()) : tmp[0].trim()
|
||||
res[k] = tmp[1].trim()
|
||||
}
|
||||
}
|
||||
})
|
||||
return res
|
||||
}
|
||||
|
||||
export function getClass(ele) {
|
||||
let data = {}
|
||||
if (ele.data) {
|
||||
data = ele.data
|
||||
} else if (ele.$vnode && ele.$vnode.data) {
|
||||
data = ele.$vnode.data
|
||||
}
|
||||
const tempCls = data.class || {}
|
||||
const staticClass = data.staticClass
|
||||
let cls = {}
|
||||
staticClass &&
|
||||
staticClass.split(' ').forEach(c => {
|
||||
cls[c.trim()] = true
|
||||
})
|
||||
if (typeof tempCls === 'string') {
|
||||
tempCls.split(' ').forEach(c => {
|
||||
cls[c.trim()] = true
|
||||
})
|
||||
} else if (Array.isArray(tempCls)) {
|
||||
classNames(tempCls)
|
||||
.split(' ')
|
||||
.forEach(c => {
|
||||
cls[c.trim()] = true
|
||||
})
|
||||
} else {
|
||||
cls = { ...cls, ...tempCls }
|
||||
}
|
||||
return cls
|
||||
}
|
||||
|
||||
export function getStyle(ele, camel) {
|
||||
|
||||
getClass(ele)
|
||||
|
||||
let data = {}
|
||||
if (ele.data) {
|
||||
data = ele.data
|
||||
} else if (ele.$vnode && ele.$vnode.data) {
|
||||
data = ele.$vnode.data
|
||||
}
|
||||
|
||||
// update-begin-author:sunjianlei date:20200303 for: style 和 staticStyle 可以共存
|
||||
let style = data.style || {}
|
||||
let staticStyle = data.staticStyle
|
||||
staticStyle = staticStyle ? objectCamelize(data.staticStyle) : {}
|
||||
// update-end-author:sunjianlei date:20200303 for: style 和 staticStyle 可以共存
|
||||
|
||||
if (typeof style === 'string') {
|
||||
style = parseStyleText(style, camel)
|
||||
} else if (camel && style) {
|
||||
// 驼峰化
|
||||
style = objectCamelize(style)
|
||||
}
|
||||
return { ...staticStyle, ...style }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,669 @@
|
||||
import api from '@/api/api'
|
||||
import isURL from '@/utils/validate'
|
||||
import XLSX from 'xlsx'
|
||||
|
||||
export function timeFix() {
|
||||
const time = new Date()
|
||||
const hour = time.getHours()
|
||||
return hour < 9 ? '早上好' : (hour <= 11 ? '上午好' : (hour <= 13 ? '中午好' : (hour < 20 ? '下午好' : '晚上好')))
|
||||
}
|
||||
|
||||
export function welcome() {
|
||||
const arr = ['休息一会儿吧', '准备吃什么呢?', '要不要打一把 DOTA', '我猜你可能累了']
|
||||
let index = Math.floor((Math.random()*arr.length))
|
||||
return arr[index]
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发 window.resize
|
||||
*/
|
||||
export function triggerWindowResizeEvent() {
|
||||
let event = document.createEvent('HTMLEvents')
|
||||
event.initEvent('resize', true, true)
|
||||
event.eventType = 'message'
|
||||
window.dispatchEvent(event)
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤对象中为空的属性
|
||||
* @param obj
|
||||
* @returns {*}
|
||||
*/
|
||||
export function filterObj(obj) {
|
||||
if (!(typeof obj == 'object')) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( let key in obj) {
|
||||
if (obj.hasOwnProperty(key)
|
||||
&& (obj[key] == null || obj[key] == undefined || obj[key] === '')) {
|
||||
delete obj[key];
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 时间格式化
|
||||
* @param value
|
||||
* @param fmt
|
||||
* @returns {*}
|
||||
*/
|
||||
export function formatDate(value, fmt) {
|
||||
let regPos = /^\d+(\.\d+)?$/;
|
||||
if(regPos.test(value)){
|
||||
//如果是数字
|
||||
let getDate = new Date(value);
|
||||
let o = {
|
||||
'M+': getDate.getMonth() + 1,
|
||||
'd+': getDate.getDate(),
|
||||
'h+': getDate.getHours(),
|
||||
'm+': getDate.getMinutes(),
|
||||
's+': getDate.getSeconds(),
|
||||
'q+': Math.floor((getDate.getMonth() + 3) / 3),
|
||||
'S': getDate.getMilliseconds()
|
||||
};
|
||||
if (/(y+)/.test(fmt)) {
|
||||
fmt = fmt.replace(RegExp.$1, (getDate.getFullYear() + '').substr(4 - RegExp.$1.length))
|
||||
}
|
||||
for (let k in o) {
|
||||
if (new RegExp('(' + k + ')').test(fmt)) {
|
||||
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
|
||||
}
|
||||
}
|
||||
return fmt;
|
||||
}else{
|
||||
//TODO
|
||||
value = value.trim();
|
||||
return value.substr(0,fmt.length);
|
||||
}
|
||||
}
|
||||
|
||||
// 生成首页路由
|
||||
|
||||
|
||||
// 生成嵌套路由(子路由)
|
||||
|
||||
function generateChildRouters (data) {
|
||||
const routers = [];
|
||||
for (let item of data) {
|
||||
let componentPath = "";
|
||||
item.route = "1";
|
||||
if(item.component.indexOf("layouts")>=0){
|
||||
componentPath = () => import('@/components'+item.component);
|
||||
} else {
|
||||
componentPath = () => import('@/views'+item.component);
|
||||
}
|
||||
// eslint-disable-next-line
|
||||
let URL = (item.url|| '').replace(/{{([^}}]+)?}}/g, (s1, s2) => eval(s2)) // URL支持{{ window.xxx }}占位符变量
|
||||
if (isURL(URL)) {
|
||||
item.url = URL;
|
||||
}
|
||||
let componentName =''
|
||||
if(item.component) {
|
||||
let index = item.component.lastIndexOf("\/");
|
||||
componentName = item.component.substring(index + 1, item.component.length);
|
||||
}
|
||||
let menu = {
|
||||
path: item.url,
|
||||
name: item.text,
|
||||
component: componentPath,
|
||||
meta: {
|
||||
id: item.id,
|
||||
title: item.text,
|
||||
icon: item.icon,
|
||||
url: item.url,
|
||||
componentName:componentName,
|
||||
internalOrExternal:true,
|
||||
keepAlive: true
|
||||
// permissionList:""
|
||||
}
|
||||
}
|
||||
if (item.children && item.children.length > 0) {
|
||||
menu.children = [...generateChildRouters( item.children)];
|
||||
}
|
||||
//--update-begin----author:scott---date:20190320------for:根据后台菜单配置,判断是否路由菜单字段,动态选择是否生成路由(为了支持参数URL菜单)------
|
||||
//判断是否生成路由
|
||||
if(item.route && item.route === '0'){
|
||||
//console.log(' 不生成路由 item.route: '+item.route);
|
||||
//console.log(' 不生成路由 item.path: '+item.path);
|
||||
}else{
|
||||
routers.push(menu);
|
||||
}
|
||||
//--update-end----author:scott---date:20190320------for:根据后台菜单配置,判断是否路由菜单字段,动态选择是否生成路由(为了支持参数URL菜单)------
|
||||
}
|
||||
return routers
|
||||
}
|
||||
|
||||
/**
|
||||
* 深度克隆对象、数组
|
||||
* @param obj 被克隆的对象
|
||||
* @return 克隆后的对象
|
||||
*/
|
||||
export function cloneObject(obj) {
|
||||
return JSON.parse(JSON.stringify(obj))
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机生成数字
|
||||
*
|
||||
* 示例:生成长度为 12 的随机数:randomNumber(12)
|
||||
* 示例:生成 3~23 之间的随机数:randomNumber(3, 23)
|
||||
*
|
||||
* @param1 最小值 | 长度
|
||||
* @param2 最大值
|
||||
* @return int 生成后的数字
|
||||
*/
|
||||
export function randomNumber() {
|
||||
// 生成 最小值 到 最大值 区间的随机数
|
||||
const random = (min, max) => {
|
||||
return Math.floor(Math.random() * (max - min + 1) + min)
|
||||
}
|
||||
if (arguments.length === 1) {
|
||||
let [length] = arguments
|
||||
// 生成指定长度的随机数字,首位一定不是 0
|
||||
let nums = [...Array(length).keys()].map((i) => (i > 0 ? random(0, 9) : random(1, 9)))
|
||||
return parseInt(nums.join(''))
|
||||
} else if (arguments.length >= 2) {
|
||||
let [min, max] = arguments
|
||||
return random(min, max)
|
||||
} else {
|
||||
return Number.NaN
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机生成字符串
|
||||
* @param length 字符串的长度
|
||||
* @param chats 可选字符串区间(只会生成传入的字符串中的字符)
|
||||
* @return string 生成的字符串
|
||||
*/
|
||||
export function randomString(length, chats) {
|
||||
if (!length) length = 1
|
||||
if (!chats) chats = '0123456789qwertyuioplkjhgfdsazxcvbnm'
|
||||
let str = ''
|
||||
for (let i = 0; i < length; i++) {
|
||||
let num = randomNumber(0, chats.length - 1)
|
||||
str += chats[num]
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机生成uuid
|
||||
* @return string 生成的uuid
|
||||
*/
|
||||
export function randomUUID() {
|
||||
let chats = '0123456789abcdef'
|
||||
return randomString(32, chats)
|
||||
}
|
||||
|
||||
/**
|
||||
* 下划线转驼峰
|
||||
* @param string
|
||||
* @returns {*}
|
||||
*/
|
||||
export function underLine2CamelCase(string){
|
||||
return string.replace( /_([a-z])/g, function( all, letter ) {
|
||||
return letter.toUpperCase();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否显示办理按钮
|
||||
* @param bpmStatus
|
||||
* @returns {*}
|
||||
*/
|
||||
export function showDealBtn(bpmStatus){
|
||||
if(bpmStatus!="1"&&bpmStatus!="3"&&bpmStatus!="4"){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 增强CSS,可以在页面上输出全局css
|
||||
* @param css 要增强的css
|
||||
* @param id style标签的id,可以用来清除旧样式
|
||||
*/
|
||||
export function cssExpand(css, id) {
|
||||
let style = document.createElement('style')
|
||||
style.type = "text/css"
|
||||
style.innerHTML = `@charset "UTF-8"; ${css}`
|
||||
// 清除旧样式
|
||||
if (id) {
|
||||
let $style = document.getElementById(id)
|
||||
if ($style != null) $style.outerHTML = ''
|
||||
style.id = id
|
||||
}
|
||||
// 应用新样式
|
||||
document.head.appendChild(style)
|
||||
}
|
||||
|
||||
|
||||
/** 用于js增强事件,运行JS代码,可以传参 */
|
||||
// options 所需参数:
|
||||
// 参数名 类型 说明
|
||||
// vm VueComponent vue实例
|
||||
// event Object event对象
|
||||
// jsCode String 待执行的js代码
|
||||
// errorMessage String 执行出错后的提示(控制台)
|
||||
export function jsExpand(options = {}) {
|
||||
|
||||
// 绑定到window上的keyName
|
||||
let windowKeyName = 'J_CLICK_EVENT_OPTIONS'
|
||||
if (typeof window[windowKeyName] != 'object') {
|
||||
window[windowKeyName] = {}
|
||||
}
|
||||
|
||||
// 随机生成JS增强的执行id,防止冲突
|
||||
let id = randomString(16, 'qwertyuioplkjhgfdsazxcvbnm'.toUpperCase())
|
||||
// 封装按钮点击事件
|
||||
let code = `
|
||||
(function (o_${id}) {
|
||||
try {
|
||||
(function (globalEvent, vm) {
|
||||
${options.jsCode}
|
||||
})(o_${id}.event, o_${id}.vm)
|
||||
} catch (e) {
|
||||
o_${id}.error(e)
|
||||
}
|
||||
o_${id}.done()
|
||||
})(window['${windowKeyName}']['EVENT_${id}'])
|
||||
`
|
||||
// 创建script标签
|
||||
const script = document.createElement('script')
|
||||
// 将需要传递的参数挂载到window对象上
|
||||
window[windowKeyName]['EVENT_' + id] = {
|
||||
vm: options.vm,
|
||||
event: options.event,
|
||||
// 当执行完成时,无论如何都会调用的回调事件
|
||||
done() {
|
||||
// 执行完后删除新增的 script 标签不会撤销执行结果(已产生的结果不会被撤销)
|
||||
script.outerHTML = ''
|
||||
delete window[windowKeyName]['EVENT_' + id]
|
||||
},
|
||||
// 当js运行出错的时候调用的事件
|
||||
error(e) {
|
||||
console.group(`${options.errorMessage || '用户自定义JS增强代码运行出错'}(${new Date()})`)
|
||||
console.error(e)
|
||||
console.groupEnd()
|
||||
}
|
||||
}
|
||||
// 将事件挂载到document中
|
||||
script.innerHTML = code
|
||||
document.body.appendChild(script)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 重复值验证工具方法
|
||||
*
|
||||
* 使用示例:
|
||||
* { validator: (rule, value, callback) => validateDuplicateValue('sys_fill_rule', 'rule_code', value, this.model.id, callback) }
|
||||
*
|
||||
* @param tableName 被验证的表名
|
||||
* @param fieldName 被验证的字段名
|
||||
* @param fieldVal 被验证的值
|
||||
* @param dataId 数据ID,可空
|
||||
* @param callback
|
||||
*/
|
||||
export function validateDuplicateValue(tableName, fieldName, fieldVal, dataId, callback) {
|
||||
if (fieldVal) {
|
||||
let params = { tableName, fieldName, fieldVal, dataId }
|
||||
api.duplicateCheck(params).then(res => {
|
||||
res['success'] ? callback() : callback(res['message'])
|
||||
}).catch(err => {
|
||||
callback(err.message || err)
|
||||
})
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据编码校验规则code,校验传入的值是否合法
|
||||
*
|
||||
* 使用示例:
|
||||
* { validator: (rule, value, callback) => validateCheckRule('common', value, callback) }
|
||||
*
|
||||
* @param ruleCode 编码校验规则 code
|
||||
* @param value 被验证的值
|
||||
* @param callback
|
||||
*/
|
||||
export function validateCheckRule(ruleCode, value, callback) {
|
||||
if (ruleCode && value) {
|
||||
value = encodeURIComponent(value)
|
||||
api.checkRuleByCode({ ruleCode, value }).then(res => {
|
||||
res['success'] ? callback() : callback(res['message'])
|
||||
}).catch(err => {
|
||||
callback(err.message || err)
|
||||
})
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果值不存在就 push 进数组,反之不处理
|
||||
* @param array 要操作的数据
|
||||
* @param value 要添加的值
|
||||
* @param key 可空,如果比较的是对象,可能存在地址不一样但值实际上是一样的情况,可以传此字段判断对象中唯一的字段,例如 id。不传则直接比较实际值
|
||||
* @returns {boolean} 成功 push 返回 true,不处理返回 false
|
||||
*/
|
||||
export function pushIfNotExist(array, value, key) {
|
||||
for (let item of array) {
|
||||
if (key && (item[key] === value[key])) {
|
||||
return false
|
||||
} else if (item === value) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
array.push(value)
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* 可用于判断是否成功
|
||||
* @type {symbol}
|
||||
*/
|
||||
export const succeedSymbol = Symbol()
|
||||
/**
|
||||
* 可用于判断是否失败
|
||||
* @type {symbol}
|
||||
*/
|
||||
export const failedSymbol = Symbol()
|
||||
|
||||
/**
|
||||
* 使 promise 无论如何都会 resolve,除非传入的参数不是一个Promise对象或返回Promise对象的方法
|
||||
* 一般用在 Promise.all 中
|
||||
*
|
||||
* @param promise 可传Promise对象或返回Promise对象的方法
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
export function alwaysResolve(promise) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let p = promise
|
||||
if (typeof promise === 'function') {
|
||||
p = promise()
|
||||
}
|
||||
if (p instanceof Promise) {
|
||||
p.then(data => {
|
||||
resolve({ type: succeedSymbol, data })
|
||||
}).catch(error => {
|
||||
resolve({ type: failedSymbol, error })
|
||||
})
|
||||
} else {
|
||||
reject('alwaysResolve: 传入的参数不是一个Promise对象或返回Promise对象的方法')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 简单实现防抖方法
|
||||
*
|
||||
* 防抖(debounce)函数在第一次触发给定的函数时,不立即执行函数,而是给出一个期限值(delay),比如100ms。
|
||||
* 如果100ms内再次执行函数,就重新开始计时,直到计时结束后再真正执行函数。
|
||||
* 这样做的好处是如果短时间内大量触发同一事件,只会执行一次函数。
|
||||
*
|
||||
* @param fn 要防抖的函数
|
||||
* @param delay 防抖的毫秒数
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function simpleDebounce(fn, delay = 100) {
|
||||
let timer = null
|
||||
return function () {
|
||||
let args = arguments
|
||||
if (timer) {
|
||||
clearTimeout(timer)
|
||||
}
|
||||
timer = setTimeout(() => {
|
||||
fn.apply(null, args)
|
||||
}, delay)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 不用正则的方式替换所有值
|
||||
* @param text 被替换的字符串
|
||||
* @param checker 替换前的内容
|
||||
* @param replacer 替换后的内容
|
||||
* @returns {String} 替换后的字符串
|
||||
*/
|
||||
export function replaceAll(text, checker, replacer) {
|
||||
let lastText = text
|
||||
text = text.replace(checker, replacer)
|
||||
if (lastText !== text) {
|
||||
return replaceAll(text, checker, replacer)
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换商品扩展字段的格式
|
||||
* @param thisRows
|
||||
* @param checker
|
||||
* @param replacer
|
||||
* @returns {string}
|
||||
*/
|
||||
export function getMpListShort(thisRows, checker, replacer) {
|
||||
let mPropertyListShort = ''
|
||||
let nativeNameStr = ''
|
||||
for (let i = 0; i < thisRows.length; i++) {
|
||||
if (thisRows[i].enabled) {
|
||||
nativeNameStr += thisRows[i].nativeName + ",";
|
||||
}
|
||||
}
|
||||
if (nativeNameStr) {
|
||||
mPropertyListShort = nativeNameStr.substring(0, nativeNameStr.length - 1);
|
||||
}
|
||||
return mPropertyListShort
|
||||
}
|
||||
|
||||
/**
|
||||
* js获取当前月份, 格式“yyyy-MM”
|
||||
*/
|
||||
export function getNowFormatMonth() {
|
||||
var date = new Date();
|
||||
var seperator1 = "-";
|
||||
var month = date.getMonth() + 1;
|
||||
if (month >= 1 && month <= 9) {
|
||||
month = "0" + month;
|
||||
}
|
||||
var currentdate = date.getFullYear() + seperator1 + month;
|
||||
return currentdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* js获取当前日期, 格式“yyyy-MM-dd”
|
||||
*/
|
||||
export function getFormatDate() {
|
||||
var date = new Date();
|
||||
var seperator1 = "-";
|
||||
var year = date.getFullYear();
|
||||
var month = date.getMonth() + 1;
|
||||
var strDate = date.getDate();
|
||||
if (month >= 1 && month <= 9) {
|
||||
month = "0" + month;
|
||||
}
|
||||
if (strDate >= 0 && strDate <= 9) {
|
||||
strDate = "0" + strDate;
|
||||
}
|
||||
var currentdate = year + seperator1 + month + seperator1 + strDate;
|
||||
return currentdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* js获取当前时间, 格式“yyyy-MM-dd HH:MM:SS”
|
||||
*/
|
||||
export function getNowFormatDateTime() {
|
||||
var date = new Date();
|
||||
var seperator1 = "-";
|
||||
var seperator2 = ":";
|
||||
var month = date.getMonth() + 1;
|
||||
var strDate = date.getDate();
|
||||
var strHours = date.getHours();
|
||||
var strMinutes = date.getMinutes();
|
||||
var strSeconds = date.getSeconds();
|
||||
if (month >= 1 && month <= 9) {
|
||||
month = "0" + month;
|
||||
}
|
||||
if (strDate >= 0 && strDate <= 9) {
|
||||
strDate = "0" + strDate;
|
||||
}
|
||||
if (strHours >= 0 && strHours <= 9) {
|
||||
strHours = "0" + strHours;
|
||||
}
|
||||
if (strMinutes >= 0 && strMinutes <= 9) {
|
||||
strMinutes = "0" + strMinutes;
|
||||
}
|
||||
if (strSeconds >= 0 && strSeconds <= 9) {
|
||||
strSeconds = "0" + strSeconds;
|
||||
}
|
||||
var currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate
|
||||
+ " " + strHours + seperator2 + strMinutes
|
||||
+ seperator2 + strSeconds;
|
||||
return currentdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* js获取当前时间, 格式“MMddHHMMSS”
|
||||
*/
|
||||
export function getNowFormatStr() {
|
||||
var date = new Date();
|
||||
var month = date.getMonth() + 1;
|
||||
var strDate = date.getDate();
|
||||
var strHours = date.getHours();
|
||||
var strMinutes = date.getMinutes();
|
||||
var strSeconds = date.getSeconds();
|
||||
if (month >= 1 && month <= 9) {
|
||||
month = "0" + month;
|
||||
}
|
||||
if (strDate >= 0 && strDate <= 9) {
|
||||
strDate = "0" + strDate;
|
||||
}
|
||||
if (strHours >= 0 && strHours <= 9) {
|
||||
strHours = "0" + strHours;
|
||||
}
|
||||
if (strMinutes >= 0 && strMinutes <= 9) {
|
||||
strMinutes = "0" + strMinutes;
|
||||
}
|
||||
if (strSeconds >= 0 && strSeconds <= 9) {
|
||||
strSeconds = "0" + strSeconds;
|
||||
}
|
||||
var currentdate = month + strDate + strHours + strMinutes + strSeconds;
|
||||
console.log(currentdate,'currentdate')
|
||||
return currentdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* JS中根据指定值删除数组中的元素
|
||||
* @param arrylist
|
||||
* @param val
|
||||
*/
|
||||
export function removeByVal(arrylist, val) {
|
||||
for(var i = 0; i < arrylist .length; i++) {
|
||||
if(arrylist [i] == val) {
|
||||
arrylist .splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数组单个金额中的数值转为负数
|
||||
* @param arr
|
||||
* @returns {Array}
|
||||
*/
|
||||
export function changeListFmtMinus(arr) {
|
||||
var newArr = new Array();
|
||||
for(var i=0; i<arr.length; i++) {
|
||||
if(arr[i] < 0){
|
||||
newArr.push((arr[i]-0).toString());
|
||||
}
|
||||
else {
|
||||
newArr.push((0 - arr[i]).toString());
|
||||
}
|
||||
}
|
||||
return newArr;
|
||||
}
|
||||
|
||||
/**
|
||||
通用的打开下载对话框方法,没有测试过具体兼容性
|
||||
@param url 下载地址,也可以是一个blob对象,必选
|
||||
@param saveName 保存文件名,可选
|
||||
*/
|
||||
export function openDownloadDialog (url, saveName) {
|
||||
if (typeof url === 'object' && url instanceof Blob) {
|
||||
url = URL.createObjectURL(url) // 创建blob地址
|
||||
}
|
||||
let aLink = document.createElement('a')
|
||||
aLink.href = url
|
||||
saveName = saveName + '_' + getNowFormatStr() + '.xlsx'
|
||||
aLink.download = saveName || '' // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效
|
||||
let event
|
||||
if (window.MouseEvent) event = new MouseEvent('click')
|
||||
else {
|
||||
event = document.createEvent('MouseEvents')
|
||||
event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
|
||||
}
|
||||
aLink.dispatchEvent(event)
|
||||
}
|
||||
|
||||
/**
|
||||
* 将一个sheet转成最终的excel文件的blob对象,然后利用URL.createObjectURL下载
|
||||
* @param sheet
|
||||
* @param sheetName
|
||||
* @returns {Blob}
|
||||
*/
|
||||
export function sheet2blob (aoa, sheetName) {
|
||||
let sheet = XLSX.utils.aoa_to_sheet(aoa)
|
||||
sheetName = sheetName || 'sheet1'
|
||||
let workbook = {
|
||||
SheetNames: [sheetName],
|
||||
Sheets: {}
|
||||
}
|
||||
workbook.Sheets[sheetName] = sheet
|
||||
// 生成excel的配置项
|
||||
let wopts = {
|
||||
bookType: 'xlsx', // 要生成的文件类型
|
||||
bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
|
||||
type: 'binary'
|
||||
}
|
||||
let wbout = XLSX.write(workbook, wopts)
|
||||
let blob = new Blob([s2ab(wbout)], { type: 'application/octet-stream' })
|
||||
// 字符串转ArrayBuffer
|
||||
function s2ab (s) {
|
||||
let buf = new ArrayBuffer(s.length)
|
||||
let view = new Uint8Array(buf)
|
||||
for (let i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF
|
||||
return buf
|
||||
}
|
||||
return blob
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 回车后自动跳到下一个input
|
||||
*/
|
||||
export function autoJumpNextInput(domInfo) {
|
||||
let domIndex = 0
|
||||
let inputs = document.getElementById(domInfo).getElementsByTagName('input')
|
||||
inputs[domIndex].focus()
|
||||
document.getElementById(domInfo).addEventListener('keydown',function(e){
|
||||
if(e.keyCode === 13){
|
||||
domIndex++
|
||||
if(domIndex === inputs.length) {
|
||||
domIndex = 0
|
||||
}
|
||||
inputs[domIndex].focus()
|
||||
}
|
||||
})
|
||||
for(let i=0; i<inputs.length; i++){
|
||||
//这个index就是做个介质,来获取当前的i是第几个
|
||||
inputs[i].index = i;
|
||||
inputs[i].onclick = function () {
|
||||
domIndex = this.index
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -81,3 +81,11 @@ export function isArray(arg) {
|
||||
}
|
||||
return Array.isArray(arg)
|
||||
}
|
||||
|
||||
/**
|
||||
* URL地址
|
||||
* @param {*} s
|
||||
*/
|
||||
export function isURL (s) {
|
||||
return /^http[s]?:\/\/.*/.test(s)
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="当前审批任务" align="center" prop="tasks">
|
||||
<template slot-scope="scope">
|
||||
<el-button v-for="task in scope.row.tasks" type="text" @click="handleFormDetail(task.id)">
|
||||
<el-button v-for="task in scope.row.tasks" :key="task" type="text" @click="handleFormDetail(task.id)">
|
||||
<span>{{ task.name }}</span>
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="24">
|
||||
<a-card :style="cardStyle" :bordered="false">
|
||||
<!-- 查询区域 -->
|
||||
<div class="table-page-search-wrapper">
|
||||
<!-- 搜索区域 -->
|
||||
<a-form layout="inline" @keyup.enter.native="searchQuery">
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据编号" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入单据编号" v-model="queryParam.number"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="商品信息" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入物料编码、名称、规格、型号" v-model="queryParam.materialParam"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据日期" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-range-picker
|
||||
style="width:100%"
|
||||
v-model="queryParam.createTimeRange"
|
||||
format="YYYY-MM-DD"
|
||||
:placeholder="['开始时间', '结束时间']"
|
||||
@change="onDateChange"
|
||||
@ok="onDateOk"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<template v-if="toggleSearchStatus">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="仓库名称" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="请选择仓库" showSearch optionFilterProp="children" v-model="queryParam.depotId">
|
||||
<a-select-option v-for="(depot,index) in depotList" :key="index" :value="depot.id">
|
||||
{{ depot.depotName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="操作员" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择操作员" showSearch optionFilterProp="children" v-model="queryParam.creator">
|
||||
<a-select-option v-for="(item,index) in userList" :key="index" :value="item.id">
|
||||
{{ item.userName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</template>
|
||||
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-button type="primary" @click="searchQuery">查询</a-button>
|
||||
<a-button style="margin-left: 8px" @click="searchReset">重置</a-button>
|
||||
<a @click="handleToggleSearch" style="margin-left: 8px">
|
||||
{{ toggleSearchStatus ? '收起' : '展开' }}
|
||||
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
|
||||
</a>
|
||||
</a-col>
|
||||
</span>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
<!-- 操作按钮区域 -->
|
||||
<div class="table-operator" style="margin-top: 5px">
|
||||
<a-button v-if="btnEnableList.indexOf(1)>-1" @click="myHandleAdd" type="primary" icon="plus">新增</a-button>
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" v-if="btnEnableList.indexOf(1)>-1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
|
||||
<a-menu-item key="2" v-if="btnEnableList.indexOf(2)>-1" @click="batchSetStatus(1)"><a-icon type="check"/>审核</a-menu-item>
|
||||
<a-menu-item key="3" v-if="btnEnableList.indexOf(7)>-1" @click="batchSetStatus(0)"><a-icon type="stop"/>反审核</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button>
|
||||
批量操作 <a-icon type="down" />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
<a-tooltip placement="left" title="用于两个仓库之间的商品调拨,调拨单会影响库存。" slot="action">
|
||||
<a-icon v-if="btnEnableList.indexOf(1)>-1" type="question-circle" style="font-size:20px;float:right;" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<!-- table区域-begin -->
|
||||
<a-row>
|
||||
<a-col :md="2.5" :sm="24">
|
||||
<list-columns-setter v-model="columns" :def-columns="columns" style="float: right;"/>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div>
|
||||
<a-table
|
||||
ref="table"
|
||||
size="middle"
|
||||
bordered
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:components="drag(columns)"
|
||||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:scroll="scroll"
|
||||
:loading="loading"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
|
||||
@change="handleTableChange">
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<a @click="myHandleDetail(record, '调拨出库')">查看</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleEdit(record)">编辑</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleCopyAdd(record)">复制</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a-popconfirm v-if="btnEnableList.indexOf(1)>-1" title="确定删除吗?" @confirm="() => myHandleDelete(record)">
|
||||
<a>删除</a>
|
||||
</a-popconfirm>
|
||||
</span>
|
||||
<template slot="customRenderStatus" slot-scope="status">
|
||||
<a-tag v-if="status == '0'" color="red">未审核</a-tag>
|
||||
<a-tag v-if="status == '1'" color="green">已审核</a-tag>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
<!-- table区域-end -->
|
||||
<!-- 表单区域 -->
|
||||
<allocation-out-modal ref="modalForm" @ok="modalFormOk"></allocation-out-modal>
|
||||
<bill-detail ref="modalDetail"></bill-detail>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
<!--power by jishenghua-->
|
||||
<script>
|
||||
import AllocationOutModal from './modules/AllocationOutModal'
|
||||
import BillDetail from './dialog/BillDetail'
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
import { BillListMixin } from './mixins/BillListMixin'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
import ListColumnsSetter from '@/components/ListColumnsSetter'
|
||||
import tableDragResizeMixin from '@/mixins/tableDragResizeMixin'
|
||||
export default {
|
||||
name: "AllocationOutList",
|
||||
mixins:[JeecgListMixin,BillListMixin,tableDragResizeMixin],
|
||||
components: {
|
||||
AllocationOutModal,
|
||||
BillDetail,
|
||||
JDate,
|
||||
ListColumnsSetter
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
// 查询条件
|
||||
queryParam: {
|
||||
number: "",
|
||||
materialParam: "",
|
||||
type: "出库",
|
||||
subType: "调拨",
|
||||
roleType: Vue.ls.get('roleType'),
|
||||
depotId: "",
|
||||
creator: ""
|
||||
},
|
||||
labelCol: {
|
||||
span: 5
|
||||
},
|
||||
wrapperCol: {
|
||||
span: 18,
|
||||
offset: 1
|
||||
},
|
||||
// 表头
|
||||
columns: [
|
||||
{ title: '单据编号', dataIndex: 'number',width:160, align: 'center',
|
||||
customRender:function (text,record,index) {
|
||||
if(record.linkNumber) {
|
||||
return text + "[转]";
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '商品信息', dataIndex: 'materialsList',width:220, align: 'center', ellipsis:true,
|
||||
customRender:function (text,record,index) {
|
||||
if(text) {
|
||||
return text.replace(",",",");
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '单据日期', dataIndex: 'operTimeStr',width:145, align: 'center',},
|
||||
{ title: '操作员', dataIndex: 'userName',width:80, align: 'center', ellipsis:true},
|
||||
{ title: '金额合计', dataIndex: 'totalPrice',width:80, align: 'center',},
|
||||
{ title: '状态', dataIndex: 'status', width: 80, align: "center",
|
||||
scopedSlots: { customRender: 'customRenderStatus' }
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align:"center", width: 150,
|
||||
scopedSlots: { customRender: 'action' },
|
||||
}
|
||||
],
|
||||
url: {
|
||||
list: "/erp/depotHead/list",
|
||||
delete: "/erp/depotHead/delete",
|
||||
deleteBatch: "/erp/depotHead/deleteBatch",
|
||||
batchSetStatusUrl: "/erp/depotHead/batchSetStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
created() {
|
||||
this.getDepotData()
|
||||
this.initUser()
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
@import '~@assets/less/common.less'
|
||||
</style>
|
||||
@@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="24">
|
||||
<a-card :style="cardStyle" :bordered="false">
|
||||
<!-- 查询区域 -->
|
||||
<div class="table-page-search-wrapper">
|
||||
<!-- 搜索区域 -->
|
||||
<a-form layout="inline" @keyup.enter.native="searchQuery">
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据编号" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入单据编号" v-model="queryParam.number"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="商品信息" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入物料编码、名称、规格、型号" v-model="queryParam.materialParam"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据日期" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-range-picker
|
||||
style="width:100%"
|
||||
v-model="queryParam.createTimeRange"
|
||||
format="YYYY-MM-DD"
|
||||
:placeholder="['开始时间', '结束时间']"
|
||||
@change="onDateChange"
|
||||
@ok="onDateOk"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<template v-if="toggleSearchStatus">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="仓库名称" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="请选择仓库" showSearch optionFilterProp="children" v-model="queryParam.depotId">
|
||||
<a-select-option v-for="(depot,index) in depotList" :key="index" :value="depot.id">
|
||||
{{ depot.depotName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="操作员" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择操作员" showSearch optionFilterProp="children" v-model="queryParam.creator">
|
||||
<a-select-option v-for="(item,index) in userList" :key="index" :value="item.id">
|
||||
{{ item.userName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</template>
|
||||
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-button type="primary" @click="searchQuery">查询</a-button>
|
||||
<a-button style="margin-left: 8px" @click="searchReset">重置</a-button>
|
||||
<a @click="handleToggleSearch" style="margin-left: 8px">
|
||||
{{ toggleSearchStatus ? '收起' : '展开' }}
|
||||
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
|
||||
</a>
|
||||
</a-col>
|
||||
</span>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
<!-- 操作按钮区域 -->
|
||||
<div class="table-operator" style="margin-top: 5px">
|
||||
<a-button v-if="btnEnableList.indexOf(1)>-1" @click="myHandleAdd" type="primary" icon="plus">新增</a-button>
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" v-if="btnEnableList.indexOf(1)>-1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
|
||||
<a-menu-item key="2" v-if="btnEnableList.indexOf(2)>-1" @click="batchSetStatus(1)"><a-icon type="check"/>审核</a-menu-item>
|
||||
<a-menu-item key="3" v-if="btnEnableList.indexOf(7)>-1" @click="batchSetStatus(0)"><a-icon type="stop"/>反审核</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button>
|
||||
批量操作 <a-icon type="down" />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
<a-tooltip placement="left" title="用于将多种商品合并成一个商品,被合并的商品库存减少,合并后的商品库存增加。" slot="action">
|
||||
<a-icon v-if="btnEnableList.indexOf(1)>-1" type="question-circle" style="font-size:20px;float:right;" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<!-- table区域-begin -->
|
||||
<a-row>
|
||||
<a-col :md="2.5" :sm="24">
|
||||
<list-columns-setter v-model="columns" :def-columns="columns" style="float: right;"/>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div>
|
||||
<a-table
|
||||
ref="table"
|
||||
size="middle"
|
||||
bordered
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:components="drag(columns)"
|
||||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:scroll="scroll"
|
||||
:loading="loading"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
|
||||
@change="handleTableChange">
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<a @click="myHandleDetail(record, '组装单')">查看</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleEdit(record)">编辑</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleCopyAdd(record)">复制</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a-popconfirm v-if="btnEnableList.indexOf(1)>-1" title="确定删除吗?" @confirm="() => myHandleDelete(record)">
|
||||
<a>删除</a>
|
||||
</a-popconfirm>
|
||||
</span>
|
||||
<template slot="customRenderStatus" slot-scope="status">
|
||||
<a-tag v-if="status == '0'" color="red">未审核</a-tag>
|
||||
<a-tag v-if="status == '1'" color="green">已审核</a-tag>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
<!-- table区域-end -->
|
||||
<!-- 表单区域 -->
|
||||
<assemble-modal ref="modalForm" @ok="modalFormOk"></assemble-modal>
|
||||
<bill-detail ref="modalDetail"></bill-detail>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
<!--power by ji sheng hua-->
|
||||
<script>
|
||||
import AssembleModal from './modules/AssembleModal'
|
||||
import BillDetail from './dialog/BillDetail'
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
import { BillListMixin } from './mixins/BillListMixin'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
import ListColumnsSetter from '@/components/ListColumnsSetter'
|
||||
import tableDragResizeMixin from '@/mixins/tableDragResizeMixin'
|
||||
export default {
|
||||
name: "AssembleList",
|
||||
mixins:[JeecgListMixin,BillListMixin,tableDragResizeMixin],
|
||||
components: {
|
||||
AssembleModal,
|
||||
BillDetail,
|
||||
JDate,
|
||||
ListColumnsSetter
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
// 查询条件
|
||||
queryParam: {
|
||||
number: "",
|
||||
materialParam: "",
|
||||
type: "其它",
|
||||
subType: "组装单",
|
||||
roleType: Vue.ls.get('roleType'),
|
||||
depotId: "",
|
||||
creator: ""
|
||||
},
|
||||
labelCol: {
|
||||
span: 5
|
||||
},
|
||||
wrapperCol: {
|
||||
span: 18,
|
||||
offset: 1
|
||||
},
|
||||
// 表头
|
||||
columns: [
|
||||
{ title: '单据编号', dataIndex: 'number',width:160, align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
if(record.linkNumber) {
|
||||
return text + "[转]";
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '商品信息', dataIndex: 'materialsList',width:220, align:'center', ellipsis:true,
|
||||
customRender:function (text,record,index) {
|
||||
if(text) {
|
||||
return text.replace(",",",");
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '单据日期', dataIndex: 'operTimeStr',width:145, align:'center',},
|
||||
{ title: '操作员', dataIndex: 'userName',width:80, align:'center', ellipsis:true},
|
||||
{ title: '金额合计', dataIndex: 'totalPrice',width:80, align:'center',},
|
||||
{ title: '状态', dataIndex: 'status', width: 80, align: "center",
|
||||
scopedSlots: { customRender: 'customRenderStatus' }
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align:"center", width: 150,
|
||||
scopedSlots: { customRender: 'action' },
|
||||
}
|
||||
],
|
||||
url: {
|
||||
list: "/erp/depotHead/list",
|
||||
delete: "/erp/depotHead/delete",
|
||||
deleteBatch: "/erp/depotHead/deleteBatch",
|
||||
batchSetStatusUrl: "/erp/depotHead/batchSetStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
created() {
|
||||
this.getDepotData()
|
||||
this.initUser()
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
@import '~@assets/less/common.less'
|
||||
</style>
|
||||
@@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="24">
|
||||
<a-card :style="cardStyle" :bordered="false">
|
||||
<!-- 查询区域 -->
|
||||
<div class="table-page-search-wrapper">
|
||||
<!-- 搜索区域 -->
|
||||
<a-form layout="inline" @keyup.enter.native="searchQuery">
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据编号" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入单据编号" v-model="queryParam.number"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="商品信息" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入物料编码、名称、规格、型号" v-model="queryParam.materialParam"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据日期" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-range-picker
|
||||
style="width:100%"
|
||||
v-model="queryParam.createTimeRange"
|
||||
format="YYYY-MM-DD"
|
||||
:placeholder="['开始时间', '结束时间']"
|
||||
@change="onDateChange"
|
||||
@ok="onDateOk"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<template v-if="toggleSearchStatus">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="仓库名称" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="请选择仓库" showSearch optionFilterProp="children" v-model="queryParam.depotId">
|
||||
<a-select-option v-for="(depot,index) in depotList" :key="index" :value="depot.id">
|
||||
{{ depot.depotName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="操作员" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择操作员" showSearch optionFilterProp="children" v-model="queryParam.creator">
|
||||
<a-select-option v-for="(item,index) in userList" :key="index" :value="item.id">
|
||||
{{ item.userName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</template>
|
||||
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-button type="primary" @click="searchQuery">查询</a-button>
|
||||
<a-button style="margin-left: 8px" @click="searchReset">重置</a-button>
|
||||
<a @click="handleToggleSearch" style="margin-left: 8px">
|
||||
{{ toggleSearchStatus ? '收起' : '展开' }}
|
||||
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
|
||||
</a>
|
||||
</a-col>
|
||||
</span>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
<!-- 操作按钮区域 -->
|
||||
<div class="table-operator" style="margin-top: 5px">
|
||||
<a-button v-if="btnEnableList.indexOf(1)>-1" @click="myHandleAdd" type="primary" icon="plus">新增</a-button>
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" v-if="btnEnableList.indexOf(1)>-1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
|
||||
<a-menu-item key="2" v-if="btnEnableList.indexOf(2)>-1" @click="batchSetStatus(1)"><a-icon type="check"/>审核</a-menu-item>
|
||||
<a-menu-item key="3" v-if="btnEnableList.indexOf(7)>-1" @click="batchSetStatus(0)"><a-icon type="stop"/>反审核</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button>
|
||||
批量操作 <a-icon type="down" />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
<a-tooltip placement="left" title="用于将一个商品拆分成多种商品,被拆分的商品库存增加,拆分后的商品库存减少。" slot="action">
|
||||
<a-icon v-if="btnEnableList.indexOf(1)>-1" type="question-circle" style="font-size:20px;float:right;" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<!-- table区域-begin -->
|
||||
<a-row>
|
||||
<a-col :md="2.5" :sm="24">
|
||||
<list-columns-setter v-model="columns" :def-columns="columns" style="float: right;"/>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div>
|
||||
<a-table
|
||||
ref="table"
|
||||
size="middle"
|
||||
bordered
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:components="drag(columns)"
|
||||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:scroll="scroll"
|
||||
:loading="loading"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
|
||||
@change="handleTableChange">
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<a @click="myHandleDetail(record, '拆卸单')">查看</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleEdit(record)">编辑</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleCopyAdd(record)">复制</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a-popconfirm v-if="btnEnableList.indexOf(1)>-1" title="确定删除吗?" @confirm="() => myHandleDelete(record)">
|
||||
<a>删除</a>
|
||||
</a-popconfirm>
|
||||
</span>
|
||||
<template slot="customRenderStatus" slot-scope="status">
|
||||
<a-tag v-if="status == '0'" color="red">未审核</a-tag>
|
||||
<a-tag v-if="status == '1'" color="green">已审核</a-tag>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
<!-- table区域-end -->
|
||||
<!-- 表单区域 -->
|
||||
<disassemble-modal ref="modalForm" @ok="modalFormOk"></disassemble-modal>
|
||||
<bill-detail ref="modalDetail"></bill-detail>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
<!--power by jisheng hua-->
|
||||
<script>
|
||||
import DisassembleModal from './modules/DisassembleModal'
|
||||
import BillDetail from './dialog/BillDetail'
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
import { BillListMixin } from './mixins/BillListMixin'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
import ListColumnsSetter from '@/components/ListColumnsSetter'
|
||||
import tableDragResizeMixin from '@/mixins/tableDragResizeMixin'
|
||||
export default {
|
||||
name: "DisassembleList",
|
||||
mixins:[JeecgListMixin,BillListMixin,tableDragResizeMixin],
|
||||
components: {
|
||||
DisassembleModal,
|
||||
BillDetail,
|
||||
JDate,
|
||||
ListColumnsSetter
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
// 查询条件
|
||||
queryParam: {
|
||||
number: "",
|
||||
materialParam: "",
|
||||
type: "其它",
|
||||
subType: "拆卸单",
|
||||
roleType: Vue.ls.get('roleType'),
|
||||
depotId: "",
|
||||
creator: ""
|
||||
},
|
||||
labelCol: {
|
||||
span: 5
|
||||
},
|
||||
wrapperCol: {
|
||||
span: 18,
|
||||
offset: 1
|
||||
},
|
||||
// 表头
|
||||
columns: [
|
||||
{ title: '单据编号', dataIndex: 'number',width:160,
|
||||
customRender:function (text,record,index) {
|
||||
if(record.linkNumber) {
|
||||
return text + "[转]";
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '商品信息', dataIndex: 'materialsList',width:220, ellipsis:true,
|
||||
customRender:function (text,record,index) {
|
||||
if(text) {
|
||||
return text.replace(",",",");
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '单据日期', dataIndex: 'operTimeStr',width:145},
|
||||
{ title: '操作员', dataIndex: 'userName',width:80, ellipsis:true},
|
||||
{ title: '金额合计', dataIndex: 'totalPrice',width:80},
|
||||
{ title: '状态', dataIndex: 'status', width: 80, align: "center",
|
||||
scopedSlots: { customRender: 'customRenderStatus' }
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align:"center", width: 150,
|
||||
scopedSlots: { customRender: 'action' },
|
||||
}
|
||||
],
|
||||
url: {
|
||||
list: "/erp/depotHead/list",
|
||||
delete: "/erp/depotHead/delete",
|
||||
deleteBatch: "/erp/depotHead/deleteBatch",
|
||||
batchSetStatusUrl: "/erp/depotHead/batchSetStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
created() {
|
||||
this.getDepotData()
|
||||
this.initUser()
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
@import '~@assets/less/common.less'
|
||||
</style>
|
||||
@@ -0,0 +1,224 @@
|
||||
<template>
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="24">
|
||||
<a-card :style="cardStyle" :bordered="false">
|
||||
<!-- 查询区域 -->
|
||||
<div class="table-page-search-wrapper">
|
||||
<!-- 搜索区域 -->
|
||||
<a-form layout="inline" @keyup.enter.native="searchQuery">
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据编号" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入单据编号" v-model="queryParam.number"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="商品信息" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入物料编码、名称、规格、型号" v-model="queryParam.materialParam"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据日期" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-range-picker
|
||||
style="width:100%"
|
||||
v-model="queryParam.createTimeRange"
|
||||
format="YYYY-MM-DD"
|
||||
:placeholder="['开始时间', '结束时间']"
|
||||
@change="onDateChange"
|
||||
@ok="onDateOk"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<template v-if="toggleSearchStatus">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="仓库名称" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="请选择仓库" showSearch optionFilterProp="children" v-model="queryParam.depotId">
|
||||
<a-select-option v-for="(depot,index) in depotList" :key="index" :value="depot.id">
|
||||
{{ depot.depotName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="操作员" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择操作员" showSearch optionFilterProp="children" v-model="queryParam.creator">
|
||||
<a-select-option v-for="(item,index) in userList" :key="index" :value="item.id">
|
||||
{{ item.userName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="关联单据" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入关联单据" v-model="queryParam.linkNumber"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</template>
|
||||
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-button type="primary" @click="searchQuery">查询</a-button>
|
||||
<a-button style="margin-left: 8px" @click="searchReset">重置</a-button>
|
||||
<a @click="handleToggleSearch" style="margin-left: 8px">
|
||||
{{ toggleSearchStatus ? '收起' : '展开' }}
|
||||
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
|
||||
</a>
|
||||
</a-col>
|
||||
</span>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
<!-- 操作按钮区域 -->
|
||||
<div class="table-operator" style="margin-top: 5px">
|
||||
<a-button v-if="btnEnableList.indexOf(1)>-1" @click="myHandleAdd" type="primary" icon="plus">新增</a-button>
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" v-if="btnEnableList.indexOf(1)>-1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
|
||||
<a-menu-item key="2" v-if="btnEnableList.indexOf(2)>-1" @click="batchSetStatus(1)"><a-icon type="check"/>审核</a-menu-item>
|
||||
<a-menu-item key="3" v-if="btnEnableList.indexOf(7)>-1" @click="batchSetStatus(0)"><a-icon type="stop"/>反审核</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button>
|
||||
批量操作 <a-icon type="down" />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
<a-tooltip placement="left" title="可以进行库存初始化,生产管理模块的成品入库。" slot="action">
|
||||
<a-icon v-if="btnEnableList.indexOf(1)>-1" type="question-circle" style="font-size:20px;float:right;" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<!-- table区域-begin -->
|
||||
<a-row>
|
||||
<a-col :md="2.5" :sm="24">
|
||||
<list-columns-setter v-model="columns" :def-columns="columns" style="float: right;"/>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div>
|
||||
<a-table
|
||||
ref="table"
|
||||
size="middle"
|
||||
bordered
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:components="drag(columns)"
|
||||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:scroll="scroll"
|
||||
:loading="loading"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
|
||||
@change="handleTableChange">
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<a @click="myHandleDetail(record, '其它入库')">查看</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleEdit(record)">编辑</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleCopyAdd(record)">复制</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a-popconfirm v-if="btnEnableList.indexOf(1)>-1" title="确定删除吗?" @confirm="() => myHandleDelete(record)">
|
||||
<a>删除</a>
|
||||
</a-popconfirm>
|
||||
</span>
|
||||
<template slot="customRenderStatus" slot-scope="status">
|
||||
<a-tag v-if="status == '0'" color="red">未审核</a-tag>
|
||||
<a-tag v-if="status == '1'" color="green">已审核</a-tag>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
<!-- table区域-end -->
|
||||
<!-- 表单区域 -->
|
||||
<inventory-review-modal ref="modalForm" @ok="modalFormOk"></inventory-review-modal>
|
||||
<bill-detail ref="modalDetail"></bill-detail>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
<!--power by ji shenghua-->
|
||||
<script>
|
||||
import InventoryReviewModal from './modules/InventoryReviewModal.vue'
|
||||
import BillDetail from './dialog/BillDetail'
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
import { BillListMixin } from './mixins/BillListMixin'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
import ListColumnsSetter from '@/components/ListColumnsSetter'
|
||||
import tableDragResizeMixin from '@/mixins/tableDragResizeMixin'
|
||||
export default {
|
||||
name: "OtherInList",
|
||||
mixins:[JeecgListMixin,BillListMixin,tableDragResizeMixin],
|
||||
components: {
|
||||
InventoryReviewModal,
|
||||
BillDetail,
|
||||
JDate,
|
||||
ListColumnsSetter
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
// 查询条件
|
||||
queryParam: {
|
||||
number: "",
|
||||
materialParam: "",
|
||||
type: "其它",
|
||||
subType: "盘点复盘",
|
||||
roleType: Vue.ls.get('roleType'),
|
||||
organId: "",
|
||||
depotId: "",
|
||||
creator: "",
|
||||
linkNumber: ""
|
||||
},
|
||||
labelCol: {
|
||||
span: 5
|
||||
},
|
||||
wrapperCol: {
|
||||
span: 18,
|
||||
offset: 1
|
||||
},
|
||||
// 表头
|
||||
columns: [
|
||||
{ title: '单据编号', dataIndex: 'number',width:160, align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
if(record.linkNumber) {
|
||||
return text + "[转]";
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '商品信息', dataIndex: 'materialsList',width:220, align:'center', ellipsis:true,
|
||||
customRender:function (text,record,index) {
|
||||
if(text) {
|
||||
return text.replace(",",",");
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '单据日期', dataIndex: 'operTimeStr',width:145, align:'center',},
|
||||
{ title: '操作员', dataIndex: 'userName',width:80, align:'center', ellipsis:true},
|
||||
{ title: '金额合计', dataIndex: 'totalPrice',width:80, align:'center',},
|
||||
{ title: '状态', dataIndex: 'status', width: 80, align: "center",
|
||||
scopedSlots: { customRender: 'customRenderStatus' }
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align:"center", width: 150,
|
||||
scopedSlots: { customRender: 'action' },
|
||||
}
|
||||
],
|
||||
url: {
|
||||
list: "/erp/depotHead/list",
|
||||
delete: "/erp/depotHead/delete",
|
||||
deleteBatch: "/erp/depotHead/deleteBatch",
|
||||
batchSetStatusUrl: "/erp/depotHead/batchSetStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
created () {
|
||||
this.initSupplier()
|
||||
this.getDepotData()
|
||||
this.initUser()
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
@import '~@assets/less/common.less'
|
||||
</style>
|
||||
@@ -0,0 +1,234 @@
|
||||
<template>
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="24">
|
||||
<a-card :style="cardStyle" :bordered="false">
|
||||
<!-- 查询区域 -->
|
||||
<div class="table-page-search-wrapper">
|
||||
<!-- 搜索区域 -->
|
||||
<a-form layout="inline" @keyup.enter.native="searchQuery">
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据编号" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入单据编号" v-model="queryParam.number"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="商品信息" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入物料编码、名称、规格、型号" v-model="queryParam.materialParam"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据日期" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-range-picker
|
||||
style="width:100%"
|
||||
v-model="queryParam.createTimeRange"
|
||||
format="YYYY-MM-DD"
|
||||
:placeholder="['开始时间', '结束时间']"
|
||||
@change="onDateChange"
|
||||
@ok="onDateOk"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<template v-if="toggleSearchStatus">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="供应商" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择供应商" showSearch optionFilterProp="children" v-model="queryParam.organId">
|
||||
<a-select-option v-for="(item,index) in supList" :key="index" :value="item.id">
|
||||
{{ item.supplier }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="仓库名称" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="请选择仓库" showSearch optionFilterProp="children" v-model="queryParam.depotId">
|
||||
<a-select-option v-for="(depot,index) in depotList" :key="index" :value="depot.id">
|
||||
{{ depot.depotName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="操作员" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择操作员" showSearch optionFilterProp="children" v-model="queryParam.creator">
|
||||
<a-select-option v-for="(item,index) in userList" :key="index" :value="item.id">
|
||||
{{ item.userName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="关联单据" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入关联单据" v-model="queryParam.linkNumber"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</template>
|
||||
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-button type="primary" @click="searchQuery">查询</a-button>
|
||||
<a-button style="margin-left: 8px" @click="searchReset">重置</a-button>
|
||||
<a @click="handleToggleSearch" style="margin-left: 8px">
|
||||
{{ toggleSearchStatus ? '收起' : '展开' }}
|
||||
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
|
||||
</a>
|
||||
</a-col>
|
||||
</span>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
<!-- 操作按钮区域 -->
|
||||
<div class="table-operator" style="margin-top: 5px">
|
||||
<a-button v-if="btnEnableList.indexOf(1)>-1" @click="myHandleAdd" type="primary" icon="plus">新增</a-button>
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" v-if="btnEnableList.indexOf(1)>-1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
|
||||
<a-menu-item key="2" v-if="btnEnableList.indexOf(2)>-1" @click="batchSetStatus(1)"><a-icon type="check"/>审核</a-menu-item>
|
||||
<a-menu-item key="3" v-if="btnEnableList.indexOf(7)>-1" @click="batchSetStatus(0)"><a-icon type="stop"/>反审核</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button>
|
||||
批量操作 <a-icon type="down" />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
<a-tooltip placement="left" title="可以进行库存初始化,生产管理模块的成品入库。" slot="action">
|
||||
<a-icon v-if="btnEnableList.indexOf(1)>-1" type="question-circle" style="font-size:20px;float:right;" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<!-- table区域-begin -->
|
||||
<a-row>
|
||||
<a-col :md="2.5" :sm="24">
|
||||
<list-columns-setter v-model="columns" :def-columns="columns" style="float: right;"/>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div>
|
||||
<a-table
|
||||
ref="table"
|
||||
size="middle"
|
||||
bordered
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:components="drag(columns)"
|
||||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:scroll="scroll"
|
||||
:loading="loading"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
|
||||
@change="handleTableChange">
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<a @click="myHandleDetail(record, '其它入库')">查看</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleEdit(record)">编辑</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleCopyAdd(record)">复制</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a-popconfirm v-if="btnEnableList.indexOf(1)>-1" title="确定删除吗?" @confirm="() => myHandleDelete(record)">
|
||||
<a>删除</a>
|
||||
</a-popconfirm>
|
||||
</span>
|
||||
<template slot="customRenderStatus" slot-scope="status">
|
||||
<a-tag v-if="status == '0'" color="red">未审核</a-tag>
|
||||
<a-tag v-if="status == '1'" color="green">已审核</a-tag>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
<!-- table区域-end -->
|
||||
<!-- 表单区域 -->
|
||||
<other-in-modal ref="modalForm" @ok="modalFormOk"></other-in-modal>
|
||||
<bill-detail ref="modalDetail"></bill-detail>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
<!--power by ji shenghua-->
|
||||
<script>
|
||||
import OtherInModal from './modules/OtherInModal'
|
||||
import BillDetail from './dialog/BillDetail'
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
import { BillListMixin } from './mixins/BillListMixin'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
import ListColumnsSetter from '@/components/ListColumnsSetter'
|
||||
import tableDragResizeMixin from '@/mixins/tableDragResizeMixin'
|
||||
export default {
|
||||
name: "OtherInList",
|
||||
mixins:[JeecgListMixin,BillListMixin,tableDragResizeMixin],
|
||||
components: {
|
||||
OtherInModal,
|
||||
BillDetail,
|
||||
JDate,
|
||||
ListColumnsSetter
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
// 查询条件
|
||||
queryParam: {
|
||||
number: "",
|
||||
materialParam: "",
|
||||
type: "入库",
|
||||
subType: "其它",
|
||||
roleType: Vue.ls.get('roleType'),
|
||||
organId: "",
|
||||
depotId: "",
|
||||
creator: "",
|
||||
linkNumber: ""
|
||||
},
|
||||
labelCol: {
|
||||
span: 5
|
||||
},
|
||||
wrapperCol: {
|
||||
span: 18,
|
||||
offset: 1
|
||||
},
|
||||
// 表头
|
||||
columns: [
|
||||
{ title: '供应商', dataIndex: 'organName',width:120, align:'center', ellipsis:true},
|
||||
{ title: '单据编号', dataIndex: 'number',width:160, align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
if(record.linkNumber) {
|
||||
return text + "[转]";
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '商品信息', dataIndex: 'materialsList',width:220, align:'center', ellipsis:true,
|
||||
customRender:function (text,record,index) {
|
||||
if(text) {
|
||||
return text.replace(",",",");
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '单据日期', dataIndex: 'operTimeStr',width:145, align:'center',},
|
||||
{ title: '操作员', dataIndex: 'userName',width:80, align:'center', ellipsis:true},
|
||||
{ title: '金额合计', dataIndex: 'totalPrice',width:80, align:'center',},
|
||||
{ title: '状态', dataIndex: 'status', width: 80, align: "center",
|
||||
scopedSlots: { customRender: 'customRenderStatus' }
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align:"center", width: 150,
|
||||
scopedSlots: { customRender: 'action' },
|
||||
}
|
||||
],
|
||||
url: {
|
||||
list: "/erp/depotHead/list",
|
||||
delete: "/erp/depotHead/delete",
|
||||
deleteBatch: "/erp/depotHead/deleteBatch",
|
||||
batchSetStatusUrl: "/erp/depotHead/batchSetStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
created () {
|
||||
this.initSupplier()
|
||||
this.getDepotData()
|
||||
this.initUser()
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
@import '~@assets/less/common.less'
|
||||
</style>
|
||||
@@ -0,0 +1,234 @@
|
||||
<template>
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="24">
|
||||
<a-card :style="cardStyle" :bordered="false">
|
||||
<!-- 查询区域 -->
|
||||
<div class="table-page-search-wrapper">
|
||||
<!-- 搜索区域 -->
|
||||
<a-form layout="inline" @keyup.enter.native="searchQuery">
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据编号" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入单据编号" v-model="queryParam.number"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="商品信息" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入物料编码、名称、规格、型号" v-model="queryParam.materialParam"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据日期" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-range-picker
|
||||
style="width:100%"
|
||||
v-model="queryParam.createTimeRange"
|
||||
format="YYYY-MM-DD"
|
||||
:placeholder="['开始时间', '结束时间']"
|
||||
@change="onDateChange"
|
||||
@ok="onDateOk"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<template v-if="toggleSearchStatus">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="客户" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择客户" showSearch optionFilterProp="children" v-model="queryParam.organId">
|
||||
<a-select-option v-for="(item,index) in cusList" :key="index" :value="item.id">
|
||||
{{ item.supplier }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="仓库名称" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="请选择仓库" showSearch optionFilterProp="children" v-model="queryParam.depotId">
|
||||
<a-select-option v-for="(depot,index) in depotList" :key="index" :value="depot.id">
|
||||
{{ depot.depotName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="操作员" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择操作员" showSearch optionFilterProp="children" v-model="queryParam.creator">
|
||||
<a-select-option v-for="(item,index) in userList" :key="index" :value="item.id">
|
||||
{{ item.userName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="关联单据" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入关联单据" v-model="queryParam.linkNumber"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</template>
|
||||
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-button type="primary" @click="searchQuery">查询</a-button>
|
||||
<a-button style="margin-left: 8px" @click="searchReset">重置</a-button>
|
||||
<a @click="handleToggleSearch" style="margin-left: 8px">
|
||||
{{ toggleSearchStatus ? '收起' : '展开' }}
|
||||
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
|
||||
</a>
|
||||
</a-col>
|
||||
</span>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
<!-- 操作按钮区域 -->
|
||||
<div class="table-operator" style="margin-top: 5px">
|
||||
<a-button v-if="btnEnableList.indexOf(1)>-1" @click="myHandleAdd" type="primary" icon="plus">新增</a-button>
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" v-if="btnEnableList.indexOf(1)>-1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
|
||||
<a-menu-item key="2" v-if="btnEnableList.indexOf(2)>-1" @click="batchSetStatus(1)"><a-icon type="check"/>审核</a-menu-item>
|
||||
<a-menu-item key="3" v-if="btnEnableList.indexOf(7)>-1" @click="batchSetStatus(0)"><a-icon type="stop"/>反审核</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button>
|
||||
批量操作 <a-icon type="down" />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
<a-tooltip placement="left" title="可以进行库存初始化,生产管理模块的领料出库。" slot="action">
|
||||
<a-icon v-if="btnEnableList.indexOf(1)>-1" type="question-circle" style="font-size:20px;float:right;" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<!-- table区域-begin -->
|
||||
<a-row>
|
||||
<a-col :md="2.5" :sm="24">
|
||||
<list-columns-setter v-model="columns" :def-columns="columns" style="float: right;"/>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div>
|
||||
<a-table
|
||||
ref="table"
|
||||
size="middle"
|
||||
bordered
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:components="drag(columns)"
|
||||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:scroll="scroll"
|
||||
:loading="loading"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
|
||||
@change="handleTableChange">
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<a @click="myHandleDetail(record, '其它出库')">查看</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleEdit(record)">编辑</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleCopyAdd(record)">复制</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a-popconfirm v-if="btnEnableList.indexOf(1)>-1" title="确定删除吗?" @confirm="() => myHandleDelete(record)">
|
||||
<a>删除</a>
|
||||
</a-popconfirm>
|
||||
</span>
|
||||
<template slot="customRenderStatus" slot-scope="status">
|
||||
<a-tag v-if="status == '0'" color="red">未审核</a-tag>
|
||||
<a-tag v-if="status == '1'" color="green">已审核</a-tag>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
<!-- table区域-end -->
|
||||
<!-- 表单区域 -->
|
||||
<other-out-modal ref="modalForm" @ok="modalFormOk"></other-out-modal>
|
||||
<bill-detail ref="modalDetail"></bill-detail>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
<!--power by j i s h e n g h u a-->
|
||||
<script>
|
||||
import OtherOutModal from './modules/OtherOutModal'
|
||||
import BillDetail from './dialog/BillDetail'
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
import { BillListMixin } from './mixins/BillListMixin'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
import ListColumnsSetter from '@/components/ListColumnsSetter'
|
||||
import tableDragResizeMixin from '@/mixins/tableDragResizeMixin'
|
||||
export default {
|
||||
name: "OtherOutList",
|
||||
mixins:[JeecgListMixin,BillListMixin,tableDragResizeMixin],
|
||||
components: {
|
||||
OtherOutModal,
|
||||
BillDetail,
|
||||
JDate,
|
||||
ListColumnsSetter
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
// 查询条件
|
||||
queryParam: {
|
||||
number: "",
|
||||
materialParam: "",
|
||||
type: "出库",
|
||||
subType: "其它",
|
||||
roleType: Vue.ls.get('roleType'),
|
||||
organId: "",
|
||||
depotId: "",
|
||||
creator: "",
|
||||
linkNumber: ""
|
||||
},
|
||||
labelCol: {
|
||||
span: 5
|
||||
},
|
||||
wrapperCol: {
|
||||
span: 18,
|
||||
offset: 1
|
||||
},
|
||||
// 表头
|
||||
columns: [
|
||||
{ title: '客户', dataIndex: 'organName',width:120, align:'center', ellipsis:true},
|
||||
{ title: '单据编号', dataIndex: 'number',width:160, align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
if(record.linkNumber) {
|
||||
return text + "[转]";
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '商品信息', dataIndex: 'materialsList',width:220, align:'center', ellipsis:true,
|
||||
customRender:function (text,record,index) {
|
||||
if(text) {
|
||||
return text.replace(",",",");
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '单据日期', dataIndex: 'operTimeStr',width:145, align:'center',},
|
||||
{ title: '操作员', dataIndex: 'userName',width:80, align:'center', ellipsis:true},
|
||||
{ title: '金额合计', dataIndex: 'totalPrice',width:80, align:'center',},
|
||||
{ title: '状态', dataIndex: 'status', width: 80, align:'center', align: "center",
|
||||
scopedSlots: { customRender: 'customRenderStatus' }
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align:"center", width: 150,
|
||||
scopedSlots: { customRender: 'action' },
|
||||
}
|
||||
],
|
||||
url: {
|
||||
list: "/erp/depotHead/list",
|
||||
delete: "/erp/depotHead/delete",
|
||||
deleteBatch: "/erp/depotHead/deleteBatch",
|
||||
batchSetStatusUrl: "/erp/depotHead/batchSetStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
created() {
|
||||
this.initCustomer()
|
||||
this.getDepotData()
|
||||
this.initUser()
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
@import '~@assets/less/common.less'
|
||||
</style>
|
||||
@@ -0,0 +1,246 @@
|
||||
<template>
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="24">
|
||||
<a-card :style="cardStyle" :bordered="false">
|
||||
<!-- 查询区域 -->
|
||||
<div class="table-page-search-wrapper">
|
||||
<!-- 搜索区域 -->
|
||||
<a-form layout="inline" @keyup.enter.native="searchQuery">
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据编号" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入单据编号" v-model="queryParam.number"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="商品信息" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入物料编码、名称、规格、型号" v-model="queryParam.materialParam"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据日期" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-range-picker
|
||||
style="width:100%"
|
||||
v-model="queryParam.createTimeRange"
|
||||
format="YYYY-MM-DD"
|
||||
:placeholder="['开始时间', '结束时间']"
|
||||
@change="onDateChange"
|
||||
@ok="onDateOk"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<template v-if="toggleSearchStatus">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="供应商" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择供应商" showSearch optionFilterProp="children" v-model="queryParam.organId">
|
||||
<a-select-option v-for="(item,index) in supList" :key="index" :value="item.id">
|
||||
{{ item.supplier }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="仓库名称" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="请选择仓库" showSearch optionFilterProp="children" v-model="queryParam.depotId">
|
||||
<a-select-option v-for="(depot,index) in depotList" :key="index" :value="depot.id">
|
||||
{{ depot.depotName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="操作员" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择操作员" showSearch optionFilterProp="children" v-model="queryParam.creator">
|
||||
<a-select-option v-for="(item,index) in userList" :key="index" :value="item.id">
|
||||
{{ item.userName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="关联单据" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入关联单据" v-model="queryParam.linkNumber"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</template>
|
||||
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-button type="primary" @click="searchQuery">查询</a-button>
|
||||
<a-button style="margin-left: 8px" @click="searchReset">重置</a-button>
|
||||
<a @click="handleToggleSearch" style="margin-left: 8px">
|
||||
{{ toggleSearchStatus ? '收起' : '展开' }}
|
||||
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
|
||||
</a>
|
||||
</a-col>
|
||||
</span>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
<!-- 操作按钮区域 -->
|
||||
<div class="table-operator" style="margin-top: 5px">
|
||||
<a-button v-if="btnEnableList.indexOf(1)>-1" @click="myHandleAdd" type="primary" icon="plus">新增</a-button>
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" v-if="btnEnableList.indexOf(1)>-1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
|
||||
<a-menu-item key="2" v-if="btnEnableList.indexOf(2)>-1" @click="batchSetStatus(1)"><a-icon type="check"/>审核</a-menu-item>
|
||||
<a-menu-item key="3" v-if="btnEnableList.indexOf(7)>-1" @click="batchSetStatus(0)"><a-icon type="stop"/>反审核</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button>
|
||||
批量操作 <a-icon type="down" />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
<a-tooltip placement="left" title="用于采购入库单据的退货。采购退货单可以由采购出库单转过来,也可以单独创建。" slot="action">
|
||||
<a-icon v-if="btnEnableList.indexOf(1)>-1" type="question-circle" style="font-size:20px;float:right;" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<!-- table区域-begin -->
|
||||
<a-row>
|
||||
<a-col :md="2.5" :sm="24">
|
||||
<list-columns-setter v-model="columns" :def-columns="columns" style="float: right;"/>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div>
|
||||
<a-table
|
||||
ref="table"
|
||||
size="middle"
|
||||
bordered
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:components="drag(columns)"
|
||||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:scroll="scroll"
|
||||
:loading="loading"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
|
||||
@change="handleTableChange">
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<a @click="myHandleDetail(record, '采购退货出库')">查看</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleEdit(record)">编辑</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleCopyAdd(record)">复制</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a-popconfirm v-if="btnEnableList.indexOf(1)>-1" title="确定删除吗?" @confirm="() => myHandleDelete(record)">
|
||||
<a>删除</a>
|
||||
</a-popconfirm>
|
||||
</span>
|
||||
<template slot="customRenderStatus" slot-scope="status">
|
||||
<a-tag v-if="status == '0'" color="red">未审核</a-tag>
|
||||
<a-tag v-if="status == '1'" color="green">已审核</a-tag>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
<!-- table区域-end -->
|
||||
<!-- 表单区域 -->
|
||||
<purchase-back-modal ref="modalForm" @ok="modalFormOk"></purchase-back-modal>
|
||||
<bill-detail ref="modalDetail"></bill-detail>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
<!-- by jisheng hua-->
|
||||
<script>
|
||||
import PurchaseBackModal from './modules/PurchaseBackModal'
|
||||
import BillDetail from './dialog/BillDetail'
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
import { BillListMixin } from './mixins/BillListMixin'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
import ListColumnsSetter from '@/components/ListColumnsSetter'
|
||||
import tableDragResizeMixin from '@/mixins/tableDragResizeMixin'
|
||||
export default {
|
||||
name: "PurchaseBackList",
|
||||
mixins:[JeecgListMixin,BillListMixin,tableDragResizeMixin],
|
||||
components: {
|
||||
PurchaseBackModal,
|
||||
BillDetail,
|
||||
JDate,
|
||||
ListColumnsSetter
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
// 查询条件
|
||||
queryParam: {
|
||||
number: "",
|
||||
materialParam: "",
|
||||
type: "出库",
|
||||
subType: "采购退货",
|
||||
roleType: Vue.ls.get('roleType'),
|
||||
organId: "",
|
||||
depotId: "",
|
||||
creator: "",
|
||||
linkNumber: ""
|
||||
},
|
||||
labelCol: {
|
||||
span: 5
|
||||
},
|
||||
wrapperCol: {
|
||||
span: 18,
|
||||
offset: 1
|
||||
},
|
||||
// 表头
|
||||
columns: [
|
||||
{ title: '供应商', dataIndex: 'organName',width:120, ellipsis:true,align:'center',},
|
||||
{ title: '单据编号', dataIndex: 'number',width:160,align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
if(record.linkNumber) {
|
||||
return text + "[转]";
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '商品信息', dataIndex: 'materialsList',width:220,align:'center', ellipsis:true,
|
||||
customRender:function (text,record,index) {
|
||||
if(text) {
|
||||
return text.replace(",",",");
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '单据日期', dataIndex: 'operTimeStr',width:145,align:'center',},
|
||||
{ title: '操作员', dataIndex: 'userName',width:80,align:'center', ellipsis:true},
|
||||
{ title: '金额合计', dataIndex: 'totalPrice',width:80,align:'center',},
|
||||
{ title: '含税合计', dataIndex: 'totalTaxLastMoney',width:80,align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
return (record.discountMoney + record.discountLastMoney).toFixed(2);
|
||||
}
|
||||
},
|
||||
{ title: '待退金额', dataIndex: 'needBackMoney',width:80,align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
let needBackMoney = record.discountLastMoney + record.otherMoney
|
||||
return needBackMoney? needBackMoney.toFixed(2):''
|
||||
}
|
||||
},
|
||||
{ title: '退款', dataIndex: 'changeAmount',width:50,align:'center',},
|
||||
{ title: '状态', dataIndex: 'status', width: 80, align: "center",
|
||||
scopedSlots: { customRender: 'customRenderStatus' }
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align:"center", width: 160,
|
||||
scopedSlots: { customRender: 'action' },
|
||||
}
|
||||
],
|
||||
url: {
|
||||
list: "/erp/depotHead/list",
|
||||
delete: "/erp/depotHead/delete",
|
||||
deleteBatch: "/erp/depotHead/deleteBatch",
|
||||
batchSetStatusUrl: "/erp/depotHead/batchSetStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
created () {
|
||||
this.initSupplier()
|
||||
this.getDepotData()
|
||||
this.initUser()
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
@import '~@assets/less/common.less'
|
||||
</style>
|
||||
@@ -0,0 +1,255 @@
|
||||
<template>
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="24">
|
||||
<a-card :style="cardStyle" :bordered="false">
|
||||
<!-- 查询区域 -->
|
||||
<div class="table-page-search-wrapper">
|
||||
<!-- 搜索区域 -->
|
||||
<a-form layout="inline" @keyup.enter.native="searchQuery">
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据编号" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入单据编号" v-model="queryParam.number"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="商品信息" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入物料编码、名称、规格、型号" v-model="queryParam.materialParam"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据日期" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-range-picker
|
||||
style="width:100%"
|
||||
v-model="queryParam.createTimeRange"
|
||||
format="YYYY-MM-DD"
|
||||
:placeholder="['开始时间', '结束时间']"
|
||||
@change="onDateChange"
|
||||
@ok="onDateOk"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<template v-if="toggleSearchStatus">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="供应商" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择供应商" showSearch optionFilterProp="children" v-model="queryParam.organId">
|
||||
<a-select-option v-for="(item,index) in supList" :key="index" :value="item.id">
|
||||
{{ item.supplier }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="仓库名称" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="请选择仓库" showSearch optionFilterProp="children" v-model="queryParam.depotId">
|
||||
<a-select-option v-for="(depot,index) in depotList" :key="index" :value="depot.id">
|
||||
{{ depot.depotName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="操作员" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择操作员" showSearch optionFilterProp="children" v-model="queryParam.creator">
|
||||
<a-select-option v-for="(item,index) in userList" :key="index" :value="item.id">
|
||||
{{ item.userName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="关联订单" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入关联订单" v-model="queryParam.linkNumber"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</template>
|
||||
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-button type="primary" @click="searchQuery">查询</a-button>
|
||||
<a-button style="margin-left: 8px" @click="searchReset">重置</a-button>
|
||||
<a @click="handleToggleSearch" style="margin-left: 8px">
|
||||
{{ toggleSearchStatus ? '收起' : '展开' }}
|
||||
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
|
||||
</a>
|
||||
</a-col>
|
||||
</span>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
<!-- 操作按钮区域 -->
|
||||
<div class="table-operator" style="margin-top: 5px">
|
||||
<a-button v-if="btnEnableList.indexOf(1)>-1" @click="myHandleAdd" type="primary" icon="plus">新增</a-button>
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" v-if="btnEnableList.indexOf(1)>-1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
|
||||
<a-menu-item key="2" v-if="btnEnableList.indexOf(2)>-1" @click="batchSetStatus(1)"><a-icon type="check"/>审核</a-menu-item>
|
||||
<a-menu-item key="3" v-if="btnEnableList.indexOf(7)>-1" @click="batchSetStatus(0)"><a-icon type="stop"/>反审核</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button>
|
||||
批量操作 <a-icon type="down" />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
<a-tooltip placement="left" title="采购入库单可以由采购订单转过来,也可以单独创建。
|
||||
采购入库单据中的仓库列表只显示当前用户有权限的仓库。采购入库单可以使用多账户付款。
|
||||
勾选单据之后可以进行批量操作(删除、审核、反审核)" slot="action">
|
||||
<a-icon v-if="btnEnableList.indexOf(1)>-1" type="question-circle" style="font-size:20px;float:right;" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<!-- table区域-begin -->
|
||||
<!-- table区域-begin -->
|
||||
<a-row>
|
||||
<a-col :md="2.5" :sm="24">
|
||||
<list-columns-setter v-model="columns" :def-columns="columns" style="float: right;"/>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div>
|
||||
<a-table
|
||||
ref="table"
|
||||
size="middle"
|
||||
bordered
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:components="drag(columns)"
|
||||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:scroll="scroll"
|
||||
:loading="loading"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
|
||||
@change="handleTableChange">
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<a @click="myHandleDetail(record, '采购入库')">查看</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleEdit(record)">编辑</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleCopyAdd(record)">复制</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a-popconfirm v-if="btnEnableList.indexOf(1)>-1" title="确定删除吗?" @confirm="() => myHandleDelete(record)">
|
||||
<a>删除</a>
|
||||
</a-popconfirm>
|
||||
</span>
|
||||
<template slot="customRenderStatus" slot-scope="status">
|
||||
<a-tag v-if="status == '0'" color="red">未审核</a-tag>
|
||||
<a-tag v-if="status == '1'" color="green">已审核</a-tag>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
<!-- table区域-end -->
|
||||
<!-- 表单区域 -->
|
||||
<purchase-in-modal ref="modalForm" @ok="modalFormOk"></purchase-in-modal>
|
||||
<bill-detail ref="modalDetail"></bill-detail>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
<!-- by ji sheng hua-->
|
||||
<script>
|
||||
import PurchaseInModal from './modules/PurchaseInModal'
|
||||
import BillDetail from './dialog/BillDetail'
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
import { BillListMixin } from './mixins/BillListMixin'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
import ListColumnsSetter from '@/components/ListColumnsSetter'
|
||||
import tableDragResizeMixin from '@/mixins/tableDragResizeMixin'
|
||||
export default {
|
||||
name: "PurchaseInList",
|
||||
mixins:[JeecgListMixin,BillListMixin,tableDragResizeMixin],
|
||||
components: {
|
||||
PurchaseInModal,
|
||||
BillDetail,
|
||||
JDate,
|
||||
ListColumnsSetter
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
// 查询条件
|
||||
queryParam: {
|
||||
number: "",
|
||||
materialParam: "",
|
||||
type: "入库",
|
||||
subType: "采购",
|
||||
roleType: Vue.ls.get('roleType'),
|
||||
organId: "",
|
||||
depotId: "",
|
||||
creator: "",
|
||||
linkNumber: ""
|
||||
},
|
||||
labelCol: {
|
||||
span: 5
|
||||
},
|
||||
wrapperCol: {
|
||||
span: 18,
|
||||
offset: 1
|
||||
},
|
||||
// 表头
|
||||
columns: [
|
||||
{ title: '供应商', dataIndex: 'organName',width:120, ellipsis:true, align:'center',},
|
||||
{ title: '单据编号', dataIndex: 'number',width:160,align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
if(record.linkNumber) {
|
||||
return text + "[订]";
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '商品信息', dataIndex: 'materialsList',width:220, ellipsis:true,align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
if(text) {
|
||||
return text.replace(",",",");
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '单据日期', dataIndex: 'operTimeStr',width:145,align:'center',},
|
||||
{ title: '操作员', dataIndex: 'userName',width:80, ellipsis:true,align:'center',},
|
||||
{ title: '金额合计', dataIndex: 'totalPrice',width:80,align:'center',},
|
||||
{ title: '含税合计', dataIndex: 'totalTaxLastMoney',width:80,align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
return (record.discountMoney + record.discountLastMoney).toFixed(2);
|
||||
}
|
||||
},
|
||||
{ title: '待付金额', dataIndex: 'needInMoney',width:80,align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
let needInMoney = record.discountLastMoney + record.otherMoney
|
||||
return needInMoney? needInMoney.toFixed(2):''
|
||||
}
|
||||
},
|
||||
{ title: '付款', dataIndex: 'changeAmount',width:60,align:'center',},
|
||||
{ title: '欠款', dataIndex: 'debt',width:60,align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
let debt = record.discountLastMoney + record.otherMoney - record.changeAmount
|
||||
return debt? debt.toFixed(2):''
|
||||
}
|
||||
},
|
||||
{ title: '状态', dataIndex: 'status', width: 80, align: "center",align:'center',
|
||||
scopedSlots: { customRender: 'customRenderStatus' }
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align:"center", width: 180,
|
||||
scopedSlots: { customRender: 'action' },
|
||||
}
|
||||
],
|
||||
url: {
|
||||
list: "/erp/depotHead/list",
|
||||
delete: "/erp/depotHead/delete",
|
||||
deleteBatch: "/erp/depotHead/deleteBatch",
|
||||
batchSetStatusUrl: "/erp/depotHead/batchSetStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
created () {
|
||||
this.initSupplier()
|
||||
this.getDepotData()
|
||||
this.initUser()
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
@import '~@assets/less/common.less'
|
||||
</style>
|
||||
@@ -0,0 +1,230 @@
|
||||
<template>
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="24">
|
||||
<a-card :style="cardStyle" :bordered="false">
|
||||
<!-- 查询区域 -->
|
||||
<div class="table-page-search-wrapper">
|
||||
<!-- 搜索区域 -->
|
||||
<a-form layout="inline" @keyup.enter.native="searchQuery">
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据编号" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入单据编号" v-model="queryParam.number"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="商品信息" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入物料编码、名称、规格、型号" v-model="queryParam.materialParam"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据日期" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-range-picker
|
||||
style="width:100%"
|
||||
v-model="queryParam.createTimeRange"
|
||||
format="YYYY-MM-DD"
|
||||
:placeholder="['开始时间', '结束时间']"
|
||||
@change="onDateChange"
|
||||
@ok="onDateOk"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<template v-if="toggleSearchStatus">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="供应商" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择供应商" showSearch optionFilterProp="children" v-model="queryParam.organId">
|
||||
<a-select-option v-for="(item,index) in supList" :key="index" :value="item.id">
|
||||
{{ item.supplier }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="操作员" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择操作员" showSearch optionFilterProp="children" v-model="queryParam.creator">
|
||||
<a-select-option v-for="(item,index) in userList" :key="index" :value="item.id">
|
||||
{{ item.userName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</template>
|
||||
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-button type="primary" @click="searchQuery">查询</a-button>
|
||||
<a-button style="margin-left: 8px" @click="searchReset">重置</a-button>
|
||||
<a @click="handleToggleSearch" style="margin-left: 8px">
|
||||
{{ toggleSearchStatus ? '收起' : '展开' }}
|
||||
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
|
||||
</a>
|
||||
</a-col>
|
||||
</span>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
<!-- 操作按钮区域 -->
|
||||
<div class="table-operator" style="margin-top: 5px">
|
||||
<a-button v-if="btnEnableList.indexOf(1)>-1" @click="myHandleAdd" type="primary" icon="plus">新增</a-button>
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" v-if="btnEnableList.indexOf(1)>-1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
|
||||
<a-menu-item key="2" v-if="btnEnableList.indexOf(2)>-1" @click="batchSetStatus(1)"><a-icon type="check"/>审核</a-menu-item>
|
||||
<a-menu-item key="3" v-if="btnEnableList.indexOf(7)>-1" @click="batchSetStatus(0)"><a-icon type="stop"/>反审核</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button>
|
||||
批量操作 <a-icon type="down" />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
<a-tooltip placement="left" title="采购订单不涉及付款金额,采购订单可以转采购入库单,但需要先对采购订单进行审核。
|
||||
勾选单据之后可以进行批量操作(删除、审核、反审核)" slot="action">
|
||||
<a-icon v-if="btnEnableList.indexOf(1)>-1" type="question-circle" style="font-size:20px;float:right;" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<!-- table区域-begin -->
|
||||
<a-row>
|
||||
<a-col :md="2.5" :sm="24">
|
||||
<list-columns-setter v-model="columns" :def-columns="columns" style="float: right;"/>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div>
|
||||
<a-table
|
||||
ref="table"
|
||||
size="middle"
|
||||
bordered
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:components="drag(columns)"
|
||||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:scroll="scroll"
|
||||
:loading="loading"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
|
||||
@change="handleTableChange">
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<a @click="myHandleDetail(record, '采购订单')">查看</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleEdit(record)">编辑</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleCopyAdd(record)">复制</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a-popconfirm v-if="btnEnableList.indexOf(1)>-1" title="确定删除吗?" @confirm="() => myHandleDelete(record)">
|
||||
<a>删除</a>
|
||||
</a-popconfirm>
|
||||
</span>
|
||||
<template slot="customRenderStatus" slot-scope="status">
|
||||
<a-tag v-if="status == '0'" color="red">未审核</a-tag>
|
||||
<a-tag v-if="status == '1'" color="green">已审核</a-tag>
|
||||
<a-tag v-if="status == '2'" color="cyan">完成采购</a-tag>
|
||||
<a-tag v-if="status == '3'" color="blue">部分采购</a-tag>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
<!-- table区域-end -->
|
||||
<!-- 表单区域 -->
|
||||
<purchase-order-modal ref="modalForm" @ok="modalFormOk"></purchase-order-modal>
|
||||
<bill-detail ref="modalDetail"></bill-detail>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
<!-- by ji sheng hua-->
|
||||
<script>
|
||||
import PurchaseOrderModal from './modules/PurchaseOrderModal'
|
||||
import BillDetail from './dialog/BillDetail'
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
import { BillListMixin } from './mixins/BillListMixin'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
import ListColumnsSetter from '@/components/ListColumnsSetter'
|
||||
import tableDragResizeMixin from '@/mixins/tableDragResizeMixin'
|
||||
export default {
|
||||
name: "PurchaseOrderList",
|
||||
mixins:[JeecgListMixin,BillListMixin,tableDragResizeMixin],
|
||||
components: {
|
||||
PurchaseOrderModal,
|
||||
BillDetail,
|
||||
JDate,
|
||||
ListColumnsSetter
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
// 查询条件
|
||||
queryParam: {
|
||||
number: "",
|
||||
materialParam: "",
|
||||
type: "其它",
|
||||
subType: "采购订单",
|
||||
roleType: Vue.ls.get('roleType'),
|
||||
organId: "",
|
||||
depotId: "",
|
||||
creator: ""
|
||||
},
|
||||
labelCol: {
|
||||
span: 5
|
||||
},
|
||||
wrapperCol: {
|
||||
span: 18,
|
||||
offset: 1
|
||||
},
|
||||
// 表头
|
||||
columns: [
|
||||
{ title: '供应商', dataIndex: 'organName',width:120, align:'center', ellipsis:true},
|
||||
{ title: '单据编号', dataIndex: 'number',width:160, align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
if(record.linkNumber) {
|
||||
return text + "[转]";
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '商品信息', dataIndex: 'materialsList',width:220, align:'center', ellipsis:true,
|
||||
customRender:function (text,record,index) {
|
||||
if(text) {
|
||||
return text.replace(",",",");
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '单据日期', dataIndex: 'operTimeStr',width:145,align:'center',},
|
||||
{ title: '操作员', dataIndex: 'userName',width:80, ellipsis:true,align:'center',},
|
||||
{ title: '金额合计', dataIndex: 'totalPrice',width:80,align:'center',},
|
||||
{ title: '含税合计', dataIndex: 'totalTaxLastMoney',width:80,align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
if(record.discountLastMoney) {
|
||||
return (record.discountMoney + record.discountLastMoney).toFixed(2);
|
||||
} else {
|
||||
return record.totalPrice;
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '状态', dataIndex: 'status', width: 80, align: "center",align:'center',
|
||||
scopedSlots: { customRender: 'customRenderStatus' }
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align:"center", width: 150,
|
||||
scopedSlots: { customRender: 'action' },
|
||||
}
|
||||
],
|
||||
url: {
|
||||
list: "/erp/depotHead/list",
|
||||
delete: "/erp/depotHead/delete",
|
||||
deleteBatch: "/erp/depotHead/deleteBatch",
|
||||
batchSetStatusUrl: "/erp/depotHead/batchSetStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initSupplier()
|
||||
this.initUser()
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
@import '~@assets/less/common.less'
|
||||
</style>
|
||||
@@ -0,0 +1,244 @@
|
||||
<template>
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="24">
|
||||
<a-card :style="cardStyle" :bordered="false">
|
||||
<!-- 查询区域 -->
|
||||
<div class="table-page-search-wrapper">
|
||||
<!-- 搜索区域 -->
|
||||
<a-form layout="inline" @keyup.enter.native="searchQuery">
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据编号" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入单据编号" v-model="queryParam.number"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="商品信息" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入物料编码、名称、规格、型号" v-model="queryParam.materialParam"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据日期" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-range-picker
|
||||
style="width:100%"
|
||||
v-model="queryParam.createTimeRange"
|
||||
format="YYYY-MM-DD"
|
||||
:placeholder="['开始时间', '结束时间']"
|
||||
@change="onDateChange"
|
||||
@ok="onDateOk"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<template v-if="toggleSearchStatus">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="会员卡号" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择会员卡号" showSearch optionFilterProp="children" v-model="queryParam.organId">
|
||||
<a-select-option v-for="(item,index) in retailList" :key="index" :value="item.id">
|
||||
{{ item.supplier }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="仓库名称" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="请选择仓库" showSearch optionFilterProp="children" v-model="queryParam.depotId">
|
||||
<a-select-option v-for="(depot,index) in depotList" :key="index" :value="depot.id">
|
||||
{{ depot.depotName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="操作员" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择操作员" showSearch optionFilterProp="children" v-model="queryParam.creator">
|
||||
<a-select-option v-for="(item,index) in userList" :key="index" :value="item.id">
|
||||
{{ item.userName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="关联单据" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入关联单据" v-model="queryParam.linkNumber"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</template>
|
||||
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-button type="primary" @click="searchQuery">查询</a-button>
|
||||
<a-button style="margin-left: 8px" @click="searchReset">重置</a-button>
|
||||
<a @click="handleToggleSearch" style="margin-left: 8px">
|
||||
{{ toggleSearchStatus ? '收起' : '展开' }}
|
||||
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
|
||||
</a>
|
||||
</a-col>
|
||||
</span>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
<!-- 操作按钮区域 -->
|
||||
<div class="table-operator" style="margin-top: 5px">
|
||||
<a-button v-if="btnEnableList.indexOf(1)>-1" @click="myHandleAdd" type="primary" icon="plus">新增</a-button>
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" v-if="btnEnableList.indexOf(1)>-1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
|
||||
<a-menu-item key="2" v-if="btnEnableList.indexOf(2)>-1" @click="batchSetStatus(1)"><a-icon type="check"/>审核</a-menu-item>
|
||||
<a-menu-item key="3" v-if="btnEnableList.indexOf(7)>-1" @click="batchSetStatus(0)"><a-icon type="stop"/>反审核</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button>
|
||||
批量操作 <a-icon type="down" />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
<a-tooltip placement="left" title="用于零售出库单据的退货。零售退货单可以由零售出库单转过来,也可以单独创建。" slot="action">
|
||||
<a-icon v-if="btnEnableList.indexOf(1)>-1" type="question-circle" style="font-size:20px;float:right;" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<!-- table区域-begin -->
|
||||
<a-row>
|
||||
<a-col :md="2.5" :sm="24">
|
||||
<list-columns-setter v-model="columns" :def-columns="columns" style="float: right;"/>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div>
|
||||
<a-table
|
||||
ref="table"
|
||||
size="middle"
|
||||
bordered
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:components="drag(columns)"
|
||||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:scroll="scroll"
|
||||
:loading="loading"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
|
||||
@change="handleTableChange">
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<a @click="myHandleDetail(record, '零售退货入库')">查看</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleEdit(record)">编辑</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleCopyAdd(record)">复制</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a-popconfirm v-if="btnEnableList.indexOf(1)>-1" title="确定删除吗?" @confirm="() => myHandleDelete(record)">
|
||||
<a>删除</a>
|
||||
</a-popconfirm>
|
||||
</span>
|
||||
<template slot="customRenderStatus" slot-scope="status">
|
||||
<a-tag v-if="status == '0'" color="red">未审核</a-tag>
|
||||
<a-tag v-if="status == '1'" color="green">已审核</a-tag>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
<!-- table区域-end -->
|
||||
<!-- 表单区域 -->
|
||||
<retail-back-modal ref="modalForm" @ok="modalFormOk"></retail-back-modal>
|
||||
<bill-detail ref="modalDetail"></bill-detail>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
<!-- by jisheng h u a-->
|
||||
<script>
|
||||
import RetailBackModal from './modules/RetailBackModal'
|
||||
import BillDetail from './dialog/BillDetail'
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
import { BillListMixin } from './mixins/BillListMixin'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
import ListColumnsSetter from '@/components/ListColumnsSetter'
|
||||
import tableDragResizeMixin from '@/mixins/tableDragResizeMixin'
|
||||
export default {
|
||||
name: "RetailBackList",
|
||||
mixins:[JeecgListMixin,BillListMixin,tableDragResizeMixin],
|
||||
components: {
|
||||
RetailBackModal,
|
||||
BillDetail,
|
||||
JDate,
|
||||
ListColumnsSetter
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
// 查询条件
|
||||
queryParam: {
|
||||
number: "",
|
||||
materialParam: "",
|
||||
type: "入库",
|
||||
subType: "零售退货",
|
||||
roleType: Vue.ls.get('roleType'),
|
||||
organId: "",
|
||||
depotId: "",
|
||||
creator: "",
|
||||
linkNumber: ""
|
||||
},
|
||||
labelCol: {
|
||||
span: 5
|
||||
},
|
||||
wrapperCol: {
|
||||
span: 18,
|
||||
offset: 1
|
||||
},
|
||||
// 表头
|
||||
columns: [
|
||||
{ title: '会员', dataIndex: 'organName',width:120, ellipsis:true, align:'center'},
|
||||
{ title: '单据编号', dataIndex: 'number',width:160, align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
if(record.linkNumber) {
|
||||
return text + "[转]";
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '商品信息', dataIndex: 'materialsList',width:220, ellipsis:true,
|
||||
customRender:function (text,record,index) {
|
||||
if(text) {
|
||||
return text.replace(",",",");
|
||||
}
|
||||
}, align:'center'
|
||||
},
|
||||
{ title: '单据日期', dataIndex: 'operTimeStr',width:145, align:'center'},
|
||||
{ title: '操作员', dataIndex: 'userName',width:80, ellipsis:true, align:'center'},
|
||||
{ title: '金额合计', dataIndex: 'totalPrice',width:80, align:'center'},
|
||||
{ title: '付款金额', dataIndex: 'getAmount',width:80, align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
if(record.backAmount) {
|
||||
return record.changeAmount + record.backAmount
|
||||
} else {
|
||||
return record.changeAmount
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '找零', dataIndex: 'backAmount',width:50, align:'center'},
|
||||
{ title: '状态', dataIndex: 'status', width: 80, align: "center",
|
||||
scopedSlots: { customRender: 'customRenderStatus' }
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align:"center", width: 150,
|
||||
scopedSlots: { customRender: 'action' },
|
||||
}
|
||||
],
|
||||
url: {
|
||||
list: "/erp/depotHead/list",
|
||||
delete: "/erp/depotHead/delete",
|
||||
deleteBatch: "/erp/depotHead/deleteBatch",
|
||||
batchSetStatusUrl: "/erp/depotHead/batchSetStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
created () {
|
||||
this.initRetail()
|
||||
this.getDepotData()
|
||||
this.initUser()
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
@import '~@assets/less/common.less'
|
||||
</style>
|
||||
@@ -0,0 +1,238 @@
|
||||
<template>
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="24">
|
||||
<a-card :style="cardStyle" :bordered="false">
|
||||
<!-- 查询区域 -->
|
||||
<div class="table-page-search-wrapper">
|
||||
<!-- 搜索区域 -->
|
||||
<a-form layout="inline" @keyup.enter.native="searchQuery">
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据编号" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入单据编号" v-model="queryParam.number"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="商品信息" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入物料编码、名称、规格、型号" v-model="queryParam.materialParam"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据日期" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-range-picker
|
||||
style="width:100%"
|
||||
v-model="queryParam.createTimeRange"
|
||||
format="YYYY-MM-DD"
|
||||
:placeholder="['开始时间', '结束时间']"
|
||||
@change="onDateChange"
|
||||
@ok="onDateOk"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<template v-if="toggleSearchStatus">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="会员卡号" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择会员卡号" showSearch optionFilterProp="children" v-model="queryParam.organId">
|
||||
<a-select-option v-for="(item,index) in retailList" :key="index" :value="item.id">
|
||||
{{ item.supplier }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="仓库名称" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="请选择仓库" showSearch optionFilterProp="children" v-model="queryParam.depotId">
|
||||
<a-select-option v-for="(depot,index) in depotList" :key="index" :value="depot.id">
|
||||
{{ depot.depotName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="操作员" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择操作员" showSearch optionFilterProp="children" v-model="queryParam.creator">
|
||||
<a-select-option v-for="(item,index) in userList" :key="index" :value="item.id">
|
||||
{{ item.userName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</template>
|
||||
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-button type="primary" @click="searchQuery">查询</a-button>
|
||||
<a-button style="margin-left: 8px" @click="searchReset">重置</a-button>
|
||||
<a @click="handleToggleSearch" style="margin-left: 8px">
|
||||
{{ toggleSearchStatus ? '收起' : '展开' }}
|
||||
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
|
||||
</a>
|
||||
</a-col>
|
||||
</span>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
<!-- 操作按钮区域 -->
|
||||
<div class="table-operator" style="margin-top: 5px">
|
||||
<a-button v-if="btnEnableList.indexOf(1)>-1" @click="myHandleAdd" type="primary" icon="plus">新增</a-button>
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" v-if="btnEnableList.indexOf(1)>-1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
|
||||
<a-menu-item key="2" v-if="btnEnableList.indexOf(2)>-1" @click="batchSetStatus(1)"><a-icon type="check"/>审核</a-menu-item>
|
||||
<a-menu-item key="3" v-if="btnEnableList.indexOf(7)>-1" @click="batchSetStatus(0)"><a-icon type="stop"/>反审核</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button>
|
||||
批量操作 <a-icon type="down" />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
<a-tooltip placement="left" title="用于非会员和会员的单据录入,主要是用于散户使用,不能欠款。" slot="action">
|
||||
<a-icon v-if="btnEnableList.indexOf(1)>-1" type="question-circle" style="font-size:20px;float:right;" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<!-- table区域-begin -->
|
||||
<a-row>
|
||||
<a-col :md="2.5" :sm="24">
|
||||
<list-columns-setter v-model="columns" :def-columns="columns" style="float: right;"/>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div>
|
||||
<a-table
|
||||
ref="table"
|
||||
size="middle"
|
||||
bordered
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:components="drag(columns)"
|
||||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:scroll="scroll"
|
||||
:loading="loading"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
|
||||
@change="handleTableChange">
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<a @click="myHandleDetail(record, '零售出库')">查看</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleEdit(record)">编辑</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleCopyAdd(record)">复制</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a-popconfirm v-if="btnEnableList.indexOf(1)>-1" title="确定删除吗?" @confirm="() => myHandleDelete(record)">
|
||||
<a>删除</a>
|
||||
</a-popconfirm>
|
||||
</span>
|
||||
<template slot="customRenderStatus" slot-scope="status">
|
||||
<a-tag v-if="status == '0'" color="red">未审核</a-tag>
|
||||
<a-tag v-if="status == '1'" color="green">已审核</a-tag>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
<!-- table区域-end -->
|
||||
<!-- 表单区域 -->
|
||||
<retail-out-modal ref="modalForm" @ok="modalFormOk"></retail-out-modal>
|
||||
<bill-detail ref="modalDetail"></bill-detail>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
<!-- create ji sheng hua-->
|
||||
<script>
|
||||
import RetailOutModal from './modules/RetailOutModal'
|
||||
import BillDetail from './dialog/BillDetail'
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
import { BillListMixin } from './mixins/BillListMixin'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
import ListColumnsSetter from '@/components/ListColumnsSetter'
|
||||
import tableDragResizeMixin from '@/mixins/tableDragResizeMixin'
|
||||
export default {
|
||||
name: "RetailOutList",
|
||||
mixins:[JeecgListMixin,BillListMixin,tableDragResizeMixin],
|
||||
components: {
|
||||
RetailOutModal,
|
||||
BillDetail,
|
||||
JDate,
|
||||
ListColumnsSetter
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
// 查询条件
|
||||
queryParam: {
|
||||
number: "",
|
||||
materialParam: "",
|
||||
type: "出库",
|
||||
subType: "零售",
|
||||
roleType: Vue.ls.get('roleType'),
|
||||
organId: "",
|
||||
depotId: "",
|
||||
creator: ""
|
||||
},
|
||||
labelCol: {
|
||||
span: 5
|
||||
},
|
||||
wrapperCol: {
|
||||
span: 18,
|
||||
offset: 1
|
||||
},
|
||||
// 表头
|
||||
columns: [
|
||||
{ title: '会员', dataIndex: 'organName',width:120, ellipsis:true, align:'center'},
|
||||
{ title: '单据编号', dataIndex: 'number',width:160, align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
if(record.linkNumber) {
|
||||
return text + "[转]";
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '商品信息', dataIndex: 'materialsList',width:220, ellipsis:true, align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
if(text) {
|
||||
return text.replace(",",",");
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '单据日期', dataIndex: 'operTimeStr',width:145, align:'center'},
|
||||
{ title: '操作员', dataIndex: 'userName',width:80, ellipsis:true, align:'center'},
|
||||
{ title: '金额合计', dataIndex: 'totalPrice',width:80, align:'center'},
|
||||
{ title: '收款金额', dataIndex: 'getAmount',width:80, align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
if(record.backAmount) {
|
||||
return record.changeAmount + record.backAmount
|
||||
} else {
|
||||
return record.changeAmount
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '找零', dataIndex: 'backAmount',width:50, align:'center'},
|
||||
{ title: '状态', dataIndex: 'status', width: 80, align: "center",
|
||||
scopedSlots: { customRender: 'customRenderStatus' }, align:'center'
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align:"center", width: 150,
|
||||
scopedSlots: { customRender: 'action' },
|
||||
}
|
||||
],
|
||||
url: {
|
||||
list: "/erp/depotHead/list",
|
||||
delete: "/erp/depotHead/delete",
|
||||
deleteBatch: "/erp/depotHead/deleteBatch",
|
||||
batchSetStatusUrl: "/erp/depotHead/batchSetStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
created () {
|
||||
this.initRetail()
|
||||
this.getDepotData()
|
||||
this.initUser()
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
@import '~@assets/less/common.less'
|
||||
</style>
|
||||
@@ -0,0 +1,246 @@
|
||||
<!-- create ji sheng hua-->
|
||||
<template>
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="24">
|
||||
<a-card :style="cardStyle" :bordered="false">
|
||||
<!-- 查询区域 -->
|
||||
<div class="table-page-search-wrapper">
|
||||
<!-- 搜索区域 -->
|
||||
<a-form layout="inline" @keyup.enter.native="searchQuery">
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据编号" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入单据编号" v-model="queryParam.number"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="商品信息" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入条码、名称、规格、型号" v-model="queryParam.materialParam"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据日期" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-range-picker
|
||||
style="width:100%"
|
||||
v-model="queryParam.createTimeRange"
|
||||
format="YYYY-MM-DD"
|
||||
:placeholder="['开始时间', '结束时间']"
|
||||
@change="onDateChange"
|
||||
@ok="onDateOk"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<template v-if="toggleSearchStatus">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="客户" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择客户" showSearch optionFilterProp="children" v-model="queryParam.organId">
|
||||
<a-select-option v-for="(item,index) in cusList" :key="index" :value="item.id">
|
||||
{{ item.supplier }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="仓库名称" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="请选择仓库" showSearch optionFilterProp="children" v-model="queryParam.depotId">
|
||||
<a-select-option v-for="(depot,index) in depotList" :key="index" :value="depot.id">
|
||||
{{ depot.depotName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="操作员" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择操作员" showSearch optionFilterProp="children" v-model="queryParam.creator">
|
||||
<a-select-option v-for="(item,index) in userList" :key="index" :value="item.id">
|
||||
{{ item.userName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="关联单据" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入关联单据" v-model="queryParam.linkNumber"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</template>
|
||||
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-button type="primary" @click="searchQuery">查询</a-button>
|
||||
<a-button style="margin-left: 8px" @click="searchReset">重置</a-button>
|
||||
<a @click="handleToggleSearch" style="margin-left: 8px">
|
||||
{{ toggleSearchStatus ? '收起' : '展开' }}
|
||||
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
|
||||
</a>
|
||||
</a-col>
|
||||
</span>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
<!-- 操作按钮区域 -->
|
||||
<div class="table-operator" style="margin-top: 5px">
|
||||
<a-button v-if="btnEnableList.indexOf(1)>-1" @click="myHandleAdd" type="primary" icon="plus">新增</a-button>
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" v-if="btnEnableList.indexOf(1)>-1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
|
||||
<a-menu-item key="2" v-if="btnEnableList.indexOf(2)>-1" @click="batchSetStatus(1)"><a-icon type="check"/>审核</a-menu-item>
|
||||
<a-menu-item key="3" v-if="btnEnableList.indexOf(7)>-1" @click="batchSetStatus(0)"><a-icon type="stop"/>反审核</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button>
|
||||
批量操作 <a-icon type="down" />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
<a-tooltip placement="left" title="用于销售出库单据的退货。销售退货单可以由销售出库单转过来,也可以单独创建。" slot="action">
|
||||
<a-icon v-if="btnEnableList.indexOf(1)>-1" type="question-circle" style="font-size:20px;float:right;" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<!-- table区域-begin -->
|
||||
<a-row>
|
||||
<a-col :md="2.5" :sm="24">
|
||||
<list-columns-setter v-model="columns" :def-columns="columns" style="float: right;"/>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div>
|
||||
<a-table
|
||||
ref="table"
|
||||
size="middle"
|
||||
bordered
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:components="drag(columns)"
|
||||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:scroll="scroll"
|
||||
:loading="loading"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
|
||||
@change="handleTableChange">
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<a @click="myHandleDetail(record, '销售退货入库')">查看</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleEdit(record)">编辑</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleCopyAdd(record)">复制</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a-popconfirm v-if="btnEnableList.indexOf(1)>-1" title="确定删除吗?" @confirm="() => myHandleDelete(record)">
|
||||
<a>删除</a>
|
||||
</a-popconfirm>
|
||||
</span>
|
||||
<template slot="customRenderStatus" slot-scope="status">
|
||||
<a-tag v-if="status == '0'" color="red">未审核</a-tag>
|
||||
<a-tag v-if="status == '1'" color="green">已审核</a-tag>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
<!-- table区域-end -->
|
||||
<!-- 表单区域 -->
|
||||
<sale-back-modal ref="modalForm" @ok="modalFormOk"></sale-back-modal>
|
||||
<bill-detail ref="modalDetail"></bill-detail>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
<script>
|
||||
import SaleBackModal from './modules/SaleBackModal'
|
||||
import BillDetail from './dialog/BillDetail'
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
import { BillListMixin } from './mixins/BillListMixin'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
import ListColumnsSetter from '@/components/ListColumnsSetter'
|
||||
import tableDragResizeMixin from '@/mixins/tableDragResizeMixin'
|
||||
export default {
|
||||
name: "SaleBackList",
|
||||
mixins:[JeecgListMixin,BillListMixin,tableDragResizeMixin],
|
||||
components: {
|
||||
SaleBackModal,
|
||||
BillDetail,
|
||||
JDate,
|
||||
ListColumnsSetter
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
// 查询条件
|
||||
queryParam: {
|
||||
number: "",
|
||||
materialParam: "",
|
||||
type: "入库",
|
||||
subType: "销售退货",
|
||||
roleType: Vue.ls.get('roleType'),
|
||||
organId: "",
|
||||
depotId: "",
|
||||
creator: "",
|
||||
linkNumber: ""
|
||||
},
|
||||
labelCol: {
|
||||
span: 5
|
||||
},
|
||||
wrapperCol: {
|
||||
span: 18,
|
||||
offset: 1
|
||||
},
|
||||
// 表头
|
||||
columns: [
|
||||
{ title: '客户', dataIndex: 'organName',width:120, align:"center", ellipsis:true},
|
||||
{ title: '单据编号', dataIndex: 'number',width:160, align:"center",
|
||||
customRender:function (text,record,index) {
|
||||
if(record.linkNumber) {
|
||||
return text + "[转]";
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '商品信息', dataIndex: 'materialsList',width:220, align:"center", ellipsis:true,
|
||||
customRender:function (text,record,index) {
|
||||
if(text) {
|
||||
return text.replace(",",",");
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '单据日期', dataIndex: 'operTimeStr',width:145, align:"center", },
|
||||
{ title: '操作员', dataIndex: 'userName',width:80, align:"center", ellipsis:true},
|
||||
{ title: '金额合计', dataIndex: 'totalPrice',width:80, align:"center", },
|
||||
{ title: '含税合计', dataIndex: 'totalTaxLastMoney',width:80, align:"center",
|
||||
customRender:function (text,record,index) {
|
||||
return (record.discountMoney + record.discountLastMoney).toFixed(2);
|
||||
}
|
||||
},
|
||||
{ title: '待退金额', dataIndex: 'needBackMoney',width:80, align:"center",
|
||||
customRender:function (text,record,index) {
|
||||
let needBackMoney = record.discountLastMoney + record.otherMoney
|
||||
return needBackMoney? needBackMoney.toFixed(2):''
|
||||
}
|
||||
},
|
||||
{ title: '退款', dataIndex: 'changeAmount',width:50, align:"center", },
|
||||
{ title: '状态', dataIndex: 'status', width: 80, align: "center",
|
||||
scopedSlots: { customRender: 'customRenderStatus' }
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align:"center", width: 160,
|
||||
scopedSlots: { customRender: 'action' },
|
||||
}
|
||||
],
|
||||
url: {
|
||||
list: "/erp/depotHead/list",
|
||||
delete: "/erp/depotHead/delete",
|
||||
deleteBatch: "/erp/depotHead/deleteBatch",
|
||||
batchSetStatusUrl: "/erp/depotHead/batchSetStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
created () {
|
||||
this.initCustomer()
|
||||
this.getDepotData()
|
||||
this.initUser()
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
@import '~@assets/less/common.less'
|
||||
</style>
|
||||
@@ -0,0 +1,245 @@
|
||||
<!-- create jishenghua-->
|
||||
<template>
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="24">
|
||||
<a-card :style="cardStyle" :bordered="false">
|
||||
<!-- 查询区域 -->
|
||||
<div class="table-page-search-wrapper">
|
||||
<!-- 搜索区域 -->
|
||||
<a-form layout="inline" @keyup.enter.native="searchQuery">
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据编号" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入单据编号" v-model="queryParam.number"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="商品信息" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入物料编码、名称、规格、型号" v-model="queryParam.materialParam"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据日期" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-range-picker
|
||||
style="width:100%"
|
||||
v-model="queryParam.createTimeRange"
|
||||
format="YYYY-MM-DD"
|
||||
:placeholder="['开始时间', '结束时间']"
|
||||
@change="onDateChange"
|
||||
@ok="onDateOk"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<template v-if="toggleSearchStatus">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="客户" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择客户" showSearch optionFilterProp="children" v-model="queryParam.organId">
|
||||
<a-select-option v-for="(item,index) in cusList" :key="index" :value="item.id">
|
||||
{{ item.supplier }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="操作员" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择操作员" showSearch optionFilterProp="children" v-model="queryParam.creator">
|
||||
<a-select-option v-for="(item,index) in userList" :key="index" :value="item.id">
|
||||
{{ item.userName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</template>
|
||||
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-button type="primary" @click="searchQuery">查询</a-button>
|
||||
<a-button style="margin-left: 8px" @click="searchReset">重置</a-button>
|
||||
<a @click="handleToggleSearch" style="margin-left: 8px">
|
||||
{{ toggleSearchStatus ? '收起' : '展开' }}
|
||||
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
|
||||
</a>
|
||||
</a-col>
|
||||
</span>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
<!-- 操作按钮区域 -->
|
||||
<div class="table-operator" style="margin-top: 5px">
|
||||
<a-button v-if="btnEnableList.indexOf(1)>-1" @click="myHandleAdd" type="primary" icon="plus">新增</a-button>
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" v-if="btnEnableList.indexOf(1)>-1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
|
||||
<a-menu-item key="2" v-if="btnEnableList.indexOf(2)>-1" @click="batchSetStatus(1)"><a-icon type="check"/>审核</a-menu-item>
|
||||
<a-menu-item key="3" v-if="btnEnableList.indexOf(7)>-1" @click="batchSetStatus(0)"><a-icon type="stop"/>反审核</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button>
|
||||
批量操作 <a-icon type="down" />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
<a-tooltip placement="left" title="销售订单不涉及收款金额,销售订单可以转销售出库单,但需要先对销售订单进行审核。
|
||||
勾选单据之后可以进行批量操作(删除、审核、反审核)" slot="action">
|
||||
<a-icon v-if="btnEnableList.indexOf(1)>-1" type="question-circle" style="font-size:20px;float:right;" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<!-- table区域-begin -->
|
||||
<a-row>
|
||||
<a-col :md="2.5" :sm="24">
|
||||
<list-columns-setter v-model="columns" :def-columns="columns" style="float: right;"/>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div>
|
||||
<a-table
|
||||
ref="table"
|
||||
size="middle"
|
||||
bordered
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:components="drag(columns)"
|
||||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:scroll="scroll"
|
||||
:loading="loading"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
|
||||
@change="handleTableChange">
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<a @click="myHandleDetail(record, '销售订单')">查看</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleEdit(record)">编辑</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleCopyAdd(record)">复制</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a-popconfirm v-if="btnEnableList.indexOf(1)>-1" title="确定删除吗?" @confirm="() => myHandleDelete(record)">
|
||||
<a>删除</a>
|
||||
</a-popconfirm>
|
||||
</span>
|
||||
<template slot="customRenderStatus" slot-scope="status">
|
||||
<a-tag v-if="status == '0'" color="red">未审核</a-tag>
|
||||
<a-tag v-if="status == '1'" color="green">已审核</a-tag>
|
||||
<a-tag v-if="status == '2'" color="cyan">完成销售</a-tag>
|
||||
<a-tag v-if="status == '3'" color="blue">部分销售</a-tag>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
<!-- table区域-end -->
|
||||
<!-- 表单区域 -->
|
||||
<sale-order-modal ref="modalForm" @ok="modalFormOk"></sale-order-modal>
|
||||
<bill-detail ref="modalDetail"></bill-detail>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
<script>
|
||||
import SaleOrderModal from './modules/SaleOrderModal'
|
||||
import BillDetail from './dialog/BillDetail'
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
import { BillListMixin } from './mixins/BillListMixin'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
import ListColumnsSetter from '@/components/ListColumnsSetter'
|
||||
import tableDragResizeMixin from '@/mixins/tableDragResizeMixin'
|
||||
export default {
|
||||
name: "SaleOrderList",
|
||||
mixins:[JeecgListMixin,BillListMixin,tableDragResizeMixin],
|
||||
components: {
|
||||
SaleOrderModal,
|
||||
BillDetail,
|
||||
JDate,
|
||||
ListColumnsSetter
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
// 查询条件
|
||||
queryParam: {
|
||||
number: "",
|
||||
materialParam: "",
|
||||
type: "其它",
|
||||
subType: "销售订单",
|
||||
roleType: Vue.ls.get('roleType'),
|
||||
organId: "",
|
||||
depotId: "",
|
||||
creator: ""
|
||||
},
|
||||
labelCol: {
|
||||
span: 5
|
||||
},
|
||||
wrapperCol: {
|
||||
span: 18,
|
||||
offset: 1
|
||||
},
|
||||
// 表头
|
||||
columns: [
|
||||
{ title: '客户', dataIndex: 'organName',width:120, align:'center', ellipsis:true},
|
||||
{ title: '单据编号', dataIndex: 'number',width:160, align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
if(record.linkNumber) {
|
||||
return text + "[转]";
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '商品信息', dataIndex: 'materialsList',width:220, align:'center', ellipsis:true,
|
||||
customRender:function (text,record,index) {
|
||||
if(text) {
|
||||
return text.replace(",",",");
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '单据日期', dataIndex: 'operTimeStr',width:145, align:'center',},
|
||||
{ title: '操作员', dataIndex: 'userName',width:80, align:'center', ellipsis:true},
|
||||
{ title: '金额合计', dataIndex: 'totalPrice',width:80, align:'center',},
|
||||
{ title: '含税合计', dataIndex: 'totalTaxLastMoney',width:80, align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
if(record.discountLastMoney) {
|
||||
return (record.discountMoney + record.discountLastMoney).toFixed(2);
|
||||
} else {
|
||||
return record.totalPrice;
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '状态', dataIndex: 'status', width: 70, align: "center",
|
||||
scopedSlots: { customRender: 'customRenderStatus' }
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align:"center", width: 150,
|
||||
scopedSlots: { customRender: 'action' },
|
||||
}
|
||||
],
|
||||
url: {
|
||||
list: "/erp/depotHead/list",
|
||||
delete: "/erp/depotHead/delete",
|
||||
deleteBatch: "/erp/depotHead/deleteBatch",
|
||||
batchSetStatusUrl: "/erp/depotHead/batchSetStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initCustomer()
|
||||
this.initUser()
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
methods: {
|
||||
myHandleEdit(record) {
|
||||
if(record.status === '0') {
|
||||
this.$refs.modalForm.action = "edit";
|
||||
this.handleEdit(record);
|
||||
} else {
|
||||
this.$message.warning("抱歉,只有未审核的单据才能编辑!")
|
||||
}
|
||||
},
|
||||
myHandleDelete(record) {
|
||||
if(record.status === '0') {
|
||||
this.handleDelete(record.id)
|
||||
} else {
|
||||
this.$message.warning("抱歉,只有未审核的单据才能删除!")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
@import '~@assets/less/common.less'
|
||||
</style>
|
||||
@@ -0,0 +1,254 @@
|
||||
<!-- create j i s h e n g h u a -->
|
||||
<template>
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="24">
|
||||
<a-card :style="cardStyle" :bordered="false">
|
||||
<!-- 查询区域 -->
|
||||
<div class="table-page-search-wrapper">
|
||||
<!-- 搜索区域 -->
|
||||
<a-form layout="inline" @keyup.enter.native="searchQuery">
|
||||
<a-row :gutter="24">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据编号" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入单据编号" v-model="queryParam.number"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="商品信息" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入物料编码、名称、规格、型号" v-model="queryParam.materialParam"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="单据日期" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-range-picker
|
||||
style="width:100%"
|
||||
v-model="queryParam.createTimeRange"
|
||||
format="YYYY-MM-DD"
|
||||
:placeholder="['开始时间', '结束时间']"
|
||||
@change="onDateChange"
|
||||
@ok="onDateOk"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<template v-if="toggleSearchStatus">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="客户" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择客户" showSearch optionFilterProp="children" v-model="queryParam.organId">
|
||||
<a-select-option v-for="(item,index) in cusList" :key="index" :value="item.id">
|
||||
{{ item.supplier }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="仓库名称" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="请选择仓库" showSearch optionFilterProp="children" v-model="queryParam.depotId">
|
||||
<a-select-option v-for="(depot,index) in depotList" :key="index" :value="depot.id">
|
||||
{{ depot.depotName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="操作员" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-select placeholder="选择操作员" showSearch optionFilterProp="children" v-model="queryParam.creator">
|
||||
<a-select-option v-for="(item,index) in userList" :key="index" :value="item.id">
|
||||
{{ item.userName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-form-item label="关联订单" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input placeholder="请输入关联订单" v-model="queryParam.linkNumber"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</template>
|
||||
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
|
||||
<a-col :md="6" :sm="24">
|
||||
<a-button type="primary" @click="searchQuery">查询</a-button>
|
||||
<a-button style="margin-left: 8px" @click="searchReset">重置</a-button>
|
||||
<a @click="handleToggleSearch" style="margin-left: 8px">
|
||||
{{ toggleSearchStatus ? '收起' : '展开' }}
|
||||
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
|
||||
</a>
|
||||
</a-col>
|
||||
</span>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
<!-- 操作按钮区域 -->
|
||||
<div class="table-operator" style="margin-top: 5px">
|
||||
<a-button v-if="btnEnableList.indexOf(1)>-1" @click="myHandleAdd" type="primary" icon="plus">新增</a-button>
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" v-if="btnEnableList.indexOf(1)>-1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
|
||||
<a-menu-item key="2" v-if="btnEnableList.indexOf(2)>-1" @click="batchSetStatus(1)"><a-icon type="check"/>审核</a-menu-item>
|
||||
<a-menu-item key="3" v-if="btnEnableList.indexOf(7)>-1" @click="batchSetStatus(0)"><a-icon type="stop"/>反审核</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button>
|
||||
批量操作 <a-icon type="down" />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
<a-tooltip placement="left" title="销售出库单可以由销售订单转过来,也可以单独创建。
|
||||
销售出库单据中的仓库列表只显示当前用户有权限的仓库。销售出库单可以使用多账户收款。
|
||||
勾选单据之后可以进行批量操作(删除、审核、反审核)" slot="action">
|
||||
<a-icon v-if="btnEnableList.indexOf(1)>-1" type="question-circle" style="font-size:20px;float:right;" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<!-- table区域-begin -->
|
||||
<a-row>
|
||||
<a-col :md="2.5" :sm="24">
|
||||
<list-columns-setter v-model="columns" :def-columns="columns" style="float: right;"/>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div>
|
||||
<a-table
|
||||
ref="table"
|
||||
size="middle"
|
||||
bordered
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:components="drag(columns)"
|
||||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:scroll="scroll"
|
||||
:loading="loading"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
|
||||
@change="handleTableChange">
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<a @click="myHandleDetail(record, '销售出库')">查看</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleEdit(record)">编辑</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a v-if="btnEnableList.indexOf(1)>-1" @click="myHandleCopyAdd(record)">复制</a>
|
||||
<a-divider v-if="btnEnableList.indexOf(1)>-1" type="vertical" />
|
||||
<a-popconfirm v-if="btnEnableList.indexOf(1)>-1" title="确定删除吗?" @confirm="() => myHandleDelete(record)">
|
||||
<a>删除</a>
|
||||
</a-popconfirm>
|
||||
</span>
|
||||
<template slot="customRenderStatus" slot-scope="status">
|
||||
<a-tag v-if="status == '0'" color="red">未审核</a-tag>
|
||||
<a-tag v-if="status == '1'" color="green">已审核</a-tag>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
<!-- table区域-end -->
|
||||
<!-- 表单区域 -->
|
||||
<sale-out-modal ref="modalForm" @ok="modalFormOk"></sale-out-modal>
|
||||
<bill-detail ref="modalDetail"></bill-detail>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
<script>
|
||||
import SaleOutModal from './modules/SaleOutModal'
|
||||
import BillDetail from './dialog/BillDetail'
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
import { BillListMixin } from './mixins/BillListMixin'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
import ListColumnsSetter from '@/components/ListColumnsSetter'
|
||||
import tableDragResizeMixin from '@/mixins/tableDragResizeMixin'
|
||||
export default {
|
||||
name: "SaleOutList",
|
||||
mixins:[JeecgListMixin,BillListMixin,tableDragResizeMixin],
|
||||
components: {
|
||||
SaleOutModal,
|
||||
BillDetail,
|
||||
JDate,
|
||||
ListColumnsSetter
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
// 查询条件
|
||||
queryParam: {
|
||||
number: "",
|
||||
materialParam: "",
|
||||
type: "出库",
|
||||
subType: "销售",
|
||||
roleType: Vue.ls.get('roleType'),
|
||||
organId: "",
|
||||
depotId: "",
|
||||
creator: "",
|
||||
linkNumber: ""
|
||||
},
|
||||
labelCol: {
|
||||
span: 5
|
||||
},
|
||||
wrapperCol: {
|
||||
span: 18,
|
||||
offset: 1
|
||||
},
|
||||
// 表头
|
||||
columns: [
|
||||
{ title: '客户', dataIndex: 'organName',width:120, align:'center', ellipsis:true},
|
||||
{ title: '单据编号', dataIndex: 'number',width:160, align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
if(record.linkNumber) {
|
||||
return text + "[订]";
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '商品信息', dataIndex: 'materialsList',width:220, align:'center', ellipsis:true,
|
||||
customRender:function (text,record,index) {
|
||||
if(text) {
|
||||
return text.replace(",",",");
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '单据日期', dataIndex: 'operTimeStr',width:145, align:'center',},
|
||||
{ title: '操作员', dataIndex: 'userName',width:80, align:'center', ellipsis:true},
|
||||
{ title: '金额合计', dataIndex: 'totalPrice',width:80, align:'center',},
|
||||
{ title: '含税合计', dataIndex: 'totalTaxLastMoney',width:80, align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
return (record.discountMoney + record.discountLastMoney).toFixed(2);
|
||||
}
|
||||
},
|
||||
{ title: '待收金额', dataIndex: 'needOutMoney',width:80, align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
let needOutMoney = record.discountLastMoney + record.otherMoney
|
||||
return needOutMoney? needOutMoney.toFixed(2):''
|
||||
}
|
||||
},
|
||||
{ title: '收款', dataIndex: 'changeAmount',width:60, align:'center',},
|
||||
{ title: '欠款', dataIndex: 'debt',width:60, align:'center',
|
||||
customRender:function (text,record,index) {
|
||||
let debt = record.discountLastMoney + record.otherMoney - record.changeAmount
|
||||
return debt? debt.toFixed(2):''
|
||||
}
|
||||
},
|
||||
{ title: '状态', dataIndex: 'status', width: 80, align: "center",
|
||||
scopedSlots: { customRender: 'customRenderStatus' }
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align:"center", width: 180,
|
||||
scopedSlots: { customRender: 'action' },
|
||||
}
|
||||
],
|
||||
url: {
|
||||
list: "/erp/depotHead/list",
|
||||
delete: "/erp/depotHead/delete",
|
||||
deleteBatch: "/erp/depotHead/deleteBatch",
|
||||
batchSetStatusUrl: "/erp/depotHead/batchSetStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
created() {
|
||||
this.initCustomer()
|
||||
this.getDepotData()
|
||||
this.initUser()
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
@import '~@assets/less/common.less'
|
||||
</style>
|
||||
@@ -0,0 +1,112 @@
|
||||
<template>
|
||||
<a-modal
|
||||
:title="title"
|
||||
:width="500"
|
||||
:visible="visible"
|
||||
:confirmLoading="confirmLoading"
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
cancelText="关闭"
|
||||
wrapClassName="ant-modal-cust-warp"
|
||||
style="top:30%;height: 35%;overflow-y: hidden">
|
||||
<template slot="footer">
|
||||
<a-button key="back" v-if="isReadOnly" @click="handleCancel">
|
||||
关闭
|
||||
</a-button>
|
||||
</template>
|
||||
<a-spin :spinning="confirmLoading">
|
||||
<a-form :form="form" id="batchSetDepot">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="仓库名称">
|
||||
<a-select placeholder="请选择仓库" v-decorator="[ 'depotId', validatorRules.depotId ]" showSearch optionFilterProp="children">
|
||||
<a-select-option v-for="(depot,index) in depotList" :key="index" :value="depot.id">
|
||||
{{ depot.depotName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
</a-modal>
|
||||
</template>
|
||||
<script>
|
||||
import pick from 'lodash.pick'
|
||||
import { getAction } from '@/api/manage'
|
||||
export default {
|
||||
name: "BatchSetDepot",
|
||||
data () {
|
||||
return {
|
||||
title:"操作",
|
||||
visible: false,
|
||||
model: {},
|
||||
depotList: [],
|
||||
isReadOnly: false,
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 5 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
confirmLoading: false,
|
||||
form: this.$form.createForm(this),
|
||||
validatorRules:{
|
||||
depotId:{
|
||||
rules: [
|
||||
{ required: true, message: '请选择仓库!' }
|
||||
]
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
created () {
|
||||
},
|
||||
methods: {
|
||||
getDepotData() {
|
||||
getAction('/depot/findDepotByCurrentUser').then((res)=>{
|
||||
if(res.code === 200){
|
||||
this.depotList = res.data;
|
||||
}else{
|
||||
this.$message.info(res.data);
|
||||
}
|
||||
})
|
||||
},
|
||||
add () {
|
||||
this.edit({});
|
||||
this.getDepotData()
|
||||
},
|
||||
edit (record) {
|
||||
this.form.resetFields();
|
||||
this.model = Object.assign({}, record);
|
||||
this.visible = true;
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue(pick(this.model, 'depotId'))
|
||||
});
|
||||
},
|
||||
close () {
|
||||
this.$emit('close');
|
||||
this.visible = false;
|
||||
},
|
||||
handleOk () {
|
||||
const that = this;
|
||||
// 触发表单验证
|
||||
this.form.validateFields((err, values) => {
|
||||
if (!err) {
|
||||
that.confirmLoading = true;
|
||||
let formData = Object.assign(this.model, values);
|
||||
let depotId = formData.depotId
|
||||
that.$emit('ok', depotId);
|
||||
that.confirmLoading = false;
|
||||
that.close();
|
||||
}
|
||||
})
|
||||
},
|
||||
handleCancel () {
|
||||
this.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<a-modal
|
||||
:title="title"
|
||||
:width="width"
|
||||
:visible="visible"
|
||||
@cancel="handleCancel"
|
||||
cancelText="关闭"
|
||||
wrapClassName="ant-modal-cust-warp"
|
||||
style="top:5%;height: 100%;overflow-y: hidden">
|
||||
<template slot="footer">
|
||||
<a-button key="back" @click="handleCancel">取消</a-button>
|
||||
</template>
|
||||
<a-form :form="form">
|
||||
<template>
|
||||
<iframe :src="billPrintUrl" width="100%" :height="height" frameborder="0" scrolling="no"></iframe>
|
||||
</template>
|
||||
<template>
|
||||
<a-row>
|
||||
<a-col>
|
||||
<a-form-item>
|
||||
<a-input v-decorator="['id']" hidden/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import pick from 'lodash.pick'
|
||||
export default {
|
||||
name: 'BillPrintIframe',
|
||||
data () {
|
||||
return {
|
||||
title: "三联打印预览",
|
||||
width: '1550px',
|
||||
visible: false,
|
||||
billPrintUrl: '',
|
||||
height: "",
|
||||
model: {},
|
||||
form: this.$form.createForm(this),
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
created () {
|
||||
},
|
||||
methods: {
|
||||
show(record, billPrintUrl, billPrintHeight) {
|
||||
this.height = billPrintHeight
|
||||
this.billPrintUrl = billPrintUrl
|
||||
this.visible = true;
|
||||
this.model = Object.assign({}, record);
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue(pick(this.model,'id'))
|
||||
});
|
||||
},
|
||||
handleCancel() {
|
||||
this.close()
|
||||
},
|
||||
close() {
|
||||
this.$emit('close');
|
||||
this.visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,159 @@
|
||||
<template>
|
||||
<a-modal
|
||||
:title="title"
|
||||
:width="1250"
|
||||
:visible="visible"
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
cancelText="关闭"
|
||||
wrapClassName="ant-modal-cust-warp"
|
||||
style="top:5%;height: 100%;overflow-y: hidden">
|
||||
<!-- table区域-begin -->
|
||||
<a-table
|
||||
bordered
|
||||
ref="table"
|
||||
size="middle"
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:loading="loading"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange, type: getType}"
|
||||
:customRow="rowAction"
|
||||
@change="handleTableChange">
|
||||
<template slot="customRenderStatus" slot-scope="status">
|
||||
<a-tag v-if="status === '0'" color="red">未审核</a-tag>
|
||||
<a-tag v-if="status === '1'" color="green">已审核</a-tag>
|
||||
<a-tag v-if="status === '2' && queryParam.subType === '采购订单'" color="cyan">完成采购</a-tag>
|
||||
<a-tag v-if="status === '2' && queryParam.subType === '销售订单'" color="cyan">完成销售</a-tag>
|
||||
<a-tag v-if="status === '3' && queryParam.subType === '采购订单'" color="blue">部分采购</a-tag>
|
||||
<a-tag v-if="status === '3' && queryParam.subType === '销售订单'" color="blue">部分销售</a-tag>
|
||||
</template>
|
||||
</a-table>
|
||||
<!-- table区域-end -->
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
export default {
|
||||
name: 'LinkBillList',
|
||||
mixins:[JeecgListMixin],
|
||||
data () {
|
||||
return {
|
||||
title: "操作",
|
||||
visible: false,
|
||||
disableMixinCreated: true,
|
||||
selectedRowKeys: [],
|
||||
selectionRows: [],
|
||||
selectBillRows: [],
|
||||
selectBillIds: '',
|
||||
queryParam: {
|
||||
number: "",
|
||||
searchMaterial: "",
|
||||
type: "",
|
||||
subType: "",
|
||||
status: ""
|
||||
},
|
||||
// 表头
|
||||
columns: [
|
||||
{
|
||||
title: '#',
|
||||
dataIndex: '',
|
||||
key:'rowIndex',
|
||||
width:40,
|
||||
align:"center",
|
||||
customRender:function (t,r,index) {
|
||||
return parseInt(index)+1;
|
||||
}
|
||||
},
|
||||
{ title: '', dataIndex: 'organName',width:120},
|
||||
{ title: '单据编号', dataIndex: 'number',width:150},
|
||||
{ title: '商品信息', dataIndex: 'materialsList',width:280, ellipsis:true,
|
||||
customRender:function (text,record,index) {
|
||||
if(text) {
|
||||
return text.replace(",",",");
|
||||
}
|
||||
}
|
||||
},
|
||||
{ title: '单据日期', dataIndex: 'operTimeStr',width:145},
|
||||
{ title: '操作员', dataIndex: 'userName',width:70},
|
||||
{ title: '金额合计', dataIndex: 'totalPrice',width:70},
|
||||
{ title: '状态', dataIndex: 'status', width: 70, align: "center",
|
||||
scopedSlots: { customRender: 'customRenderStatus' }
|
||||
}
|
||||
],
|
||||
url: {
|
||||
list: "/depotHead/list"
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getType: function () {
|
||||
return 'radio';
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
methods: {
|
||||
show(type, subType, organType, status) {
|
||||
this.queryParam.type = type
|
||||
this.queryParam.subType = subType
|
||||
this.queryParam.status = status
|
||||
this.columns[1].title = organType
|
||||
this.model = Object.assign({}, {});
|
||||
this.visible = true;
|
||||
this.loadData(1)
|
||||
},
|
||||
close () {
|
||||
this.$emit('close');
|
||||
this.visible = false;
|
||||
},
|
||||
handleCancel () {
|
||||
this.close()
|
||||
},
|
||||
onSelectChange(selectedRowKeys, selectionRows) {
|
||||
this.selectedRowKeys = selectedRowKeys;
|
||||
this.selectionRows = selectionRows;
|
||||
},
|
||||
handleOk () {
|
||||
this.getSelectBillRows();
|
||||
this.$emit('ok', this.selectBillRows);
|
||||
this.close();
|
||||
},
|
||||
getSelectBillRows() {
|
||||
let dataSource = this.dataSource;
|
||||
let billIds = "";
|
||||
this.selectBillRows = [];
|
||||
for (let i = 0, len = dataSource.length; i < len; i++) {
|
||||
if (this.selectedRowKeys.includes(dataSource[i].id)) {
|
||||
this.selectBillRows.push(dataSource[i]);
|
||||
billIds = billIds + "," + dataSource[i].id
|
||||
}
|
||||
}
|
||||
this.selectBillIds = billIds.substring(1);
|
||||
},
|
||||
rowAction(record, index) {
|
||||
return {
|
||||
on: {
|
||||
click: () => {
|
||||
let arr = []
|
||||
arr.push(record.id)
|
||||
this.selectedRowKeys = arr
|
||||
},
|
||||
dblclick: () => {
|
||||
let arr = []
|
||||
arr.push(record.id)
|
||||
this.selectedRowKeys = arr
|
||||
this.handleOk()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,188 @@
|
||||
<template>
|
||||
<a-modal
|
||||
:title="title"
|
||||
:width="650"
|
||||
:visible="visible"
|
||||
:confirmLoading="confirmLoading"
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
cancelText="关闭"
|
||||
wrapClassName="ant-modal-cust-warp"
|
||||
style="top:20%;height: 60%;overflow-y: hidden">
|
||||
<a-spin :spinning="confirmLoading">
|
||||
<a-form :form="form">
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="12" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="结算账户1">
|
||||
<a-select style="width:185px;" placeholder="请选择结算账户" v-decorator="[ 'oneAccountId' ]" :dropdownMatchSelectWidth="false" allowClear>
|
||||
<a-select-option v-for="(item,index) in accountList" :key="index" :value="item.id">
|
||||
{{ item.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="结算金额">
|
||||
<a-input-number placeholder="请输入金额" v-decorator.trim="[ 'oneAccountPrice' ]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="12" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="结算账户2">
|
||||
<a-select style="width:185px;" placeholder="请选择结算账户" v-decorator="[ 'twoAccountId' ]" :dropdownMatchSelectWidth="false" allowClear>
|
||||
<a-select-option v-for="(item,index) in accountList" :key="index" :value="item.id">
|
||||
{{ item.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="结算金额">
|
||||
<a-input-number placeholder="请输入金额" v-decorator.trim="[ 'twoAccountPrice' ]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="12" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="结算账户3">
|
||||
<a-select style="width:185px;" placeholder="请选择结算账户" v-decorator="[ 'threeAccountId' ]" :dropdownMatchSelectWidth="false" allowClear>
|
||||
<a-select-option v-for="(item,index) in accountList" :key="index" :value="item.id">
|
||||
{{ item.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="结算金额">
|
||||
<a-input-number placeholder="请输入金额" v-decorator.trim="[ 'threeAccountPrice' ]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
</a-modal>
|
||||
</template>
|
||||
<script>
|
||||
import pick from 'lodash.pick'
|
||||
import {getAccount} from '@/api/api'
|
||||
export default {
|
||||
name: 'ManyAccountModal',
|
||||
data () {
|
||||
return {
|
||||
title:"操作",
|
||||
visible: false,
|
||||
model: {},
|
||||
accountList: [],
|
||||
accountIdList: [],
|
||||
accountMoneyList: [],
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 8 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
confirmLoading: false,
|
||||
form: this.$form.createForm(this)
|
||||
}
|
||||
},
|
||||
created () {
|
||||
},
|
||||
methods: {
|
||||
edit (idStr, moneyStr) {
|
||||
this.initAccount()
|
||||
this.form.resetFields();
|
||||
this.model = Object.assign({}, {});
|
||||
let idList = [], moneyList = []
|
||||
if(idStr && idStr.indexOf(',')>-1) {
|
||||
idList = idStr.split(",")
|
||||
moneyList = moneyStr.split(",")
|
||||
} else {
|
||||
idList = idStr
|
||||
moneyList = moneyStr
|
||||
}
|
||||
if(idList[0]) {this.model.oneAccountId = idList[0]-0}
|
||||
if(idList[1]) {this.model.twoAccountId = idList[1]-0}
|
||||
if(idList[2]) {this.model.threeAccountId = idList[2]-0}
|
||||
if(moneyList[0]) {this.model.oneAccountPrice = Math.abs(moneyList[0])}
|
||||
if(moneyList[1]) {this.model.twoAccountPrice = Math.abs(moneyList[1])}
|
||||
if(moneyList[2]) {this.model.threeAccountPrice = Math.abs(moneyList[2])}
|
||||
this.visible = true;
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue(pick(this.model,'oneAccountId','oneAccountPrice',
|
||||
'twoAccountId','twoAccountPrice','threeAccountId','threeAccountPrice'))
|
||||
});
|
||||
},
|
||||
close () {
|
||||
this.$emit('close');
|
||||
this.visible = false;
|
||||
},
|
||||
handleOk () {
|
||||
const that = this;
|
||||
// 触发表单验证
|
||||
this.form.validateFields((err, values) => {
|
||||
if (!err) {
|
||||
let allPrice = 0
|
||||
that.confirmLoading = true;
|
||||
that.accountIdList = []
|
||||
that.accountMoneyList = []
|
||||
let formData = Object.assign(this.model, values);
|
||||
if(formData.oneAccountId!==undefined) {
|
||||
that.accountIdList.push(formData.oneAccountId)
|
||||
}
|
||||
if(formData.twoAccountId!==undefined) {
|
||||
that.accountIdList.push(formData.twoAccountId)
|
||||
}
|
||||
if(formData.threeAccountId!==undefined) {
|
||||
that.accountIdList.push(formData.threeAccountId)
|
||||
}
|
||||
if(formData.oneAccountPrice!==undefined) {
|
||||
that.accountMoneyList.push(formData.oneAccountPrice)
|
||||
allPrice = allPrice + formData.oneAccountPrice
|
||||
}
|
||||
if(formData.twoAccountPrice!==undefined) {
|
||||
that.accountMoneyList.push(formData.twoAccountPrice)
|
||||
allPrice = allPrice + formData.twoAccountPrice
|
||||
}
|
||||
if(formData.threeAccountPrice!==undefined) {
|
||||
that.accountMoneyList.push(formData.threeAccountPrice)
|
||||
allPrice = allPrice + formData.threeAccountPrice
|
||||
}
|
||||
if(that.accountIdList.length<2 || that.accountMoneyList.length<2) {
|
||||
this.$message.warning('抱歉,多账户结算必须选择两个以上账户和金额!');
|
||||
that.confirmLoading = false;
|
||||
return;
|
||||
}
|
||||
if((formData.oneAccountId && !formData.oneAccountPrice)||
|
||||
(formData.twoAccountId && !formData.twoAccountPrice)||
|
||||
(formData.threeAccountId && !formData.threeAccountPrice)) {
|
||||
this.$message.warning('抱歉,请填写结算金额!');
|
||||
that.confirmLoading = false;
|
||||
return;
|
||||
}
|
||||
that.$emit('ok', that.accountIdList, that.accountMoneyList, allPrice);
|
||||
that.confirmLoading = false;
|
||||
that.close();
|
||||
}
|
||||
})
|
||||
},
|
||||
handleCancel () {
|
||||
this.close()
|
||||
},
|
||||
initAccount(){
|
||||
let that = this;
|
||||
getAccount({}).then((res)=>{
|
||||
if(res && res.code === 200) {
|
||||
that.accountList = res.data.accountList
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,133 @@
|
||||
import Vue from 'vue'
|
||||
import {getAction } from '@/api/manage'
|
||||
import {findBySelectSup, findBySelectCus, findBySelectRetail, getUserList } from '@/api/api'
|
||||
|
||||
export const BillListMixin = {
|
||||
data () {
|
||||
return {
|
||||
supList: [],
|
||||
cusList: [],
|
||||
retailList: [],
|
||||
userList: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
importExcelUrl: function(){
|
||||
return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
|
||||
},
|
||||
|
||||
isBatchDelEnabled: function () {
|
||||
for (let i = 0; i < this.selectedRowKeys.length; i++) {
|
||||
if (!this.selectionRows[i].actionsEnabled.delete) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.removeStatusColumn()
|
||||
},
|
||||
methods: {
|
||||
myHandleAdd() {
|
||||
this.$refs.modalForm.action = "add";
|
||||
this.handleAdd();
|
||||
},
|
||||
myHandleCopyAdd(record) {
|
||||
this.$refs.modalForm.action = "copyAdd";
|
||||
this.$refs.modalForm.edit(record);
|
||||
this.$refs.modalForm.title = "复制新增";
|
||||
this.$refs.modalForm.disableSubmit = false;
|
||||
},
|
||||
myHandleEdit(record) {
|
||||
if(record.status === '0') {
|
||||
this.$refs.modalForm.action = "edit";
|
||||
this.handleEdit(record);
|
||||
} else {
|
||||
this.$message.warning("抱歉,只有未审核的单据才能编辑!")
|
||||
}
|
||||
},
|
||||
myHandleDelete(record) {
|
||||
if(record.status === '0') {
|
||||
this.handleDelete(record.id)
|
||||
} else {
|
||||
this.$message.warning("抱歉,只有未审核的单据才能删除!")
|
||||
}
|
||||
},
|
||||
myHandleDetail(record, type) {
|
||||
this.handleDetail(record, type);
|
||||
},
|
||||
handleApprove(record) {
|
||||
this.$refs.modalForm.action = "approve";
|
||||
this.$refs.modalForm.edit(record);
|
||||
this.$refs.modalForm.title = "审核";
|
||||
},
|
||||
searchReset() {
|
||||
this.queryParam = {
|
||||
type: this.queryParam.type,
|
||||
subType: this.queryParam.subType
|
||||
}
|
||||
this.loadData(1);
|
||||
},
|
||||
onDateChange: function (value, dateString) {
|
||||
this.queryParam.beginTime=dateString[0];
|
||||
this.queryParam.endTime=dateString[1];
|
||||
},
|
||||
onDateOk(value) {
|
||||
console.log(value);
|
||||
},
|
||||
removeStatusColumn() {
|
||||
//没有审核反审核权限的时候直接移除状态列
|
||||
if(this.btnEnableList.indexOf(2)===-1 && this.btnEnableList.indexOf(7)===-1) {
|
||||
let statusIndex = 0
|
||||
for(let i=0; i<this.columns.length; i++){
|
||||
if(this.columns[i].dataIndex === 'status') {
|
||||
statusIndex = i
|
||||
}
|
||||
}
|
||||
//移除状态列
|
||||
this.columns.splice(statusIndex,1)
|
||||
}
|
||||
},
|
||||
initSupplier() {
|
||||
let that = this;
|
||||
findBySelectSup({}).then((res)=>{
|
||||
if(res) {
|
||||
that.supList = res;
|
||||
}
|
||||
});
|
||||
},
|
||||
initCustomer() {
|
||||
let that = this;
|
||||
findBySelectCus({}).then((res)=>{
|
||||
if(res) {
|
||||
that.cusList = res;
|
||||
}
|
||||
});
|
||||
},
|
||||
initRetail() {
|
||||
let that = this;
|
||||
findBySelectRetail({}).then((res)=>{
|
||||
if(res) {
|
||||
that.retailList = res;
|
||||
}
|
||||
});
|
||||
},
|
||||
getDepotData() {
|
||||
getAction('/depot/findDepotByCurrentUser').then((res)=>{
|
||||
if(res.code === 200){
|
||||
this.depotList = res.data;
|
||||
}else{
|
||||
this.$message.info(res.data);
|
||||
}
|
||||
})
|
||||
},
|
||||
initUser() {
|
||||
getUserList({}).then((res)=>{
|
||||
if(res) {
|
||||
this.userList = res;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,748 @@
|
||||
import { FormTypes, getListData } from '@/utils/JEditableTableUtil'
|
||||
import {findBySelectSup,findBySelectCus,findBySelectRetail,getMaterialByBarCode,findStockByDepotAndBarCode,getAccount,
|
||||
getPersonByNumType, getBatchNumberList} from '@/api/api'
|
||||
import { getAction,putAction } from '@/api/manage'
|
||||
import { getMpListShort, getNowFormatDateTime } from "@/utils/util"
|
||||
import Vue from 'vue'
|
||||
|
||||
export const BillModalMixin = {
|
||||
data() {
|
||||
return {
|
||||
action: '',
|
||||
manyAccountBtnStatus: false,
|
||||
supList: [],
|
||||
cusList: [],
|
||||
retailList: [],
|
||||
personList: {
|
||||
options: [],
|
||||
value: ''
|
||||
},
|
||||
depotList: [],
|
||||
accountList: [],
|
||||
accountIdList: [],
|
||||
accountMoneyList: [],
|
||||
billUnitPirce: '',
|
||||
scanBarCode: '',
|
||||
scanStatus: true,
|
||||
isTenant: false,
|
||||
spans: {
|
||||
labelCol1: {span: 2},
|
||||
wrapperCol1: {span: 22},
|
||||
//1_5: 分为1.5列(相当于占了2/3)
|
||||
labelCol1_5: { span: 3 },
|
||||
wrapperCol1_5: { span: 21 },
|
||||
labelCol2: {span: 4},
|
||||
wrapperCol2: {span: 20},
|
||||
labelCol3: {span: 6},
|
||||
wrapperCol3: {span: 18},
|
||||
labelCol6: {span: 12},
|
||||
wrapperCol6: {span: 12}
|
||||
},
|
||||
};
|
||||
},
|
||||
created () {
|
||||
// this.isTenant = userInfo.id === userInfo.tenantId? true:false
|
||||
this.isTenant = true;
|
||||
var that = this
|
||||
document.onkeydown = function (e) {
|
||||
var key = window.event.keyCode
|
||||
if (key === 13) {
|
||||
that.handleOk() // 触发事件
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
readOnly: function() {
|
||||
return this.action !== "add" && this.action !== "edit";
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addInit(amountNum) {
|
||||
getAction('/sequence/buildNumber').then((res) => {
|
||||
if (res && res.code === 200) {
|
||||
this.form.setFieldsValue({'number':amountNum + res.data.defaultNumber})
|
||||
}
|
||||
})
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({'operTime':getNowFormatDateTime(), 'discount': 0,
|
||||
'discountMoney': 0, 'discountLastMoney': 0, 'otherMoney': 0, 'changeAmount': 0, 'debt': 0})
|
||||
})
|
||||
this.$nextTick(() => {
|
||||
getAccount({}).then((res)=>{
|
||||
if(res && res.code === 200) {
|
||||
for (const item of res.data.accountList) {
|
||||
if(item.isDefault){
|
||||
this.form.setFieldsValue({'accountId': Number(item.id)})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
this.accountIdList = []
|
||||
this.accountMoneyList = []
|
||||
this.manyAccountBtnStatus = false
|
||||
},
|
||||
copyAddInit(amountNum) {
|
||||
getAction('/sequence/buildNumber').then((res) => {
|
||||
if (res && res.code === 200) {
|
||||
this.form.setFieldsValue({'number':amountNum + res.data.defaultNumber})
|
||||
}
|
||||
})
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({'operTime':getNowFormatDateTime()})
|
||||
})
|
||||
},
|
||||
/** 查询某个tab的数据 */
|
||||
requestSubTableData(url, params, tab, success) {
|
||||
tab.loading = true
|
||||
getAction(url, params).then(res => {
|
||||
if(res && res.code === 200){
|
||||
tab.dataSource = res.data.rows
|
||||
for(let i=0; i<tab.dataSource.length; i++){
|
||||
let info = tab.dataSource[i]
|
||||
this.changeColumnShow(info)
|
||||
}
|
||||
typeof success === 'function' ? success(res) : ''
|
||||
}
|
||||
}).finally(() => {
|
||||
tab.loading = false
|
||||
})
|
||||
},
|
||||
//改变字段的状态,1-显示 0-隐藏
|
||||
changeFormTypes(columns, key, type) {
|
||||
for(let i=0; i<columns.length; i++){
|
||||
if(columns[i].key === key) {
|
||||
if(type){
|
||||
if(key === 'snList' || key === 'batchNumber') {
|
||||
if(this.prefixNo === 'LSCK' || this.prefixNo === 'CGTH' || this.prefixNo === 'XSCK' || this.prefixNo === 'QTCK') {
|
||||
columns[i].type = FormTypes.popupJsh //显示
|
||||
} else {
|
||||
columns[i].type = FormTypes.input //显示
|
||||
}
|
||||
} else if(key === 'expirationDate') {
|
||||
if(this.prefixNo === 'LSTH' || this.prefixNo === 'CGRK' || this.prefixNo === 'XSTH' || this.prefixNo === 'QTRK') {
|
||||
columns[i].type = FormTypes.date //显示
|
||||
} else {
|
||||
columns[i].type = FormTypes.normal //显示
|
||||
}
|
||||
} else {
|
||||
columns[i].type = FormTypes.normal //显示
|
||||
}
|
||||
} else {
|
||||
columns[i].type = FormTypes.hidden //隐藏
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
initSupplier() {
|
||||
let that = this;
|
||||
findBySelectSup({}).then((res)=>{
|
||||
if(res) {
|
||||
that.supList = res;
|
||||
// this.form.setFieldsValue({'organId': Number(that.supList[0].id)})
|
||||
}
|
||||
});
|
||||
},
|
||||
initCustomer() {
|
||||
let that = this;
|
||||
findBySelectCus({}).then((res)=>{
|
||||
if(res) {
|
||||
that.cusList = res;
|
||||
}
|
||||
});
|
||||
},
|
||||
initRetail() {
|
||||
let that = this;
|
||||
findBySelectRetail({}).then((res)=>{
|
||||
if(res) {
|
||||
that.retailList = res;
|
||||
}
|
||||
});
|
||||
},
|
||||
initSalesman() {
|
||||
let that = this;
|
||||
getPersonByNumType({type:1}).then((res)=>{
|
||||
if(res) {
|
||||
that.personList.options = res;
|
||||
}
|
||||
});
|
||||
},
|
||||
initDepot() {
|
||||
let that = this;
|
||||
getAction('/depot/findDepotByCurrentUser').then((res) => {
|
||||
if(res.code === 200){
|
||||
let arr = res.data
|
||||
for(let item of that.materialTable.columns){
|
||||
if(item.key == 'depotId' || item.key == 'anotherDepotId') {
|
||||
item.options = []
|
||||
for(let i=0; i<arr.length; i++) {
|
||||
let depotInfo = {};
|
||||
depotInfo.value = arr[i].id + '' //注意-此处value必须为字符串格式
|
||||
depotInfo.text = arr[i].depotName
|
||||
depotInfo.title = arr[i].depotName
|
||||
item.options.push(depotInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
initAccount(){
|
||||
let that = this;
|
||||
getAccount({}).then((res)=>{
|
||||
if(res && res.code === 200) {
|
||||
let list = res.data.accountList
|
||||
list.splice(0,0,{id: 0, name: '多账户'})
|
||||
that.accountList = list
|
||||
}
|
||||
})
|
||||
},
|
||||
handleManyAccount(){
|
||||
this.selectAccount(0)
|
||||
},
|
||||
selectAccount(value){
|
||||
if(value === 0) { //多账户
|
||||
this.$refs.manyAccountModalForm.edit(this.accountIdList, this.accountMoneyList)
|
||||
this.$refs.manyAccountModalForm.title = "多账户结算"
|
||||
this.manyAccountBtnStatus = true
|
||||
} else {
|
||||
this.accountIdList = []
|
||||
this.accountMoneyList = []
|
||||
this.manyAccountBtnStatus = false
|
||||
}
|
||||
},
|
||||
manyAccountModalFormOk(idList, moneyList, allPrice) {
|
||||
this.accountIdList = idList
|
||||
this.accountMoneyList = moneyList
|
||||
let discountLastMoney = this.form.getFieldValue('discountLastMoney')-0
|
||||
let otherMoney = this.form.getFieldValue('otherMoney')-0
|
||||
let debt = (discountLastMoney + otherMoney - allPrice).toFixed(2)
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({'changeAmount':allPrice, 'debt':debt})
|
||||
});
|
||||
},
|
||||
addSupplier() {
|
||||
this.$refs.vendorModalForm.add();
|
||||
this.$refs.vendorModalForm.title = "新增供应商";
|
||||
this.$refs.vendorModalForm.disableSubmit = false;
|
||||
},
|
||||
addCustomer() {
|
||||
this.$refs.customerModalForm.add();
|
||||
this.$refs.customerModalForm.title = "新增客户(提醒:如果找不到新添加的客户,请到用户管理检查是否分配了该客户权限)";
|
||||
this.$refs.customerModalForm.disableSubmit = false;
|
||||
},
|
||||
addMember() {
|
||||
this.$refs.memberModalForm.add();
|
||||
this.$refs.memberModalForm.title = "新增会员";
|
||||
this.$refs.memberModalForm.disableSubmit = false;
|
||||
},
|
||||
handleBatchSetDepot() {
|
||||
this.$refs.batchSetDepotModalForm.add();
|
||||
this.$refs.batchSetDepotModalForm.title = "批量设置仓库";
|
||||
this.$refs.batchSetDepotModalForm.disableSubmit = false;
|
||||
},
|
||||
addDepot() {
|
||||
this.$refs.depotModalForm.add();
|
||||
this.$refs.depotModalForm.title = "新增仓库";
|
||||
this.$refs.depotModalForm.disableSubmit = false;
|
||||
},
|
||||
addAccount() {
|
||||
this.$refs.accountModalForm.add();
|
||||
this.$refs.accountModalForm.title = "新增结算账户";
|
||||
this.$refs.accountModalForm.disableSubmit = false;
|
||||
},
|
||||
vendorModalFormOk() {
|
||||
this.initSupplier()
|
||||
},
|
||||
customerModalFormOk() {
|
||||
this.initCustomer()
|
||||
},
|
||||
memberModalFormOk() {
|
||||
this.initRetail()
|
||||
},
|
||||
batchSetDepotModalFormOk(depotId) {
|
||||
this.getAllTable().then(tables => {
|
||||
return getListData(this.form, tables)
|
||||
}).then(allValues => {
|
||||
//获取单据明细列表信息
|
||||
let detailArr = allValues.tablesValue[0].values
|
||||
let barCodes = ''
|
||||
for(let detail of detailArr){
|
||||
barCodes += detail.barCode + ','
|
||||
}
|
||||
if(barCodes) {
|
||||
barCodes = barCodes.substring(0, barCodes.length-1)
|
||||
}
|
||||
let param = {
|
||||
barCode: barCodes,
|
||||
depotId: depotId,
|
||||
mpList: getMpListShort(Vue.ls.get('materialPropertyList')), //扩展属性
|
||||
prefixNo: this.prefixNo
|
||||
}
|
||||
getMaterialByBarCode(param).then((res) => {
|
||||
if (res && res.code === 200) {
|
||||
let mList = res.data
|
||||
//构造新的列表数组,用于存放单据明细信息
|
||||
let newDetailArr = []
|
||||
if(mList && mList.length) {
|
||||
for (let i = 0; i < detailArr.length; i++) {
|
||||
let item = detailArr[i]
|
||||
item.depotId = depotId
|
||||
item.stock = mList[i] ? (mList[i].stock ? mList[i].stock : 0) : 0
|
||||
newDetailArr.push(item)
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < detailArr.length; i++) {
|
||||
let item = detailArr[i]
|
||||
item.depotId = depotId
|
||||
newDetailArr.push(item)
|
||||
}
|
||||
}
|
||||
this.materialTable.dataSource = newDetailArr
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
depotModalFormOk() {
|
||||
this.initDepot()
|
||||
},
|
||||
accountModalFormOk() {
|
||||
this.initAccount()
|
||||
},
|
||||
onAdded(event) {
|
||||
const { row, target } = event
|
||||
getAction('/depot/findDepotByCurrentUser').then((res) => {
|
||||
if (res.code === 200) {
|
||||
let arr = res.data
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if(arr[i].isDefault){
|
||||
target.setValues([{rowKey: row.id, values: {depotId: arr[i].id+''}}])
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
//单元值改变一个字符就触发一次
|
||||
onValueChange(event) {
|
||||
let that = this
|
||||
const { type, row, column, value, target } = event
|
||||
let param,snList,batchNumber,operNumber,unitPrice,allPrice,taxRate,taxMoney,taxLastMoney
|
||||
switch(column.key) {
|
||||
case "depotId":
|
||||
if(row.barCode){
|
||||
that.getStockByDepotBarCode(row, target)
|
||||
}
|
||||
break;
|
||||
case "barCode":
|
||||
param = {
|
||||
barCode: value,
|
||||
mpList: getMpListShort(Vue.ls.get('materialPropertyList')), //扩展属性
|
||||
prefixNo: this.prefixNo
|
||||
}
|
||||
getMaterialByBarCode(param).then((res) => {
|
||||
if (res && res.code === 200) {
|
||||
let mList = res.data
|
||||
if (value.indexOf(',') > -1) {
|
||||
//多个物料编码
|
||||
this.$refs.materialDataTable.getValues((error, values) => {
|
||||
values.pop() //移除最后一行数据
|
||||
let mArr = values
|
||||
for (let i = 0; i < mList.length; i++) {
|
||||
let mInfo = mList[i]
|
||||
this.changeColumnShow(mInfo)
|
||||
let mObj = this.parseInfoToObj(mInfo)
|
||||
mObj.depotId = mInfo.depotId
|
||||
mObj.stock = mInfo.stock
|
||||
mObj.barCode = mInfo.mBarCode
|
||||
mArr.push(mObj)
|
||||
}
|
||||
let taxLastMoneyTotal = 0
|
||||
for (let j = 0; j < mArr.length; j++) {
|
||||
taxLastMoneyTotal += mArr[j].taxLastMoney-0
|
||||
//组合和拆分单据给商品类型进行重新赋值
|
||||
if(j===0) {
|
||||
mArr[0].mType = '组合件'
|
||||
} else {
|
||||
mArr[j].mType = '普通子件'
|
||||
}
|
||||
}
|
||||
this.materialTable.dataSource = mArr
|
||||
target.statisticsColumns.taxLastMoney = taxLastMoneyTotal
|
||||
that.autoChangePrice(target)
|
||||
})
|
||||
} else {
|
||||
//单个物料编码
|
||||
findStockByDepotAndBarCode({ depotId: row.depotId, barCode: row.barCode }).then((res) => {
|
||||
if (res && res.code === 200) {
|
||||
let mArr = []
|
||||
let mInfo = mList[0]
|
||||
this.changeColumnShow(mInfo)
|
||||
let mInfoEx = this.parseInfoToObj(mInfo)
|
||||
mInfoEx.stock = res.data.stock
|
||||
mInfoEx.barCode = row.barCode
|
||||
let mObj = {
|
||||
rowKey: row.id,
|
||||
values: mInfoEx
|
||||
}
|
||||
mArr.push(mObj)
|
||||
target.setValues(mArr);
|
||||
target.recalcAllStatisticsColumns()
|
||||
that.autoChangePrice(target)
|
||||
target.autoSelectBySpecialKey('operNumber')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
case "snList":
|
||||
snList = value
|
||||
if(snList) {
|
||||
let snArr = snList.split(',')
|
||||
operNumber = snArr.length
|
||||
taxRate = row.taxRate-0 //税率
|
||||
unitPrice = row.unitPrice-0 //单价
|
||||
allPrice = (unitPrice*operNumber).toFixed(2)-0
|
||||
taxMoney =((taxRate*0.01)*allPrice).toFixed(2)-0
|
||||
taxLastMoney = (allPrice + taxMoney).toFixed(2)-0
|
||||
target.setValues([{rowKey: row.id, values: {operNumber: operNumber, allPrice: allPrice, taxMoney: taxMoney, taxLastMoney: taxLastMoney}}])
|
||||
target.recalcAllStatisticsColumns()
|
||||
that.autoChangePrice(target)
|
||||
}
|
||||
break;
|
||||
case "batchNumber":
|
||||
batchNumber = value
|
||||
getBatchNumberList({name:'', depotId: row.depotId, barCode: row.barCode, batchNumber: batchNumber}).then((res) => {
|
||||
if (res && res.code === 200) {
|
||||
if(res.data && res.data.rows) {
|
||||
let info = res.data.rows[0]
|
||||
operNumber = info.totalNum
|
||||
taxRate = row.taxRate-0 //税率
|
||||
unitPrice = row.unitPrice-0 //单价
|
||||
allPrice = (unitPrice*operNumber).toFixed(2)-0
|
||||
taxMoney =((taxRate*0.01)*allPrice).toFixed(2)-0
|
||||
taxLastMoney = (allPrice + taxMoney).toFixed(2)-0
|
||||
target.setValues([{rowKey: row.id, values: {expirationDate: info.expirationDateStr, operNumber: operNumber,
|
||||
allPrice: allPrice, taxMoney: taxMoney, taxLastMoney: taxLastMoney}}])
|
||||
target.recalcAllStatisticsColumns()
|
||||
that.autoChangePrice(target)
|
||||
}
|
||||
}
|
||||
})
|
||||
break;
|
||||
case "operNumber":
|
||||
operNumber = value-0
|
||||
taxRate = row.taxRate-0 //税率
|
||||
unitPrice = row.unitPrice-0 //单价
|
||||
allPrice = (unitPrice*operNumber).toFixed(2)-0
|
||||
taxMoney =((taxRate*0.01)*allPrice).toFixed(2)-0
|
||||
taxLastMoney = (allPrice + taxMoney).toFixed(2)-0
|
||||
target.setValues([{rowKey: row.id, values: {allPrice: allPrice, taxMoney: taxMoney, taxLastMoney: taxLastMoney}}])
|
||||
target.recalcAllStatisticsColumns()
|
||||
that.autoChangePrice(target)
|
||||
break;
|
||||
case "unitPrice":
|
||||
operNumber = row.operNumber-0 //数量
|
||||
unitPrice = value-0 //单价
|
||||
taxRate = row.taxRate-0 //税率
|
||||
allPrice = (unitPrice*operNumber).toFixed(2)-0
|
||||
taxMoney =((taxRate*0.01)*allPrice).toFixed(2)-0
|
||||
taxLastMoney = (allPrice + taxMoney).toFixed(2)-0
|
||||
target.setValues([{rowKey: row.id, values: {allPrice: allPrice, taxMoney: taxMoney, taxLastMoney: taxLastMoney}}])
|
||||
target.recalcAllStatisticsColumns()
|
||||
that.autoChangePrice(target)
|
||||
break;
|
||||
case "allPrice":
|
||||
operNumber = row.operNumber-0 //数量
|
||||
taxRate = row.taxRate-0 //税率
|
||||
allPrice = value-0
|
||||
unitPrice = (allPrice/operNumber).toFixed(6)-0 //单价
|
||||
taxMoney =((taxRate*0.01)*allPrice).toFixed(2)-0
|
||||
taxLastMoney = (allPrice + taxMoney).toFixed(2)-0
|
||||
target.setValues([{rowKey: row.id, values: {unitPrice: unitPrice, taxMoney: taxMoney, taxLastMoney: taxLastMoney}}])
|
||||
target.recalcAllStatisticsColumns()
|
||||
that.autoChangePrice(target)
|
||||
break;
|
||||
case "taxRate":
|
||||
operNumber = row.operNumber-0 //数量
|
||||
allPrice = row.allPrice-0
|
||||
unitPrice = row.unitPrice-0
|
||||
taxRate = value-0 //税率
|
||||
taxMoney =((taxRate*0.01)*allPrice).toFixed(2)-0
|
||||
taxLastMoney = (allPrice + taxMoney).toFixed(2)-0
|
||||
target.setValues([{rowKey: row.id, values: {taxMoney: taxMoney, taxLastMoney: taxLastMoney}}])
|
||||
target.recalcAllStatisticsColumns()
|
||||
that.autoChangePrice(target)
|
||||
break;
|
||||
case "taxLastMoney":
|
||||
operNumber = row.operNumber-0 //数量
|
||||
taxLastMoney = value-0
|
||||
taxRate = row.taxRate-0 //税率
|
||||
unitPrice = (taxLastMoney/operNumber/(1+taxRate*0.01)).toFixed(6)-0
|
||||
allPrice = (unitPrice*operNumber).toFixed(2)-0
|
||||
taxMoney =(taxLastMoney-allPrice).toFixed(2)-0
|
||||
target.setValues([{rowKey: row.id, values: {unitPrice: unitPrice, allPrice: allPrice, taxMoney: taxMoney}}])
|
||||
target.recalcAllStatisticsColumns()
|
||||
that.autoChangePrice(target)
|
||||
break;
|
||||
case "currentStock" :
|
||||
target.setValues([{rowKey: row.id, values: {operNumber: Number(value) - Number(row.stock)}}])
|
||||
break
|
||||
}
|
||||
if(value.split(',').length > 1) {
|
||||
this.clearKh()
|
||||
}
|
||||
},
|
||||
//转为商品对象
|
||||
parseInfoToObj(mInfo) {
|
||||
return {
|
||||
barCode: mInfo.mBarCode,
|
||||
name: mInfo.name,
|
||||
standard: mInfo.standard,
|
||||
model: mInfo.model,
|
||||
color: mInfo.color,
|
||||
materialOther: mInfo.materialOther,
|
||||
unit: mInfo.commodityUnit,
|
||||
sku: mInfo.sku,
|
||||
operNumber: 1,
|
||||
unitPrice: mInfo.billPrice,
|
||||
allPrice: mInfo.billPrice,
|
||||
taxRate: 0,
|
||||
taxMoney: 0,
|
||||
taxLastMoney: mInfo.billPrice
|
||||
}
|
||||
},
|
||||
//使得型号、颜色、扩展信息、sku等为隐藏
|
||||
changeColumnHide() {
|
||||
this.changeFormTypes(this.materialTable.columns, 'model', 0)
|
||||
this.changeFormTypes(this.materialTable.columns, 'color', 0)
|
||||
this.changeFormTypes(this.materialTable.columns, 'materialOther', 0)
|
||||
this.changeFormTypes(this.materialTable.columns, 'sku', 0)
|
||||
},
|
||||
//使得sku、序列号、批号、到期日等为显示
|
||||
changeColumnShow(info) {
|
||||
if(info.model) {
|
||||
this.changeFormTypes(this.materialTable.columns, 'model', 1)
|
||||
}
|
||||
if(info.color) {
|
||||
this.changeFormTypes(this.materialTable.columns, 'color', 1)
|
||||
}
|
||||
if(info.materialOther) {
|
||||
this.changeFormTypes(this.materialTable.columns, 'materialOther', 1)
|
||||
}
|
||||
if(info.sku) {
|
||||
this.changeFormTypes(this.materialTable.columns, 'sku', 1)
|
||||
}
|
||||
if(info.enableSerialNumber === "1") {
|
||||
this.changeFormTypes(this.materialTable.columns, 'snList', 1)
|
||||
}
|
||||
if(info.enableBatchNumber === "1") {
|
||||
this.changeFormTypes(this.materialTable.columns, 'batchNumber', 1)
|
||||
this.changeFormTypes(this.materialTable.columns, 'expirationDate', 1)
|
||||
}
|
||||
},
|
||||
//删除一行或多行的时候触发
|
||||
onDeleted(ids, target) {
|
||||
target.recalcAllStatisticsColumns()
|
||||
this.autoChangePrice(target)
|
||||
},
|
||||
//根据仓库和物料编码查询库存
|
||||
getStockByDepotBarCode(row, target){
|
||||
findStockByDepotAndBarCode({ depotId: row.depotId, barCode: row.barCode }).then((res) => {
|
||||
if (res && res.code === 200) {
|
||||
console.log(res.data.stock,'res.data.stock')
|
||||
target.setValues([{rowKey: row.id, values: {stock: res.data.stock}}])
|
||||
target.recalcAllStatisticsColumns()
|
||||
}
|
||||
})
|
||||
},
|
||||
//改变优惠、本次付款、欠款的值
|
||||
autoChangePrice(target) {
|
||||
let allTaxLastMoney = target.statisticsColumns.taxLastMoney-0
|
||||
let discount = this.form.getFieldValue('discount')-0
|
||||
let otherMoney = this.form.getFieldValue('otherMoney')-0
|
||||
let discountMoney = (discount*0.01*allTaxLastMoney).toFixed(2)-0
|
||||
let discountLastMoney = (allTaxLastMoney-discountMoney).toFixed(2)-0
|
||||
let changeAmountNew = (discountLastMoney + otherMoney).toFixed(2)-0
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({'discount':discount,'discountMoney':discountMoney,'discountLastMoney':discountLastMoney,
|
||||
'changeAmount':changeAmountNew,'debt':0})
|
||||
});
|
||||
},
|
||||
//改变优惠率
|
||||
onKeyUpDiscount(e) {
|
||||
const value = e.target.value-0
|
||||
let discountMoney = this.form.getFieldValue('discountMoney')-0
|
||||
let discountLastMoney = this.form.getFieldValue('discountLastMoney')-0
|
||||
let otherMoney = this.form.getFieldValue('otherMoney')-0
|
||||
let allTaxLastMoney = (discountMoney + discountLastMoney).toFixed(2)-0
|
||||
let discountMoneyNew = (allTaxLastMoney*value*0.01).toFixed(2)-0
|
||||
let discountLastMoneyNew = (allTaxLastMoney - discountMoneyNew).toFixed(2)-0
|
||||
let changeAmountNew = (discountLastMoneyNew + otherMoney).toFixed(2)-0
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({'discountMoney':discountMoneyNew,'discountLastMoney':discountLastMoneyNew,
|
||||
'changeAmount':changeAmountNew,'debt':0})
|
||||
});
|
||||
},
|
||||
//改变付款优惠
|
||||
onKeyUpDiscountMoney(e) {
|
||||
const value = e.target.value-0
|
||||
let discount = this.form.getFieldValue('discount')-0
|
||||
let discountLastMoney = this.form.getFieldValue('discountLastMoney')-0
|
||||
let otherMoney = this.form.getFieldValue('otherMoney')-0
|
||||
if(discount !== 100) {
|
||||
let allTaxLastMoney = (discountLastMoney/(1-discount/100)).toFixed(2)-0
|
||||
let discountNew = (value/allTaxLastMoney*100).toFixed(2)-0
|
||||
let discountLastMoneyNew = (allTaxLastMoney - value).toFixed(2)-0
|
||||
let changeAmountNew = (discountLastMoneyNew + otherMoney).toFixed(2)-0
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({'discount':discountNew,'discountLastMoney':discountLastMoneyNew,
|
||||
'changeAmount':changeAmountNew,'debt':0})
|
||||
});
|
||||
}
|
||||
},
|
||||
//其它费用
|
||||
onKeyUpOtherMoney(e) {
|
||||
const value = e.target.value-0
|
||||
let discountLastMoney = this.form.getFieldValue('discountLastMoney')-0
|
||||
let changeAmountNew = (discountLastMoney + value).toFixed(2)-0
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({'changeAmount':changeAmountNew, 'debt':0})
|
||||
});
|
||||
},
|
||||
//改变本次付款
|
||||
onKeyUpChangeAmount(e) {
|
||||
const value = e.target.value-0
|
||||
let discountLastMoney = this.form.getFieldValue('discountLastMoney')-0
|
||||
let otherMoney = this.form.getFieldValue('otherMoney')-0
|
||||
let debtNew = (discountLastMoney + otherMoney - value).toFixed(2)-0
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({'debt':debtNew})
|
||||
});
|
||||
},
|
||||
scanEnter() {
|
||||
this.scanStatus = false
|
||||
this.$nextTick(() => {
|
||||
this.$refs.scanBarCode.focus()
|
||||
})
|
||||
},
|
||||
//扫码之后回车
|
||||
scanPressEnter() {
|
||||
if(this.scanBarCode) {
|
||||
this.getAllTable().then(tables => {
|
||||
return getListData(this.form, tables)
|
||||
}).then(allValues => {
|
||||
let param = {
|
||||
barCode: this.scanBarCode,
|
||||
mpList: getMpListShort(Vue.ls.get('materialPropertyList')), //扩展属性
|
||||
prefixNo: this.prefixNo
|
||||
}
|
||||
getMaterialByBarCode(param).then((res) => {
|
||||
if (res && res.code === 200) {
|
||||
let hasFinished = false
|
||||
let allLastMoney = 0
|
||||
let allTaxLastMoney = 0
|
||||
//获取单据明细列表信息
|
||||
let detailArr = allValues.tablesValue[0].values
|
||||
//构造新的列表数组,用于存放单据明细信息
|
||||
let newDetailArr = []
|
||||
for(let detail of detailArr){
|
||||
if(detail.barCode) {
|
||||
//如果物料编码重复,就在给原来的数量加1
|
||||
if(detail.barCode === this.scanBarCode) {
|
||||
detail.operNumber = (detail.operNumber-0)+1
|
||||
//由于改变了商品数量,需要同时更新相关金额和价税合计
|
||||
let taxRate = detail.taxRate-0 //税率
|
||||
let unitPrice = detail.unitPrice-0 //单价
|
||||
detail.allPrice = (unitPrice*detail.operNumber).toFixed(2)-0
|
||||
detail.taxMoney = ((taxRate*0.01)*detail.allPrice).toFixed(2)-0
|
||||
detail.taxLastMoney = (detail.allPrice + detail.taxMoney).toFixed(2)-0
|
||||
hasFinished = true
|
||||
}
|
||||
newDetailArr.push(detail)
|
||||
}
|
||||
}
|
||||
if(!hasFinished) {
|
||||
//将扫码的物料编码对应的商品加入列表
|
||||
let item = {}
|
||||
item.barCode = this.scanBarCode
|
||||
let mList = res.data
|
||||
if(mList && mList.length>0) {
|
||||
let mInfo = mList[0]
|
||||
this.changeColumnShow(mInfo)
|
||||
item.depotId = mInfo.depotId
|
||||
item.name = mInfo.name
|
||||
item.standard = mInfo.standard
|
||||
item.model = mInfo.model
|
||||
item.color = mInfo.color
|
||||
item.materialOther = mInfo.materialOther
|
||||
item.stock = mInfo.stock
|
||||
item.unit = mInfo.commodityUnit
|
||||
item.sku = mInfo.sku
|
||||
item.operNumber = 1
|
||||
item.unitPrice = mInfo.billPrice
|
||||
item.allPrice = mInfo.billPrice
|
||||
item.taxRate = 0
|
||||
item.taxMoney = 0
|
||||
item.taxLastMoney = mInfo.billPrice
|
||||
newDetailArr.push(item)
|
||||
} else {
|
||||
this.$message.warning('抱歉,此物料编码不存在商品信息!');
|
||||
}
|
||||
}
|
||||
//组合和拆分单据给商品类型进行重新赋值
|
||||
for(let i=0; i< newDetailArr.length; i++) {
|
||||
if(i===0) {
|
||||
newDetailArr[0].mType = '组合件'
|
||||
} else {
|
||||
newDetailArr[i].mType = '普通子件'
|
||||
}
|
||||
}
|
||||
this.materialTable.dataSource = newDetailArr
|
||||
//更新优惠后金额、本次付款等信息
|
||||
for(let newDetail of newDetailArr){
|
||||
allLastMoney = allLastMoney + (newDetail.allPrice-0)
|
||||
allTaxLastMoney = allTaxLastMoney + (newDetail.taxLastMoney-0)
|
||||
}
|
||||
let discount = this.form.getFieldValue('discount')-0
|
||||
let otherMoney = this.form.getFieldValue('otherMoney')-0
|
||||
let discountMoney = (discount*0.01*allTaxLastMoney).toFixed(2)-0
|
||||
let discountLastMoney = (allTaxLastMoney-discountMoney).toFixed(2)-0
|
||||
let changeAmountNew = (discountLastMoney + otherMoney).toFixed(2)-0
|
||||
if(this.prefixNo === 'LSCK' || this.prefixNo === 'LSTH') {
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({'changeAmount':allLastMoney,'getAmount':allLastMoney,'backAmount':0})
|
||||
});
|
||||
} else {
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({'discount':discount,'discountMoney':discountMoney,'discountLastMoney':discountLastMoney,
|
||||
'changeAmount':changeAmountNew,'debt':0})
|
||||
});
|
||||
}
|
||||
//置空扫码的内容
|
||||
this.scanBarCode = ''
|
||||
this.$refs.scanBarCode.focus()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
stopScan() {
|
||||
this.scanStatus = true
|
||||
this.scanBarCode = ''
|
||||
},
|
||||
//清空空行
|
||||
clearKh() {
|
||||
this.getAllTable().then(tables => {
|
||||
let inputValues = tables[0].inputValues
|
||||
let ids = []
|
||||
inputValues.forEach((item) => {
|
||||
if(!item.barCode && !item.operNumber) {
|
||||
ids.push(item.id)
|
||||
}
|
||||
})
|
||||
tables[0].removeRows(ids)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
<template>
|
||||
<j-modal
|
||||
:title="title"
|
||||
:width="width"
|
||||
:visible="visible"
|
||||
:confirmLoading="confirmLoading"
|
||||
:maskClosable="false"
|
||||
:keyboard="false"
|
||||
:forceRender="true"
|
||||
switchFullscreen
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
wrapClassName="ant-modal-cust-warp"
|
||||
style="top:5%;height: 100%;overflow-y: hidden">
|
||||
<a-spin :spinning="confirmLoading">
|
||||
<a-form :form="form">
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="单据日期">
|
||||
<j-date v-decorator="['operTime', validatorRules.operTime]" :show-time="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="单据编号">
|
||||
<a-input placeholder="请输入单据编号" v-decorator.trim="[ 'number' ]" :readOnly="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24"></a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24"></a-col>
|
||||
</a-row>
|
||||
<j-editable-table id="billModal"
|
||||
:ref="refKeys[0]"
|
||||
:loading="materialTable.loading"
|
||||
:columns="materialTable.columns"
|
||||
:dataSource="materialTable.dataSource"
|
||||
:maxHeight="300"
|
||||
:rowNumber="false"
|
||||
:rowSelection="true"
|
||||
:actionButton="true"
|
||||
:dragSort="true"
|
||||
@valueChange="onValueChange"
|
||||
@added="onAdded"
|
||||
@deleted="onDeleted">
|
||||
<template #buttonAfter>
|
||||
<a-row :gutter="24" style="float:left;" data-step="4" data-title="扫码录入" data-intro="此功能支持扫码枪扫描商品条码进行录入">
|
||||
<a-col v-if="scanStatus" :md="6" :sm="24">
|
||||
<a-button @click="scanEnter">扫码录入</a-button>
|
||||
</a-col>
|
||||
<a-col v-if="!scanStatus" :md="16" :sm="24" style="padding: 0 6px 0 12px">
|
||||
<a-input placeholder="请扫码商品条码并回车" v-model="scanBarCode" @pressEnter="scanPressEnter" ref="scanBarCode"/>
|
||||
</a-col>
|
||||
<a-col v-if="!scanStatus" :md="6" :sm="24" style="padding: 0px">
|
||||
<a-button @click="stopScan">收起扫码</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="24" style="float:left;">
|
||||
<a-col :md="24" :sm="24">
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" @click="handleBatchSetDepot"><a-icon type="setting"/>批量设置</a-menu-item>
|
||||
<a-menu-item v-if="isTenant" key="2" @click="addDepot"><a-icon type="plus"/>新增仓库</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button style="margin-left: 8px">仓库操作 <a-icon type="down" /></a-button>
|
||||
</a-dropdown>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-button type="primary" @click="clearKh" style="margin-left:10px">清空空行</a-button>
|
||||
</template>
|
||||
</j-editable-table>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="24" :md="24" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="{xs: { span: 24 },sm: { span: 24 }}" label="">
|
||||
<a-textarea :rows="1" placeholder="请输入备注" v-decorator="[ 'remark' ]" style="margin-top:8px;"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="附件">
|
||||
<j-upload v-model="fileList" bizPath="bill"></j-upload>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
<depot-modal ref="depotModalForm" @ok="depotModalFormOk"></depot-modal>
|
||||
<batch-set-depot ref="batchSetDepotModalForm" @ok="batchSetDepotModalFormOk"></batch-set-depot>
|
||||
</j-modal>
|
||||
</template>
|
||||
<script>
|
||||
import pick from 'lodash.pick'
|
||||
import DepotModal from '../../system/modules/DepotModal'
|
||||
import BatchSetDepot from '../dialog/BatchSetDepot'
|
||||
import { FormTypes } from '@/utils/JEditableTableUtil'
|
||||
import { JEditableTableMixin } from '@/mixins/JEditableTableMixin'
|
||||
import { BillModalMixin } from '../mixins/BillModalMixin'
|
||||
import { getMpListShort } from "@/utils/util"
|
||||
import JUpload from '@/components/jeecg/JUpload'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
export default {
|
||||
name: "AllocationOutModal",
|
||||
mixins: [JEditableTableMixin, BillModalMixin],
|
||||
components: {
|
||||
DepotModal,
|
||||
BatchSetDepot,
|
||||
JUpload,
|
||||
JDate
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
title:"操作",
|
||||
width: '100%',
|
||||
moreStatus: false,
|
||||
// 新增时子表默认添加几行空数据
|
||||
addDefaultRowNum: 10,
|
||||
visible: false,
|
||||
operTimeStr: '',
|
||||
prefixNo: 'DBCK',
|
||||
fileList:[],
|
||||
model: {},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 8 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
refKeys: ['materialDataTable', ],
|
||||
activeKey: 'materialDataTable',
|
||||
materialTable: {
|
||||
loading: false,
|
||||
dataSource: [],
|
||||
columns: [
|
||||
{ title: '仓库名称', key: 'depotId', width: '7%', type: FormTypes.select, placeholder: '请选择${title}', options: [],
|
||||
allowSearch:true, validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '物料编码', key: 'barCode', width: '8%', type: FormTypes.popupJsh, kind: 'material', multi: true,
|
||||
validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '名称', key: 'name', width: '20%', type: FormTypes.normal },
|
||||
{ title: '规格', key: 'standard', width: '5%', type: FormTypes.normal },
|
||||
{ title: '型号', key: 'model', width: '5%', type: FormTypes.normal },
|
||||
{ title: '颜色', key: 'color', width: '5%', type: FormTypes.normal },
|
||||
{ title: '扩展信息', key: 'materialOther', width: '5%', type: FormTypes.normal },
|
||||
{ title: '库存', key: 'stock', width: '5%', type: FormTypes.inputNumber, readonly:true },
|
||||
{ title: '调入仓库', key: 'anotherDepotId', width: '7%', type: FormTypes.select, placeholder: '请选择${title}', options: [], allowSearch:true},
|
||||
{ title: '单位', key: 'unit', width: '4%', type: FormTypes.normal },
|
||||
{ title: '多属性', key: 'sku', width: '4%', type: FormTypes.normal },
|
||||
{ title: '数量', key: 'operNumber', width: '5%', type: FormTypes.inputNumber, statistics: true,
|
||||
validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '单价', key: 'unitPrice', width: '5%', type: FormTypes.inputNumber},
|
||||
{ title: '金额', key: 'allPrice', width: '5%', type: FormTypes.inputNumber, statistics: true },
|
||||
{ title: '备注', key: 'remark', width: '5%', type: FormTypes.input }
|
||||
]
|
||||
},
|
||||
confirmLoading: false,
|
||||
validatorRules:{
|
||||
operTime:{
|
||||
rules: [
|
||||
{ required: true, message: '请输入单据日期!' }
|
||||
]
|
||||
},
|
||||
type:{
|
||||
rules: [
|
||||
{ required: true, message: '请选择类型!' }
|
||||
]
|
||||
}
|
||||
},
|
||||
url: {
|
||||
add: '/depotHead/addDepotHeadAndDetail',
|
||||
edit: '/depotHead/updateDepotHeadAndDetail',
|
||||
detailList: '/depotItem/getDetailList'
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
},
|
||||
methods: {
|
||||
//调用完edit()方法之后会自动调用此方法
|
||||
editAfter() {
|
||||
this.changeColumnHide()
|
||||
if (this.action === 'add') {
|
||||
this.addInit(this.prefixNo)
|
||||
this.fileList = []
|
||||
} else {
|
||||
this.model.operTime = this.model.operTimeStr
|
||||
this.fileList = this.model.fileName
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue(pick(this.model,'organId', 'operTime', 'number', 'remark',
|
||||
'discount','discountMoney','discountLastMoney','otherMoney','accountId','changeAmount'))
|
||||
});
|
||||
// 加载子表数据
|
||||
let params = {
|
||||
headerId: this.model.id,
|
||||
mpList: getMpListShort(Vue.ls.get('materialPropertyList')) //扩展属性
|
||||
}
|
||||
let url = this.readOnly ? this.url.detailList : this.url.detailList;
|
||||
this.requestSubTableData(url, params, this.materialTable);
|
||||
}
|
||||
//复制新增单据-初始化单号和日期
|
||||
if(this.action === 'copyAdd') {
|
||||
this.model.id = ''
|
||||
this.model.tenantId = ''
|
||||
this.copyAddInit(this.prefixNo)
|
||||
}
|
||||
this.initDepot()
|
||||
},
|
||||
//提交单据时整理成formData
|
||||
classifyIntoFormData(allValues) {
|
||||
let totalPrice = 0
|
||||
let billMain = Object.assign(this.model, allValues.formValue)
|
||||
let detailArr = allValues.tablesValue[0].values
|
||||
billMain.type = '出库'
|
||||
billMain.subType = '调拨'
|
||||
billMain.defaultNumber = billMain.number
|
||||
for(let item of detailArr){
|
||||
totalPrice += item.allPrice-0
|
||||
}
|
||||
billMain.totalPrice = totalPrice
|
||||
if(this.fileList && this.fileList.length > 0) {
|
||||
billMain.fileName = this.fileList
|
||||
}
|
||||
if(this.model.id){
|
||||
billMain.id = this.model.id
|
||||
}
|
||||
return {
|
||||
info: billMain,
|
||||
rows: detailArr,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,258 @@
|
||||
<template>
|
||||
<j-modal
|
||||
:title="title"
|
||||
:width="width"
|
||||
:visible="visible"
|
||||
:confirmLoading="confirmLoading"
|
||||
:maskClosable="false"
|
||||
:keyboard="false"
|
||||
:forceRender="true"
|
||||
switchFullscreen
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
wrapClassName="ant-modal-cust-warp"
|
||||
style="top:5%;height: 100%;overflow-y: hidden">
|
||||
<a-spin :spinning="confirmLoading">
|
||||
<a-form :form="form">
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="单据日期">
|
||||
<j-date v-decorator="['operTime', validatorRules.operTime]" :show-time="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="单据编号">
|
||||
<a-input placeholder="请输入单据编号" v-decorator.trim="[ 'number' ]" :readOnly="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24"></a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24"></a-col>
|
||||
</a-row>
|
||||
<j-editable-table id="billModal"
|
||||
:ref="refKeys[0]"
|
||||
:loading="materialTable.loading"
|
||||
:columns="materialTable.columns"
|
||||
:dataSource="materialTable.dataSource"
|
||||
:maxHeight="300"
|
||||
:rowNumber="false"
|
||||
:rowSelection="true"
|
||||
:actionButton="true"
|
||||
@valueChange="onValueChange"
|
||||
@added="onAdded"
|
||||
@deleted="onDeleted">
|
||||
<template #buttonAfter>
|
||||
<a-row :gutter="24" style="float:left;" data-step="4" data-title="扫码录入" data-intro="此功能支持扫码枪扫描商品条码进行录入">
|
||||
<a-col v-if="scanStatus" :md="6" :sm="24">
|
||||
<a-button @click="scanEnter">扫码录入</a-button>
|
||||
</a-col>
|
||||
<a-col v-if="!scanStatus" :md="16" :sm="24" style="padding: 0 6px 0 12px">
|
||||
<a-input placeholder="请扫码商品条码并回车" v-model="scanBarCode" @pressEnter="scanPressEnter" ref="scanBarCode"/>
|
||||
</a-col>
|
||||
<a-col v-if="!scanStatus" :md="6" :sm="24" style="padding: 0px">
|
||||
<a-button @click="stopScan">收起扫码</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="24" style="float:left;">
|
||||
<a-col :md="24" :sm="24">
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" @click="handleBatchSetDepot"><a-icon type="setting"/>批量设置</a-menu-item>
|
||||
<a-menu-item v-if="isTenant" key="2" @click="addDepot"><a-icon type="plus"/>新增仓库</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button style="margin-left: 8px">仓库操作 <a-icon type="down" /></a-button>
|
||||
</a-dropdown>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-button type="primary" @click="clearKh" style="margin-left:10px">清空空行</a-button>
|
||||
</template>
|
||||
</j-editable-table>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="24" :md="24" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="{xs: { span: 24 },sm: { span: 24 }}" label="">
|
||||
<a-textarea :rows="1" placeholder="请输入备注" v-decorator="[ 'remark' ]" style="margin-top:8px;"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="附件">
|
||||
<j-upload v-model="fileList" bizPath="bill"></j-upload>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
<depot-modal ref="depotModalForm" @ok="depotModalFormOk"></depot-modal>
|
||||
<batch-set-depot ref="batchSetDepotModalForm" @ok="batchSetDepotModalFormOk"></batch-set-depot>
|
||||
</j-modal>
|
||||
</template>
|
||||
<script>
|
||||
import pick from 'lodash.pick'
|
||||
import DepotModal from '../../system/modules/DepotModal'
|
||||
import BatchSetDepot from '../dialog/BatchSetDepot'
|
||||
import { FormTypes } from '@/utils/JEditableTableUtil'
|
||||
import { JEditableTableMixin } from '@/mixins/JEditableTableMixin'
|
||||
import { BillModalMixin } from '../mixins/BillModalMixin'
|
||||
import { getAction } from '@/api/manage'
|
||||
import { getMpListShort } from "@/utils/util"
|
||||
import JUpload from '@/components/jeecg/JUpload'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
export default {
|
||||
name: "AssembleModal",
|
||||
mixins: [JEditableTableMixin, BillModalMixin],
|
||||
components: {
|
||||
DepotModal,
|
||||
BatchSetDepot,
|
||||
JUpload,
|
||||
JDate
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
title:"操作",
|
||||
width: '100%',
|
||||
moreStatus: false,
|
||||
// 新增时子表默认添加几行空数据
|
||||
addDefaultRowNum: 10,
|
||||
visible: false,
|
||||
operTimeStr: '',
|
||||
prefixNo: 'ZZD',
|
||||
fileList:[],
|
||||
model: {},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 8 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
refKeys: ['materialDataTable', ],
|
||||
activeKey: 'materialDataTable',
|
||||
materialTable: {
|
||||
loading: false,
|
||||
dataSource: [],
|
||||
columns: [
|
||||
{ title: '商品类型',key: 'mType',width:'7%', type: FormTypes.normal },
|
||||
{ title: '仓库名称', key: 'depotId', width: '7%', type: FormTypes.select, placeholder: '请选择${title}', options: [],
|
||||
allowSearch:true, validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '物料编码', key: 'barCode', width: '8%', type: FormTypes.popupJsh, kind: 'material', multi: true,
|
||||
validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '名称', key: 'name', width: '20%', type: FormTypes.normal },
|
||||
{ title: '规格', key: 'standard', width: '5%', type: FormTypes.normal },
|
||||
{ title: '型号', key: 'model', width: '5%', type: FormTypes.normal },
|
||||
{ title: '颜色', key: 'color', width: '5%', type: FormTypes.normal },
|
||||
{ title: '扩展信息', key: 'materialOther', width: '5%', type: FormTypes.normal },
|
||||
{ title: '库存', key: 'stock', width: '5%', type: FormTypes.inputNumber, readonly:true},
|
||||
{ title: '单位', key: 'unit', width: '4%', type: FormTypes.normal },
|
||||
{ title: '多属性', key: 'sku', width: '4%', type: FormTypes.normal },
|
||||
{ title: '数量', key: 'operNumber', width: '5%', type: FormTypes.inputNumber, statistics: true,
|
||||
validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '单价', key: 'unitPrice', width: '5%', type: FormTypes.inputNumber},
|
||||
{ title: '金额', key: 'allPrice', width: '5%', type: FormTypes.inputNumber, statistics: true },
|
||||
{ title: '备注', key: 'remark', width: '5%', type: FormTypes.input }
|
||||
]
|
||||
},
|
||||
confirmLoading: false,
|
||||
validatorRules:{
|
||||
operTime:{
|
||||
rules: [
|
||||
{ required: true, message: '请输入单据日期!' }
|
||||
]
|
||||
},
|
||||
type:{
|
||||
rules: [
|
||||
{ required: true, message: '请选择类型!' }
|
||||
]
|
||||
}
|
||||
},
|
||||
url: {
|
||||
add: '/depotHead/addDepotHeadAndDetail',
|
||||
edit: '/depotHead/updateDepotHeadAndDetail',
|
||||
detailList: '/depotItem/getDetailList'
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
},
|
||||
methods: {
|
||||
//调用完edit()方法之后会自动调用此方法
|
||||
editAfter() {
|
||||
this.changeColumnHide()
|
||||
if (this.action === 'add') {
|
||||
this.addInit(this.prefixNo)
|
||||
this.fileList = []
|
||||
} else {
|
||||
this.model.operTime = this.model.operTimeStr
|
||||
this.model.debt = (this.model.discountLastMoney - this.model.changeAmount).toFixed(2)
|
||||
this.fileList = this.model.fileName
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue(pick(this.model,'organId', 'operTime', 'number', 'remark',
|
||||
'discount','discountMoney','discountLastMoney','otherMoney','accountId','changeAmount','debt'))
|
||||
});
|
||||
// 加载子表数据
|
||||
let params = {
|
||||
headerId: this.model.id,
|
||||
mpList: getMpListShort(Vue.ls.get('materialPropertyList')) //扩展属性
|
||||
}
|
||||
let url = this.readOnly ? this.url.detailList : this.url.detailList;
|
||||
this.requestSubTableData(url, params, this.materialTable);
|
||||
}
|
||||
//复制新增单据-初始化单号和日期
|
||||
if(this.action === 'copyAdd') {
|
||||
this.model.id = ''
|
||||
this.model.tenantId = ''
|
||||
this.copyAddInit(this.prefixNo)
|
||||
}
|
||||
this.initDepot()
|
||||
},
|
||||
//提交单据时整理成formData
|
||||
classifyIntoFormData(allValues) {
|
||||
let totalPrice = 0
|
||||
let billMain = Object.assign(this.model, allValues.formValue)
|
||||
let detailArr = allValues.tablesValue[0].values
|
||||
billMain.type = '其它'
|
||||
billMain.subType = '组装单'
|
||||
billMain.defaultNumber = billMain.number
|
||||
for(let item of detailArr){
|
||||
totalPrice += item.allPrice-0
|
||||
}
|
||||
billMain.totalPrice = totalPrice
|
||||
if(this.fileList && this.fileList.length > 0) {
|
||||
billMain.fileName = this.fileList
|
||||
}
|
||||
if(this.model.id){
|
||||
billMain.id = this.model.id
|
||||
}
|
||||
return {
|
||||
info: billMain,
|
||||
rows: detailArr,
|
||||
}
|
||||
},
|
||||
onAdded(event) {
|
||||
const { row, target } = event
|
||||
getAction('/depot/findDepotByCurrentUser').then((res) => {
|
||||
if (res.code === 200) {
|
||||
let arr = res.data
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if(arr[i].isDefault){
|
||||
target.setValues([{rowKey: row.id, values: {depotId: arr[i].id+''}}])
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
if(target.rows.length>=2) {
|
||||
target.setValues([{rowKey: row.id, values: {mType: '普通子件'}}])
|
||||
} else {
|
||||
target.setValues([{rowKey: row.id, values: {mType: '组合件'}}])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,257 @@
|
||||
<template>
|
||||
<j-modal
|
||||
:title="title"
|
||||
:width="width"
|
||||
:visible="visible"
|
||||
:confirmLoading="confirmLoading"
|
||||
:maskClosable="false"
|
||||
:keyboard="false"
|
||||
:forceRender="true"
|
||||
switchFullscreen
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
wrapClassName="ant-modal-cust-warp"
|
||||
style="top:5%;height: 100%;overflow-y: hidden">
|
||||
<a-spin :spinning="confirmLoading">
|
||||
<a-form :form="form">
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="单据日期">
|
||||
<j-date v-decorator="['operTime', validatorRules.operTime]" :show-time="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="单据编号">
|
||||
<a-input placeholder="请输入单据编号" v-decorator.trim="[ 'number' ]" :readOnly="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24"></a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24"></a-col>
|
||||
</a-row>
|
||||
<j-editable-table id="billModal"
|
||||
:ref="refKeys[0]"
|
||||
:loading="materialTable.loading"
|
||||
:columns="materialTable.columns"
|
||||
:dataSource="materialTable.dataSource"
|
||||
:maxHeight="300"
|
||||
:rowNumber="false"
|
||||
:rowSelection="true"
|
||||
:actionButton="true"
|
||||
@valueChange="onValueChange"
|
||||
@added="onAdded"
|
||||
@deleted="onDeleted">
|
||||
<template #buttonAfter>
|
||||
<a-row :gutter="24" style="float:left;" data-step="4" data-title="扫码录入" data-intro="此功能支持扫码枪扫描商品条码进行录入">
|
||||
<a-col v-if="scanStatus" :md="6" :sm="24">
|
||||
<a-button @click="scanEnter">扫码录入</a-button>
|
||||
</a-col>
|
||||
<a-col v-if="!scanStatus" :md="16" :sm="24" style="padding: 0 6px 0 12px">
|
||||
<a-input placeholder="请扫码商品条码并回车" v-model="scanBarCode" @pressEnter="scanPressEnter" ref="scanBarCode"/>
|
||||
</a-col>
|
||||
<a-col v-if="!scanStatus" :md="6" :sm="24" style="padding: 0px">
|
||||
<a-button @click="stopScan">收起扫码</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="24" style="float:left;">
|
||||
<a-col :md="24" :sm="24">
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" @click="handleBatchSetDepot"><a-icon type="setting"/>批量设置</a-menu-item>
|
||||
<a-menu-item v-if="isTenant" key="2" @click="addDepot"><a-icon type="plus"/>新增仓库</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button style="margin-left: 8px">仓库操作 <a-icon type="down" /></a-button>
|
||||
</a-dropdown>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-button type="primary" @click="clearKh" style="margin-left:10px">清空空行</a-button>
|
||||
</template>
|
||||
</j-editable-table>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="24" :md="24" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="{xs: { span: 24 },sm: { span: 24 }}" label="">
|
||||
<a-textarea :rows="1" placeholder="请输入备注" v-decorator="[ 'remark' ]" style="margin-top:8px;"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="附件">
|
||||
<j-upload v-model="fileList" bizPath="bill"></j-upload>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
<depot-modal ref="depotModalForm" @ok="depotModalFormOk"></depot-modal>
|
||||
<batch-set-depot ref="batchSetDepotModalForm" @ok="batchSetDepotModalFormOk"></batch-set-depot>
|
||||
</j-modal>
|
||||
</template>
|
||||
<script>
|
||||
import pick from 'lodash.pick'
|
||||
import DepotModal from '../../system/modules/DepotModal'
|
||||
import BatchSetDepot from '../dialog/BatchSetDepot'
|
||||
import { FormTypes } from '@/utils/JEditableTableUtil'
|
||||
import { JEditableTableMixin } from '@/mixins/JEditableTableMixin'
|
||||
import { BillModalMixin } from '../mixins/BillModalMixin'
|
||||
import { getAction } from '@/api/manage'
|
||||
import { getMpListShort } from "@/utils/util"
|
||||
import JUpload from '@/components/jeecg/JUpload'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
export default {
|
||||
name: "DisassembleModal",
|
||||
mixins: [JEditableTableMixin, BillModalMixin],
|
||||
components: {
|
||||
DepotModal,
|
||||
BatchSetDepot,
|
||||
JUpload,
|
||||
JDate
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
title:"操作",
|
||||
width: '100%',
|
||||
moreStatus: false,
|
||||
// 新增时子表默认添加几行空数据
|
||||
addDefaultRowNum: 10,
|
||||
visible: false,
|
||||
operTimeStr: '',
|
||||
prefixNo: 'CXD',
|
||||
fileList:[],
|
||||
model: {},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 8 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
refKeys: ['materialDataTable', ],
|
||||
activeKey: 'materialDataTable',
|
||||
materialTable: {
|
||||
loading: false,
|
||||
dataSource: [],
|
||||
columns: [
|
||||
{ title: '商品类型',key: 'mType',width:'7%', type: FormTypes.normal },
|
||||
{ title: '仓库名称', key: 'depotId', width: '7%', type: FormTypes.select, placeholder: '请选择${title}', options: [],
|
||||
allowSearch:true, validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '物料编码', key: 'barCode', width: '8%', type: FormTypes.popupJsh, kind: 'material', multi: true,
|
||||
validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '名称', key: 'name', width: '20%', type: FormTypes.normal },
|
||||
{ title: '规格', key: 'standard', width: '5%', type: FormTypes.normal },
|
||||
{ title: '型号', key: 'model', width: '5%', type: FormTypes.normal },
|
||||
{ title: '颜色', key: 'color', width: '5%', type: FormTypes.normal },
|
||||
{ title: '扩展信息', key: 'materialOther', width: '5%', type: FormTypes.normal },
|
||||
{ title: '库存', key: 'stock', width: '5%', type: FormTypes.inputNumber, readonly:true},
|
||||
{ title: '单位', key: 'unit', width: '4%', type: FormTypes.normal },
|
||||
{ title: '多属性', key: 'sku', width: '4%', type: FormTypes.normal },
|
||||
{ title: '数量', key: 'operNumber', width: '5%', type: FormTypes.inputNumber, statistics: true,
|
||||
validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '单价', key: 'unitPrice', width: '5%', type: FormTypes.inputNumber},
|
||||
{ title: '金额', key: 'allPrice', width: '5%', type: FormTypes.inputNumber, statistics: true },
|
||||
{ title: '备注', key: 'remark', width: '5%', type: FormTypes.input }
|
||||
]
|
||||
},
|
||||
confirmLoading: false,
|
||||
validatorRules:{
|
||||
operTime:{
|
||||
rules: [
|
||||
{ required: true, message: '请输入单据日期!' }
|
||||
]
|
||||
},
|
||||
type:{
|
||||
rules: [
|
||||
{ required: true, message: '请选择类型!' }
|
||||
]
|
||||
}
|
||||
},
|
||||
url: {
|
||||
add: '/depotHead/addDepotHeadAndDetail',
|
||||
edit: '/depotHead/updateDepotHeadAndDetail',
|
||||
detailList: '/depotItem/getDetailList'
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
},
|
||||
methods: {
|
||||
//调用完edit()方法之后会自动调用此方法
|
||||
editAfter() {
|
||||
this.changeColumnHide()
|
||||
if (this.action === 'add') {
|
||||
this.addInit(this.prefixNo)
|
||||
this.fileList = []
|
||||
} else {
|
||||
this.model.operTime = this.model.operTimeStr
|
||||
this.fileList = this.model.fileName
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue(pick(this.model,'organId', 'operTime', 'number', 'remark',
|
||||
'discount','discountMoney','discountLastMoney','otherMoney','accountId','changeAmount'))
|
||||
});
|
||||
// 加载子表数据
|
||||
let params = {
|
||||
headerId: this.model.id,
|
||||
mpList: getMpListShort(Vue.ls.get('materialPropertyList')) //扩展属性
|
||||
}
|
||||
let url = this.readOnly ? this.url.detailList : this.url.detailList;
|
||||
this.requestSubTableData(url, params, this.materialTable);
|
||||
}
|
||||
//复制新增单据-初始化单号和日期
|
||||
if(this.action === 'copyAdd') {
|
||||
this.model.id = ''
|
||||
this.model.tenantId = ''
|
||||
this.copyAddInit(this.prefixNo)
|
||||
}
|
||||
this.initDepot()
|
||||
},
|
||||
//提交单据时整理成formData
|
||||
classifyIntoFormData(allValues) {
|
||||
let totalPrice = 0
|
||||
let billMain = Object.assign(this.model, allValues.formValue)
|
||||
let detailArr = allValues.tablesValue[0].values
|
||||
billMain.type = '其它'
|
||||
billMain.subType = '拆卸单'
|
||||
billMain.defaultNumber = billMain.number
|
||||
for(let item of detailArr){
|
||||
totalPrice += item.allPrice-0
|
||||
}
|
||||
billMain.totalPrice = totalPrice
|
||||
if(this.fileList && this.fileList.length > 0) {
|
||||
billMain.fileName = this.fileList
|
||||
}
|
||||
if(this.model.id){
|
||||
billMain.id = this.model.id
|
||||
}
|
||||
return {
|
||||
info: billMain,
|
||||
rows: detailArr,
|
||||
}
|
||||
},
|
||||
onAdded(event) {
|
||||
const { row, target } = event
|
||||
getAction('/depot/findDepotByCurrentUser').then((res) => {
|
||||
if (res.code === 200) {
|
||||
let arr = res.data
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if(arr[i].isDefault){
|
||||
target.setValues([{rowKey: row.id, values: {depotId: arr[i].id+''}}])
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
if(target.rows.length>=2) {
|
||||
target.setValues([{rowKey: row.id, values: {mType: '普通子件'}}])
|
||||
} else {
|
||||
target.setValues([{rowKey: row.id, values: {mType: '组合件'}}])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,287 @@
|
||||
<template>
|
||||
<j-modal
|
||||
:title="title"
|
||||
:width="width"
|
||||
:visible="visible"
|
||||
:confirmLoading="confirmLoading"
|
||||
:maskClosable="false"
|
||||
:keyboard="false"
|
||||
:forceRender="true"
|
||||
switchFullscreen
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
wrapClassName="ant-modal-cust-warp"
|
||||
style="top:5%;height: 100%;overflow-y: hidden">
|
||||
<a-spin :spinning="confirmLoading">
|
||||
<a-form :form="form">
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="单据日期">
|
||||
<j-date v-decorator="['operTime', validatorRules.operTime]" :show-time="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="单据编号">
|
||||
<a-input placeholder="请输入单据编号" v-decorator.trim="[ 'number' ]" :readOnly="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="关联单据">
|
||||
<a-input-search placeholder="请选择关联单据" v-decorator="[ 'linkNumber' ]" @search="onSearchLinkNumber" :readOnly="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<j-editable-table id="billModal"
|
||||
:ref="refKeys[0]"
|
||||
:loading="materialTable.loading"
|
||||
:columns="materialTable.columns"
|
||||
:dataSource="materialTable.dataSource"
|
||||
:maxHeight="300"
|
||||
:rowNumber="false"
|
||||
:rowSelection="true"
|
||||
:actionButton="true"
|
||||
:dragSort="true"
|
||||
@valueChange="onValueChange"
|
||||
@added="onAdded"
|
||||
@deleted="onDeleted">
|
||||
<template #buttonAfter>
|
||||
<a-row :gutter="24" style="float:left;" data-step="4" data-title="扫码录入" data-intro="此功能支持扫码枪扫描商品物料编码进行录入">
|
||||
<a-col v-if="scanStatus" :md="6" :sm="24">
|
||||
<a-button @click="scanEnter">扫码录入</a-button>
|
||||
</a-col>
|
||||
<a-col v-if="!scanStatus" :md="16" :sm="24" style="padding: 0 6px 0 12px">
|
||||
<a-input placeholder="请扫码商品物料编码并回车" v-model="scanBarCode" @pressEnter="scanPressEnter" ref="scanBarCode"/>
|
||||
</a-col>
|
||||
<a-col v-if="!scanStatus" :md="6" :sm="24" style="padding: 0px">
|
||||
<a-button @click="stopScan">收起扫码</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="24" style="float:left;">
|
||||
<a-col :md="24" :sm="24">
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" @click="handleBatchSetDepot"><a-icon type="setting"/>批量设置</a-menu-item>
|
||||
<a-menu-item v-if="isTenant" key="2" @click="addDepot"><a-icon type="plus"/>新增仓库</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button style="margin-left: 8px">仓库操作 <a-icon type="down" /></a-button>
|
||||
</a-dropdown>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-button type="primary" @click="clearKh" style="margin-left:10px">清空空行</a-button>
|
||||
</template>
|
||||
</j-editable-table>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="24" :md="24" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="{xs: { span: 24 },sm: { span: 24 }}" label="">
|
||||
<a-textarea :rows="1" placeholder="请输入备注" v-decorator="[ 'remark' ]" style="margin-top:8px;"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="附件">
|
||||
<j-upload v-model="fileList" bizPath="bill"></j-upload>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
<link-bill-list ref="linkBillList" @ok="linkBillListOk"></link-bill-list>
|
||||
<vendor-modal ref="vendorModalForm" @ok="vendorModalFormOk"></vendor-modal>
|
||||
<depot-modal ref="depotModalForm" @ok="depotModalFormOk"></depot-modal>
|
||||
<batch-set-depot ref="batchSetDepotModalForm" @ok="batchSetDepotModalFormOk"></batch-set-depot>
|
||||
</j-modal>
|
||||
</template>
|
||||
<script>
|
||||
import pick from 'lodash.pick'
|
||||
import LinkBillList from '../dialog/LinkBillList'
|
||||
import VendorModal from '../../system/modules/VendorModal'
|
||||
import DepotModal from '../../system/modules/DepotModal'
|
||||
import BatchSetDepot from '../dialog/BatchSetDepot'
|
||||
import { FormTypes } from '@/utils/JEditableTableUtil'
|
||||
import { JEditableTableMixin } from '@/mixins/JEditableTableMixin'
|
||||
import { BillModalMixin } from '../mixins/BillModalMixin'
|
||||
import { getMpListShort } from "@/utils/util"
|
||||
import JUpload from '@/components/jeecg/JUpload'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
export default {
|
||||
name: "OtherInModal",
|
||||
mixins: [JEditableTableMixin, BillModalMixin],
|
||||
components: {
|
||||
VendorModal,
|
||||
DepotModal,
|
||||
BatchSetDepot,
|
||||
JUpload,
|
||||
JDate,
|
||||
LinkBillList,
|
||||
VNodes: {
|
||||
functional: true,
|
||||
render: (h, ctx) => ctx.props.vnodes,
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
title:"操作",
|
||||
width: '100%',
|
||||
moreStatus: false,
|
||||
// 新增时子表默认添加几行空数据
|
||||
addDefaultRowNum: 10,
|
||||
visible: false,
|
||||
operTimeStr: '',
|
||||
prefixNo: 'QTRK',
|
||||
fileList:[],
|
||||
model: {},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 8 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
refKeys: ['materialDataTable', ],
|
||||
activeKey: 'materialDataTable',
|
||||
materialTable: {
|
||||
loading: false,
|
||||
dataSource: [],
|
||||
columns: [
|
||||
{ title: '仓库名称', key: 'depotId', width: '7%', type: FormTypes.select, placeholder: '请选择${title}', options: [],
|
||||
allowSearch:true, validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '物料编码', key: 'barCode', width: '8%', type: FormTypes.popupJsh, kind: 'material', multi: true,
|
||||
validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '名称', key: 'name', width: '20%', type: FormTypes.normal },
|
||||
{ title: '规格', key: 'standard', width: '5%', type: FormTypes.normal },
|
||||
{ title: '型号', key: 'model', width: '5%', type: FormTypes.normal },
|
||||
{ title: '颜色', key: 'color', width: '5%', type: FormTypes.normal },
|
||||
{ title: '扩展信息', key: 'materialOther', width: '5%', type: FormTypes.normal },
|
||||
{ title: '库存', key: 'stock', width: '5%', type: FormTypes.inputNumber, readonly:true },
|
||||
{ title: '单位', key: 'unit', width: '4%', type: FormTypes.normal },
|
||||
{ title: '实存', key: 'currentStock', width: '4%', type: FormTypes.inputNumber},
|
||||
{ title: '序列号', key: 'snList', width: '12%', type: FormTypes.input, placeholder: '多个序列号请用逗号隔开',
|
||||
validateRules: [{ pattern: /^\S{1,100}$/, message: '请小于100位字符' }]
|
||||
},
|
||||
{ title: '批号', key: 'batchNumber', width: '5%', type: FormTypes.input },
|
||||
{ title: '有效期', key: 'expirationDate',width: '7%', type: FormTypes.date },
|
||||
{ title: '多属性', key: 'sku', width: '4%', type: FormTypes.normal },
|
||||
{ title: '数量', key: 'operNumber', width: '5%', type: FormTypes.inputNumber,readonly:true, statistics: true,
|
||||
validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '单价', key: 'unitPrice', width: '5%', type: FormTypes.inputNumber},
|
||||
{ title: '金额', key: 'allPrice', width: '5%', type: FormTypes.inputNumber, statistics: true },
|
||||
{ title: '备注', key: 'remark', width: '5%', type: FormTypes.input }
|
||||
]
|
||||
},
|
||||
confirmLoading: false,
|
||||
validatorRules:{
|
||||
operTime:{
|
||||
rules: [
|
||||
{ required: true, message: '请输入单据日期!' }
|
||||
]
|
||||
},
|
||||
type:{
|
||||
rules: [
|
||||
{ required: true, message: '请选择类型!' }
|
||||
]
|
||||
}
|
||||
},
|
||||
url: {
|
||||
add: '/depotHead/addDepotHeadAndDetail',
|
||||
edit: '/depotHead/updateDepotHeadAndDetail',
|
||||
detailList: '/depotItem/getDetailList'
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
},
|
||||
methods: {
|
||||
//调用完edit()方法之后会自动调用此方法
|
||||
editAfter() {
|
||||
this.changeColumnHide()
|
||||
this.changeFormTypes(this.materialTable.columns, 'snList', 0)
|
||||
this.changeFormTypes(this.materialTable.columns, 'batchNumber', 0)
|
||||
this.changeFormTypes(this.materialTable.columns, 'expirationDate', 0)
|
||||
if (this.action === 'add') {
|
||||
this.addInit(this.prefixNo)
|
||||
this.fileList = []
|
||||
} else {
|
||||
this.model.operTime = this.model.operTimeStr
|
||||
this.fileList = this.model.fileName
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue(pick(this.model,'linkNumber', 'operTime', 'number', 'remark',
|
||||
'discount','discountMoney','discountLastMoney','otherMoney','accountId','changeAmount'))
|
||||
});
|
||||
// 加载子表数据
|
||||
let params = {
|
||||
headerId: this.model.id,
|
||||
mpList: getMpListShort(Vue.ls.get('materialPropertyList')) //扩展属性
|
||||
}
|
||||
let url = this.readOnly ? this.url.detailList : this.url.detailList;
|
||||
this.requestSubTableData(url, params, this.materialTable);
|
||||
}
|
||||
//复制新增单据-初始化单号和日期
|
||||
if(this.action === 'copyAdd') {
|
||||
this.model.id = ''
|
||||
this.model.tenantId = ''
|
||||
this.copyAddInit(this.prefixNo)
|
||||
}
|
||||
this.initSupplier()
|
||||
this.initDepot()
|
||||
},
|
||||
onSearchLinkNumber() {
|
||||
this.$refs.linkBillList.show('复盘', '盘点')
|
||||
this.$refs.linkBillList.title = "请选择盘点复盘"
|
||||
},
|
||||
linkBillListOk(selectBillRows) {
|
||||
this.changeFormTypes(this.materialTable.columns, 'preNumber', 1)
|
||||
this.changeFormTypes(this.materialTable.columns, 'finishNumber', 1)
|
||||
if(selectBillRows && selectBillRows.length>0) {
|
||||
let record = selectBillRows[0]
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({
|
||||
'linkNumber': record.linkNumber,
|
||||
'linkNumber': record.number,
|
||||
'remark': record.remark,
|
||||
'discountLastMoney': record.totalPrice,
|
||||
'changeAmount': record.totalPrice
|
||||
})
|
||||
});
|
||||
// 加载子表数据
|
||||
let params = {
|
||||
headerId: record.id,
|
||||
mpList: getMpListShort(Vue.ls.get('materialPropertyList')) //扩展属性
|
||||
}
|
||||
this.requestSubTableDataEx(this.url.detailList, params, this.materialTable);
|
||||
}
|
||||
},
|
||||
//提交单据时整理成formData
|
||||
classifyIntoFormData(allValues) {
|
||||
let totalPrice = 0
|
||||
let billMain = Object.assign(this.model, allValues.formValue)
|
||||
let detailArr = allValues.tablesValue[0].values
|
||||
billMain.type = '其它'
|
||||
billMain.subType = '盘点复盘'
|
||||
billMain.defaultNumber = billMain.number
|
||||
for(let item of detailArr){
|
||||
totalPrice += item.allPrice-0
|
||||
}
|
||||
billMain.totalPrice = totalPrice
|
||||
if(this.fileList && this.fileList.length > 0) {
|
||||
billMain.fileName = this.fileList
|
||||
}
|
||||
if(this.model.id){
|
||||
billMain.id = this.model.id
|
||||
}
|
||||
return {
|
||||
info: billMain,
|
||||
rows: detailArr,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,269 @@
|
||||
<template>
|
||||
<j-modal
|
||||
:title="title"
|
||||
:width="width"
|
||||
:visible="visible"
|
||||
:confirmLoading="confirmLoading"
|
||||
:maskClosable="false"
|
||||
:keyboard="false"
|
||||
:forceRender="true"
|
||||
switchFullscreen
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
wrapClassName="ant-modal-cust-warp"
|
||||
style="top:5%;height: 100%;overflow-y: hidden">
|
||||
<a-spin :spinning="confirmLoading">
|
||||
<a-form :form="form">
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="供应商">
|
||||
<a-select placeholder="选择供应商" v-decorator="[ 'organId' ]"
|
||||
:dropdownMatchSelectWidth="false" showSearch optionFilterProp="children">
|
||||
<div slot="dropdownRender" slot-scope="menu">
|
||||
<v-nodes :vnodes="menu" />
|
||||
<a-divider style="margin: 4px 0;" />
|
||||
<div v-if="isTenant" style="padding: 4px 8px; cursor: pointer;"
|
||||
@mousedown="e => e.preventDefault()" @click="addSupplier"><a-icon type="plus" /> 新增供应商</div>
|
||||
</div>
|
||||
<a-select-option v-for="(item,index) in supList" :key="index" :value="Number(item.id)">
|
||||
{{ item.supplier }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="单据日期">
|
||||
<j-date v-decorator="['operTime', validatorRules.operTime]" :show-time="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="单据编号">
|
||||
<a-input placeholder="请输入单据编号" v-decorator.trim="[ 'number' ]" :readOnly="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24"></a-col>
|
||||
</a-row>
|
||||
<j-editable-table id="billModal"
|
||||
:ref="refKeys[0]"
|
||||
:loading="materialTable.loading"
|
||||
:columns="materialTable.columns"
|
||||
:dataSource="materialTable.dataSource"
|
||||
:maxHeight="300"
|
||||
:rowNumber="false"
|
||||
:rowSelection="true"
|
||||
:actionButton="true"
|
||||
:dragSort="true"
|
||||
@valueChange="onValueChange"
|
||||
@added="onAdded"
|
||||
@deleted="onDeleted">
|
||||
<template #buttonAfter>
|
||||
<a-row :gutter="24" style="float:left;" data-step="4" data-title="扫码录入" data-intro="此功能支持扫码枪扫描商品物料编码进行录入">
|
||||
<a-col v-if="scanStatus" :md="6" :sm="24">
|
||||
<a-button @click="scanEnter">扫码录入</a-button>
|
||||
</a-col>
|
||||
<a-col v-if="!scanStatus" :md="16" :sm="24" style="padding: 0 6px 0 12px">
|
||||
<a-input placeholder="请扫码商品物料编码并回车" v-model="scanBarCode" @pressEnter="scanPressEnter" ref="scanBarCode"/>
|
||||
</a-col>
|
||||
<a-col v-if="!scanStatus" :md="6" :sm="24" style="padding: 0px">
|
||||
<a-button @click="stopScan">收起扫码</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="24" style="float:left;">
|
||||
<a-col :md="24" :sm="24">
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" @click="handleBatchSetDepot"><a-icon type="setting"/>批量设置</a-menu-item>
|
||||
<a-menu-item v-if="isTenant" key="2" @click="addDepot"><a-icon type="plus"/>新增仓库</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button style="margin-left: 8px">仓库操作 <a-icon type="down" /></a-button>
|
||||
</a-dropdown>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-button type="primary" @click="clearKh" style="margin-left:10px">清空空行</a-button>
|
||||
</template>
|
||||
</j-editable-table>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="24" :md="24" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="{xs: { span: 24 },sm: { span: 24 }}" label="">
|
||||
<a-textarea :rows="1" placeholder="请输入备注" v-decorator="[ 'remark' ]" style="margin-top:8px;"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="附件">
|
||||
<j-upload v-model="fileList" bizPath="bill"></j-upload>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
<vendor-modal ref="vendorModalForm" @ok="vendorModalFormOk"></vendor-modal>
|
||||
<depot-modal ref="depotModalForm" @ok="depotModalFormOk"></depot-modal>
|
||||
<batch-set-depot ref="batchSetDepotModalForm" @ok="batchSetDepotModalFormOk"></batch-set-depot>
|
||||
</j-modal>
|
||||
</template>
|
||||
<script>
|
||||
import pick from 'lodash.pick'
|
||||
import VendorModal from '../../system/modules/VendorModal'
|
||||
import DepotModal from '../../system/modules/DepotModal'
|
||||
import BatchSetDepot from '../dialog/BatchSetDepot'
|
||||
import { FormTypes } from '@/utils/JEditableTableUtil'
|
||||
import { JEditableTableMixin } from '@/mixins/JEditableTableMixin'
|
||||
import { BillModalMixin } from '../mixins/BillModalMixin'
|
||||
import { getMpListShort } from "@/utils/util"
|
||||
import JUpload from '@/components/jeecg/JUpload'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
export default {
|
||||
name: "OtherInModal",
|
||||
mixins: [JEditableTableMixin, BillModalMixin],
|
||||
components: {
|
||||
VendorModal,
|
||||
DepotModal,
|
||||
BatchSetDepot,
|
||||
JUpload,
|
||||
JDate,
|
||||
VNodes: {
|
||||
functional: true,
|
||||
render: (h, ctx) => ctx.props.vnodes,
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
title:"操作",
|
||||
width: '100%',
|
||||
moreStatus: false,
|
||||
// 新增时子表默认添加几行空数据
|
||||
addDefaultRowNum: 10,
|
||||
visible: false,
|
||||
operTimeStr: '',
|
||||
prefixNo: 'QTRK',
|
||||
fileList:[],
|
||||
model: {},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 8 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
refKeys: ['materialDataTable', ],
|
||||
activeKey: 'materialDataTable',
|
||||
materialTable: {
|
||||
loading: false,
|
||||
dataSource: [],
|
||||
columns: [
|
||||
{ title: '仓库名称', key: 'depotId', width: '7%', type: FormTypes.select, placeholder: '请选择${title}', options: [],
|
||||
allowSearch:true, validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '物料编码', key: 'barCode', width: '8%', type: FormTypes.popupJsh, kind: 'material', multi: true,
|
||||
validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '名称', key: 'name', width: '20%', type: FormTypes.normal },
|
||||
{ title: '规格', key: 'standard', width: '5%', type: FormTypes.normal },
|
||||
{ title: '型号', key: 'model', width: '5%', type: FormTypes.normal },
|
||||
{ title: '颜色', key: 'color', width: '5%', type: FormTypes.normal },
|
||||
{ title: '扩展信息', key: 'materialOther', width: '5%', type: FormTypes.normal },
|
||||
{ title: '库存', key: 'stock', width: '5%', type: FormTypes.inputNumber, readonly:true},
|
||||
{ title: '单位', key: 'unit', width: '4%', type: FormTypes.normal },
|
||||
{ title: '序列号', key: 'snList', width: '12%', type: FormTypes.input, placeholder: '多个序列号请用逗号隔开',
|
||||
validateRules: [{ pattern: /^\S{1,100}$/, message: '请小于100位字符' }]
|
||||
},
|
||||
{ title: '批号', key: 'batchNumber', width: '5%', type: FormTypes.input },
|
||||
{ title: '有效期', key: 'expirationDate',width: '7%', type: FormTypes.date },
|
||||
{ title: '多属性', key: 'sku', width: '4%', type: FormTypes.normal },
|
||||
{ title: '数量', key: 'operNumber', width: '5%', type: FormTypes.inputNumber, statistics: true,
|
||||
validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '单价', key: 'unitPrice', width: '5%', type: FormTypes.inputNumber},
|
||||
{ title: '金额', key: 'allPrice', width: '5%', type: FormTypes.inputNumber, statistics: true },
|
||||
{ title: '备注', key: 'remark', width: '5%', type: FormTypes.input }
|
||||
]
|
||||
},
|
||||
confirmLoading: false,
|
||||
validatorRules:{
|
||||
operTime:{
|
||||
rules: [
|
||||
{ required: true, message: '请输入单据日期!' }
|
||||
]
|
||||
},
|
||||
type:{
|
||||
rules: [
|
||||
{ required: true, message: '请选择类型!' }
|
||||
]
|
||||
}
|
||||
},
|
||||
url: {
|
||||
add: '/depotHead/addDepotHeadAndDetail',
|
||||
edit: '/depotHead/updateDepotHeadAndDetail',
|
||||
detailList: '/depotItem/getDetailList'
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
},
|
||||
methods: {
|
||||
//调用完edit()方法之后会自动调用此方法
|
||||
editAfter() {
|
||||
this.changeColumnHide()
|
||||
this.changeFormTypes(this.materialTable.columns, 'snList', 0)
|
||||
this.changeFormTypes(this.materialTable.columns, 'batchNumber', 0)
|
||||
this.changeFormTypes(this.materialTable.columns, 'expirationDate', 0)
|
||||
if (this.action === 'add') {
|
||||
this.addInit(this.prefixNo)
|
||||
this.fileList = []
|
||||
} else {
|
||||
this.model.operTime = this.model.operTimeStr
|
||||
this.fileList = this.model.fileName
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue(pick(this.model,'organId', 'operTime', 'number', 'remark',
|
||||
'discount','discountMoney','discountLastMoney','otherMoney','accountId','changeAmount'))
|
||||
});
|
||||
// 加载子表数据
|
||||
let params = {
|
||||
headerId: this.model.id,
|
||||
mpList: getMpListShort(Vue.ls.get('materialPropertyList')) //扩展属性
|
||||
}
|
||||
let url = this.readOnly ? this.url.detailList : this.url.detailList;
|
||||
this.requestSubTableData(url, params, this.materialTable);
|
||||
}
|
||||
//复制新增单据-初始化单号和日期
|
||||
if(this.action === 'copyAdd') {
|
||||
this.model.id = ''
|
||||
this.model.tenantId = ''
|
||||
this.copyAddInit(this.prefixNo)
|
||||
}
|
||||
this.initSupplier()
|
||||
this.initDepot()
|
||||
},
|
||||
//提交单据时整理成formData
|
||||
classifyIntoFormData(allValues) {
|
||||
let totalPrice = 0
|
||||
let billMain = Object.assign(this.model, allValues.formValue)
|
||||
let detailArr = allValues.tablesValue[0].values
|
||||
billMain.type = '入库'
|
||||
billMain.subType = '其它'
|
||||
billMain.defaultNumber = billMain.number
|
||||
for(let item of detailArr){
|
||||
totalPrice += item.allPrice-0
|
||||
}
|
||||
billMain.totalPrice = totalPrice
|
||||
if(this.fileList && this.fileList.length > 0) {
|
||||
billMain.fileName = this.fileList
|
||||
}
|
||||
if(this.model.id){
|
||||
billMain.id = this.model.id
|
||||
}
|
||||
return {
|
||||
info: billMain,
|
||||
rows: detailArr,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,267 @@
|
||||
<template>
|
||||
<j-modal
|
||||
:title="title"
|
||||
:width="width"
|
||||
:visible="visible"
|
||||
:confirmLoading="confirmLoading"
|
||||
:maskClosable="false"
|
||||
:keyboard="false"
|
||||
:forceRender="true"
|
||||
switchFullscreen
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
wrapClassName="ant-modal-cust-warp"
|
||||
style="top:5%;height: 100%;overflow-y: hidden">
|
||||
<a-spin :spinning="confirmLoading">
|
||||
<a-form :form="form">
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="客户">
|
||||
<a-select placeholder="选择客户" v-decorator="[ 'organId' ]"
|
||||
:dropdownMatchSelectWidth="false" showSearch optionFilterProp="children">
|
||||
<div slot="dropdownRender" slot-scope="menu">
|
||||
<v-nodes :vnodes="menu" />
|
||||
<a-divider style="margin: 4px 0;" />
|
||||
<div v-if="isTenant" style="padding: 4px 8px; cursor: pointer;"
|
||||
@mousedown="e => e.preventDefault()" @click="addCustomer"><a-icon type="plus" /> 新增客户</div>
|
||||
</div>
|
||||
<a-select-option v-for="(item,index) in cusList" :key="index" :value="item.id">
|
||||
{{ item.supplier }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="单据日期">
|
||||
<j-date v-decorator="['operTime', validatorRules.operTime]" :show-time="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="单据编号">
|
||||
<a-input placeholder="请输入单据编号" v-decorator.trim="[ 'number' ]" :readOnly="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24"></a-col>
|
||||
</a-row>
|
||||
<j-editable-table id="billModal"
|
||||
:ref="refKeys[0]"
|
||||
:loading="materialTable.loading"
|
||||
:columns="materialTable.columns"
|
||||
:dataSource="materialTable.dataSource"
|
||||
:maxHeight="300"
|
||||
:rowNumber="false"
|
||||
:rowSelection="true"
|
||||
:actionButton="true"
|
||||
:dragSort="true"
|
||||
@valueChange="onValueChange"
|
||||
@added="onAdded"
|
||||
@deleted="onDeleted">
|
||||
<template #buttonAfter>
|
||||
<a-row :gutter="24" style="float:left;" data-step="4" data-title="扫码录入" data-intro="此功能支持扫码枪扫描商品条码进行录入">
|
||||
<a-col v-if="scanStatus" :md="6" :sm="24">
|
||||
<a-button @click="scanEnter">扫码录入</a-button>
|
||||
</a-col>
|
||||
<a-col v-if="!scanStatus" :md="16" :sm="24" style="padding: 0 6px 0 12px">
|
||||
<a-input placeholder="请扫码商品条码并回车" v-model="scanBarCode" @pressEnter="scanPressEnter" ref="scanBarCode"/>
|
||||
</a-col>
|
||||
<a-col v-if="!scanStatus" :md="6" :sm="24" style="padding: 0px">
|
||||
<a-button @click="stopScan">收起扫码</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="24" style="float:left;">
|
||||
<a-col :md="24" :sm="24">
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" @click="handleBatchSetDepot"><a-icon type="setting"/>批量设置</a-menu-item>
|
||||
<a-menu-item v-if="isTenant" key="2" @click="addDepot"><a-icon type="plus"/>新增仓库</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button style="margin-left: 8px">仓库操作 <a-icon type="down" /></a-button>
|
||||
</a-dropdown>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-button type="primary" @click="clearKh" style="margin-left:10px">清空空行</a-button>
|
||||
</template>
|
||||
</j-editable-table>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="24" :md="24" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="{xs: { span: 24 },sm: { span: 24 }}" label="">
|
||||
<a-textarea :rows="1" placeholder="请输入备注" v-decorator="[ 'remark' ]" style="margin-top:8px;"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="附件">
|
||||
<j-upload v-model="fileList" bizPath="bill"></j-upload>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
<customer-modal ref="customerModalForm" @ok="customerModalFormOk"></customer-modal>
|
||||
<depot-modal ref="depotModalForm" @ok="depotModalFormOk"></depot-modal>
|
||||
<batch-set-depot ref="batchSetDepotModalForm" @ok="batchSetDepotModalFormOk"></batch-set-depot>
|
||||
</j-modal>
|
||||
</template>
|
||||
<script>
|
||||
import pick from 'lodash.pick'
|
||||
import CustomerModal from '../../system/modules/CustomerModal'
|
||||
import DepotModal from '../../system/modules/DepotModal'
|
||||
import BatchSetDepot from '../dialog/BatchSetDepot'
|
||||
import { FormTypes } from '@/utils/JEditableTableUtil'
|
||||
import { JEditableTableMixin } from '@/mixins/JEditableTableMixin'
|
||||
import { BillModalMixin } from '../mixins/BillModalMixin'
|
||||
import { getMpListShort } from "@/utils/util"
|
||||
import JUpload from '@/components/jeecg/JUpload'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
export default {
|
||||
name: "OtherOutModal",
|
||||
mixins: [JEditableTableMixin, BillModalMixin],
|
||||
components: {
|
||||
CustomerModal,
|
||||
DepotModal,
|
||||
BatchSetDepot,
|
||||
JUpload,
|
||||
JDate,
|
||||
VNodes: {
|
||||
functional: true,
|
||||
render: (h, ctx) => ctx.props.vnodes,
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
title:"操作",
|
||||
width: '100%',
|
||||
moreStatus: false,
|
||||
// 新增时子表默认添加几行空数据
|
||||
addDefaultRowNum: 10,
|
||||
visible: false,
|
||||
operTimeStr: '',
|
||||
prefixNo: 'QTCK',
|
||||
fileList:[],
|
||||
model: {},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 8 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
refKeys: ['materialDataTable', ],
|
||||
activeKey: 'materialDataTable',
|
||||
materialTable: {
|
||||
loading: false,
|
||||
dataSource: [],
|
||||
columns: [
|
||||
{ title: '仓库名称', key: 'depotId', width: '7%', type: FormTypes.select, placeholder: '请选择${title}', options: [],
|
||||
allowSearch:true, validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '物料编码', key: 'barCode', width: '8%', type: FormTypes.popupJsh, kind: 'material', multi: true,
|
||||
validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '名称', key: 'name', width: '20%', type: FormTypes.normal },
|
||||
{ title: '规格', key: 'standard', width: '5%', type: FormTypes.normal },
|
||||
{ title: '型号', key: 'model', width: '5%', type: FormTypes.normal },
|
||||
{ title: '颜色', key: 'color', width: '5%', type: FormTypes.normal },
|
||||
{ title: '扩展信息', key: 'materialOther', width: '5%', type: FormTypes.normal },
|
||||
{ title: '库存', key: 'stock', width: '5%', type: FormTypes.inputNumber, readonly:true },
|
||||
{ title: '单位', key: 'unit', width: '4%', type: FormTypes.normal },
|
||||
{ title: '序列号', key: 'snList', width: '12%', type: FormTypes.popupJsh, kind: 'sn', multi: true },
|
||||
{ title: '批号', key: 'batchNumber', width: '7%', type: FormTypes.popupJsh, kind: 'batch', multi: false },
|
||||
{ title: '有效期', key: 'expirationDate',width: '6%', type: FormTypes.normal },
|
||||
{ title: '多属性', key: 'sku', width: '4%', type: FormTypes.normal },
|
||||
{ title: '数量', key: 'operNumber', width: '5%', type: FormTypes.inputNumber, statistics: true,
|
||||
validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '单价', key: 'unitPrice', width: '5%', type: FormTypes.inputNumber},
|
||||
{ title: '金额', key: 'allPrice', width: '5%', type: FormTypes.inputNumber, statistics: true },
|
||||
{ title: '备注', key: 'remark', width: '5%', type: FormTypes.input }
|
||||
]
|
||||
},
|
||||
confirmLoading: false,
|
||||
validatorRules:{
|
||||
operTime:{
|
||||
rules: [
|
||||
{ required: true, message: '请输入单据日期!' }
|
||||
]
|
||||
},
|
||||
type:{
|
||||
rules: [
|
||||
{ required: true, message: '请选择类型!' }
|
||||
]
|
||||
}
|
||||
},
|
||||
url: {
|
||||
add: '/depotHead/addDepotHeadAndDetail',
|
||||
edit: '/depotHead/updateDepotHeadAndDetail',
|
||||
detailList: '/depotItem/getDetailList'
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
},
|
||||
methods: {
|
||||
//调用完edit()方法之后会自动调用此方法
|
||||
editAfter() {
|
||||
this.changeColumnHide()
|
||||
this.changeFormTypes(this.materialTable.columns, 'snList', 0)
|
||||
this.changeFormTypes(this.materialTable.columns, 'batchNumber', 0)
|
||||
this.changeFormTypes(this.materialTable.columns, 'expirationDate', 0)
|
||||
if (this.action === 'add') {
|
||||
this.addInit(this.prefixNo)
|
||||
this.fileList = []
|
||||
} else {
|
||||
this.model.operTime = this.model.operTimeStr
|
||||
this.fileList = this.model.fileName
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue(pick(this.model,'organId', 'operTime', 'number', 'remark',
|
||||
'discount','discountMoney','discountLastMoney','otherMoney','accountId','changeAmount'))
|
||||
});
|
||||
// 加载子表数据
|
||||
let params = {
|
||||
headerId: this.model.id,
|
||||
mpList: getMpListShort(Vue.ls.get('materialPropertyList')) //扩展属性
|
||||
}
|
||||
let url = this.readOnly ? this.url.detailList : this.url.detailList;
|
||||
this.requestSubTableData(url, params, this.materialTable);
|
||||
}
|
||||
//复制新增单据-初始化单号和日期
|
||||
if(this.action === 'copyAdd') {
|
||||
this.model.id = ''
|
||||
this.model.tenantId = ''
|
||||
this.copyAddInit(this.prefixNo)
|
||||
}
|
||||
this.initCustomer()
|
||||
this.initDepot()
|
||||
},
|
||||
//提交单据时整理成formData
|
||||
classifyIntoFormData(allValues) {
|
||||
let totalPrice = 0
|
||||
let billMain = Object.assign(this.model, allValues.formValue)
|
||||
let detailArr = allValues.tablesValue[0].values
|
||||
billMain.type = '出库'
|
||||
billMain.subType = '其它'
|
||||
billMain.defaultNumber = billMain.number
|
||||
for(let item of detailArr){
|
||||
totalPrice += item.allPrice-0
|
||||
}
|
||||
billMain.totalPrice = totalPrice
|
||||
if(this.fileList && this.fileList.length > 0) {
|
||||
billMain.fileName = this.fileList
|
||||
}
|
||||
if(this.model.id){
|
||||
billMain.id = this.model.id
|
||||
}
|
||||
return {
|
||||
info: billMain,
|
||||
rows: detailArr,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,404 @@
|
||||
<template>
|
||||
<j-modal
|
||||
:title="title"
|
||||
:width="width"
|
||||
:visible="visible"
|
||||
:confirmLoading="confirmLoading"
|
||||
:maskClosable="false"
|
||||
:keyboard="false"
|
||||
:forceRender="true"
|
||||
switchFullscreen
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
wrapClassName="ant-modal-cust-warp"
|
||||
style="top:5%;height: 100%;overflow-y: hidden">
|
||||
<a-spin :spinning="confirmLoading">
|
||||
<a-form :form="form">
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="供应商">
|
||||
<a-select placeholder="选择供应商" v-decorator="[ 'organId', validatorRules.organId ]"
|
||||
:dropdownMatchSelectWidth="false" showSearch optionFilterProp="children">
|
||||
<div slot="dropdownRender" slot-scope="menu">
|
||||
<v-nodes :vnodes="menu" />
|
||||
<a-divider style="margin: 4px 0;" />
|
||||
<div v-if="isTenant" style="padding: 4px 8px; cursor: pointer;"
|
||||
@mousedown="e => e.preventDefault()" @click="addSupplier"><a-icon type="plus" /> 新增供应商</div>
|
||||
</div>
|
||||
<a-select-option v-for="(item,index) in supList" :key="index" :value="Number(item.id)">
|
||||
{{ item.supplier }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="单据日期">
|
||||
<j-date v-decorator="['operTime', validatorRules.operTime]" :show-time="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="单据编号">
|
||||
<a-input placeholder="请输入单据编号" v-decorator.trim="[ 'number' ]" :readOnly="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="关联单据">
|
||||
<a-input-search placeholder="请选择关联单据" v-decorator="[ 'linkNumber' ]" @search="onSearchLinkNumber" :readOnly="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<j-editable-table id="billModal"
|
||||
:ref="refKeys[0]"
|
||||
:loading="materialTable.loading"
|
||||
:columns="materialTable.columns"
|
||||
:dataSource="materialTable.dataSource"
|
||||
:maxHeight="300"
|
||||
:rowNumber="false"
|
||||
:rowSelection="true"
|
||||
:actionButton="true"
|
||||
:dragSort="true"
|
||||
@valueChange="onValueChange"
|
||||
@added="onAdded"
|
||||
@deleted="onDeleted">
|
||||
<template #buttonAfter>
|
||||
<a-row :gutter="24" style="float:left;" data-step="4" data-title="扫码录入" data-intro="此功能支持扫码枪扫描商品条码进行录入">
|
||||
<a-col v-if="scanStatus" :md="6" :sm="24">
|
||||
<a-button @click="scanEnter">扫码录入</a-button>
|
||||
</a-col>
|
||||
<a-col v-if="!scanStatus" :md="16" :sm="24" style="padding: 0 6px 0 12px">
|
||||
<a-input placeholder="请扫码商品条码并回车" v-model="scanBarCode" @pressEnter="scanPressEnter" ref="scanBarCode"/>
|
||||
</a-col>
|
||||
<a-col v-if="!scanStatus" :md="6" :sm="24" style="padding: 0px">
|
||||
<a-button @click="stopScan">收起扫码</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="24" style="float:left;">
|
||||
<a-col :md="24" :sm="24">
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" @click="handleBatchSetDepot"><a-icon type="setting"/>批量设置</a-menu-item>
|
||||
<a-menu-item v-if="isTenant" key="2" @click="addDepot"><a-icon type="plus"/>新增仓库</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button style="margin-left: 8px">仓库操作 <a-icon type="down" /></a-button>
|
||||
</a-dropdown>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-button type="primary" @click="clearKh" style="margin-left:10px">清空空行</a-button>
|
||||
</template>
|
||||
</j-editable-table>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="24" :md="24" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="{xs: { span: 24 },sm: { span: 24 }}" label="">
|
||||
<a-textarea :rows="1" placeholder="请输入备注" v-decorator="[ 'remark' ]" style="margin-top:8px;"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="优惠率">
|
||||
<a-input style="width:185px;" placeholder="请输入优惠率" v-decorator.trim="[ 'discount' ]" suffix="%" @keyup="onKeyUpDiscount"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="退款优惠">
|
||||
<a-input placeholder="请输入付款优惠" v-decorator.trim="[ 'discountMoney' ]" @keyup="onKeyUpDiscountMoney"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="优惠后金额">
|
||||
<a-input placeholder="请输入优惠后金额" v-decorator.trim="[ 'discountLastMoney' ]" :readOnly="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="其它费用">
|
||||
<a-input placeholder="请输入其它费用" v-decorator.trim="[ 'otherMoney' ]" @keyup="onKeyUpOtherMoney"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="结算账户">
|
||||
<a-select style="width:185px;" placeholder="选择结算账户" v-decorator="[ 'accountId']"
|
||||
:dropdownMatchSelectWidth="false" allowClear @select="selectAccount">
|
||||
<div slot="dropdownRender" slot-scope="menu">
|
||||
<v-nodes :vnodes="menu" />
|
||||
<a-divider style="margin: 4px 0;" />
|
||||
<div v-if="isTenant" style="padding: 4px 8px; cursor: pointer;"
|
||||
@mousedown="e => e.preventDefault()" @click="addAccount"><a-icon type="plus" /> 新增结算账户</div>
|
||||
</div>
|
||||
<a-select-option v-for="(item,index) in accountList" :key="index" :value="item.id">
|
||||
{{ item.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<a-tooltip title="多账户明细">
|
||||
<a-button type="default" icon="folder" style="margin-left: 8px;" size="small" v-show="manyAccountBtnStatus" @click="handleManyAccount"/>
|
||||
</a-tooltip>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="本次退款">
|
||||
<a-input placeholder="请输入本次退款" v-decorator.trim="[ 'changeAmount' ]" @keyup="onKeyUpChangeAmount" :readOnly="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="本次欠款">
|
||||
<a-input placeholder="请输入本次欠款" v-decorator.trim="[ 'debt' ]" :readOnly="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="附件">
|
||||
<j-upload v-model="fileList" bizPath="bill"></j-upload>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
<many-account-modal ref="manyAccountModalForm" @ok="manyAccountModalFormOk"></many-account-modal>
|
||||
<link-bill-list ref="linkBillList" @ok="linkBillListOk"></link-bill-list>
|
||||
<vendor-modal ref="vendorModalForm" @ok="vendorModalFormOk"></vendor-modal>
|
||||
<depot-modal ref="depotModalForm" @ok="depotModalFormOk"></depot-modal>
|
||||
<account-modal ref="accountModalForm" @ok="accountModalFormOk"></account-modal>
|
||||
<batch-set-depot ref="batchSetDepotModalForm" @ok="batchSetDepotModalFormOk"></batch-set-depot>
|
||||
</j-modal>
|
||||
</template>
|
||||
<script>
|
||||
import pick from 'lodash.pick'
|
||||
import ManyAccountModal from '../dialog/ManyAccountModal'
|
||||
import LinkBillList from '../dialog/LinkBillList'
|
||||
import VendorModal from '../../system/modules/VendorModal'
|
||||
import DepotModal from '../../system/modules/DepotModal'
|
||||
import AccountModal from '../../system/modules/AccountModal'
|
||||
import BatchSetDepot from '../dialog/BatchSetDepot'
|
||||
import { FormTypes } from '@/utils/JEditableTableUtil'
|
||||
import { JEditableTableMixin } from '@/mixins/JEditableTableMixin'
|
||||
import { BillModalMixin } from '../mixins/BillModalMixin'
|
||||
import { getMpListShort} from "@/utils/util"
|
||||
import { getAction } from '@/api/manage'
|
||||
import JUpload from '@/components/jeecg/JUpload'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
export default {
|
||||
name: "PurchaseBackModal",
|
||||
mixins: [JEditableTableMixin, BillModalMixin],
|
||||
components: {
|
||||
ManyAccountModal,
|
||||
LinkBillList,
|
||||
VendorModal,
|
||||
DepotModal,
|
||||
AccountModal,
|
||||
BatchSetDepot,
|
||||
JUpload,
|
||||
JDate,
|
||||
VNodes: {
|
||||
functional: true,
|
||||
render: (h, ctx) => ctx.props.vnodes,
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
title:"操作",
|
||||
width: '100%',
|
||||
moreStatus: false,
|
||||
// 新增时子表默认添加几行空数据
|
||||
addDefaultRowNum: 10,
|
||||
visible: false,
|
||||
operTimeStr: '',
|
||||
prefixNo: 'CGTH',
|
||||
fileList:[],
|
||||
model: {},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 8 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
refKeys: ['materialDataTable', ],
|
||||
activeKey: 'materialDataTable',
|
||||
materialTable: {
|
||||
loading: false,
|
||||
dataSource: [],
|
||||
columns: [
|
||||
{ title: '仓库名称', key: 'depotId', width: '7%', type: FormTypes.select, placeholder: '请选择${title}', options: [],
|
||||
allowSearch:true, validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '物料编码', key: 'barCode', width: '8%', type: FormTypes.popupJsh, kind: 'material', multi: true,
|
||||
validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '名称', key: 'name', width: '20%', type: FormTypes.normal },
|
||||
{ title: '规格', key: 'standard', width: '5%', type: FormTypes.normal },
|
||||
{ title: '型号', key: 'model', width: '5%', type: FormTypes.normal },
|
||||
{ title: '颜色', key: 'color', width: '5%', type: FormTypes.normal },
|
||||
{ title: '扩展信息', key: 'materialOther', width: '5%', type: FormTypes.normal },
|
||||
{ title: '库存', key: 'stock', width: '5%', type: FormTypes.inputNumber, readonly:true },
|
||||
{ title: '单位', key: 'unit', width: '4%', type: FormTypes.normal },
|
||||
{ title: '序列号', key: 'snList', width: '12%', type: FormTypes.popupJsh, kind: 'sn', multi: true },
|
||||
{ title: '批号', key: 'batchNumber', width: '7%', type: FormTypes.popupJsh, kind: 'batch', multi: false },
|
||||
{ title: '有效期', key: 'expirationDate',width: '6%', type: FormTypes.normal },
|
||||
{ title: '多属性', key: 'sku', width: '4%', type: FormTypes.normal },
|
||||
{ title: '数量', key: 'operNumber', width: '5%', type: FormTypes.inputNumber, statistics: true,
|
||||
validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '单价', key: 'unitPrice', width: '5%', type: FormTypes.inputNumber},
|
||||
{ title: '金额', key: 'allPrice', width: '5%', type: FormTypes.inputNumber, statistics: true },
|
||||
{ title: '税率', key: 'taxRate', width: '4%', type: FormTypes.inputNumber,placeholder: '%'},
|
||||
{ title: '税额', key: 'taxMoney', width: '5%', type: FormTypes.inputNumber, readonly: true, statistics: true },
|
||||
{ title: '价税合计', key: 'taxLastMoney', width: '5%', type: FormTypes.inputNumber, statistics: true },
|
||||
{ title: '备注', key: 'remark', width: '5%', type: FormTypes.input }
|
||||
]
|
||||
},
|
||||
confirmLoading: false,
|
||||
validatorRules:{
|
||||
operTime:{
|
||||
rules: [
|
||||
{ required: true, message: '请输入单据日期!' }
|
||||
]
|
||||
},
|
||||
organId:{
|
||||
rules: [
|
||||
{ required: true, message: '请选择供应商!' }
|
||||
]
|
||||
},
|
||||
accountId:{
|
||||
rules: [
|
||||
{ required: true, message: '请选择结算账户!' }
|
||||
]
|
||||
}
|
||||
},
|
||||
url: {
|
||||
add: '/depotHead/addDepotHeadAndDetail',
|
||||
edit: '/depotHead/updateDepotHeadAndDetail',
|
||||
detailList: '/depotItem/getDetailList'
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
},
|
||||
methods: {
|
||||
//调用完edit()方法之后会自动调用此方法
|
||||
editAfter() {
|
||||
this.changeColumnHide()
|
||||
this.changeFormTypes(this.materialTable.columns, 'snList', 0)
|
||||
this.changeFormTypes(this.materialTable.columns, 'batchNumber', 0)
|
||||
this.changeFormTypes(this.materialTable.columns, 'expirationDate', 0)
|
||||
if (this.action === 'add') {
|
||||
this.addInit(this.prefixNo)
|
||||
this.fileList = []
|
||||
} else {
|
||||
this.model.operTime = this.model.operTimeStr
|
||||
this.model.debt = (this.model.discountLastMoney + this.model.otherMoney - this.model.changeAmount).toFixed(2)
|
||||
if(this.model.accountId == null) {
|
||||
this.model.accountId = 0
|
||||
this.manyAccountBtnStatus = true
|
||||
this.accountIdList = this.model.accountIdList
|
||||
this.accountMoneyList = this.model.accountMoneyList
|
||||
} else {
|
||||
this.manyAccountBtnStatus = false
|
||||
}
|
||||
this.fileList = this.model.fileName
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue(pick(this.model,'organId', 'operTime', 'number', 'linkNumber', 'remark',
|
||||
'discount','discountMoney','discountLastMoney','otherMoney','accountId','changeAmount','debt'))
|
||||
});
|
||||
// 加载子表数据
|
||||
let params = {
|
||||
headerId: this.model.id,
|
||||
mpList: getMpListShort(Vue.ls.get('materialPropertyList')) //扩展属性
|
||||
}
|
||||
let url = this.readOnly ? this.url.detailList : this.url.detailList;
|
||||
this.requestSubTableData(url, params, this.materialTable);
|
||||
}
|
||||
//复制新增单据-初始化单号和日期
|
||||
if(this.action === 'copyAdd') {
|
||||
this.model.id = ''
|
||||
this.model.tenantId = ''
|
||||
this.copyAddInit(this.prefixNo)
|
||||
}
|
||||
this.initSupplier()
|
||||
this.initDepot()
|
||||
this.initAccount()
|
||||
},
|
||||
//提交单据时整理成formData
|
||||
classifyIntoFormData(allValues) {
|
||||
let totalPrice = 0
|
||||
let billMain = Object.assign(this.model, allValues.formValue)
|
||||
let detailArr = allValues.tablesValue[0].values
|
||||
billMain.type = '出库'
|
||||
billMain.subType = '采购退货'
|
||||
billMain.defaultNumber = billMain.number
|
||||
for(let item of detailArr){
|
||||
totalPrice += item.allPrice-0
|
||||
}
|
||||
billMain.totalPrice = totalPrice
|
||||
if(billMain.accountId === 0) {
|
||||
billMain.accountId = ''
|
||||
}
|
||||
billMain.accountIdList = this.accountIdList.length>0 ? JSON.stringify(this.accountIdList) : ""
|
||||
billMain.accountMoneyList = this.accountMoneyList.length>0 ? JSON.stringify(this.accountMoneyList) : ""
|
||||
if(this.fileList && this.fileList.length > 0) {
|
||||
billMain.fileName = this.fileList
|
||||
}
|
||||
if(this.model.id){
|
||||
billMain.id = this.model.id
|
||||
}
|
||||
return {
|
||||
info: billMain,
|
||||
rows: detailArr,
|
||||
}
|
||||
},
|
||||
onSearchLinkNumber() {
|
||||
this.$refs.linkBillList.show('入库', '采购', '供应商', "1")
|
||||
this.$refs.linkBillList.title = "选择采购入库"
|
||||
},
|
||||
linkBillListOk(selectBillRows) {
|
||||
if(selectBillRows && selectBillRows.length>0) {
|
||||
let record = selectBillRows[0]
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({
|
||||
'organId': record.organId,
|
||||
'linkNumber': record.number,
|
||||
'remark': record.remark,
|
||||
'discountLastMoney': record.totalPrice,
|
||||
'changeAmount': record.totalPrice
|
||||
})
|
||||
});
|
||||
// 加载子表数据
|
||||
let params = {
|
||||
headerId: record.id,
|
||||
mpList: getMpListShort(Vue.ls.get('materialPropertyList')) //扩展属性
|
||||
}
|
||||
this.requestSubTableDataEx(this.url.detailList, params, this.materialTable);
|
||||
}
|
||||
},
|
||||
/** 查询某个tab的数据,给明细里面的价税合计赋值 */
|
||||
requestSubTableDataEx(url, params, tab, success) {
|
||||
tab.loading = true
|
||||
getAction(url, params).then(res => {
|
||||
if(res && res.code === 200){
|
||||
let list = res.data.rows
|
||||
let listEx = []
|
||||
for(let j=0; j<list.length; j++){
|
||||
let info = list[j];
|
||||
info.taxMoney = 0
|
||||
info.taxLastMoney = info.allPrice
|
||||
listEx.push(info)
|
||||
this.changeColumnShow(info)
|
||||
}
|
||||
tab.dataSource = listEx
|
||||
typeof success === 'function' ? success(res) : ''
|
||||
}
|
||||
}).finally(() => {
|
||||
tab.loading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,564 @@
|
||||
<template>
|
||||
<j-modal
|
||||
:title="title"
|
||||
:width="width"
|
||||
:visible="visible"
|
||||
:confirmLoading="confirmLoading"
|
||||
:maskClosable="false"
|
||||
:keyboard="false"
|
||||
:forceRender="true"
|
||||
v-bind:prefixNo="prefixNo"
|
||||
switchHelp
|
||||
switchFullscreen
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
wrapClassName="ant-modal-cust-warp"
|
||||
:id="prefixNo"
|
||||
style="top: 5%; height: 100%; overflow-y: hidden"
|
||||
>
|
||||
<a-spin :spinning="confirmLoading">
|
||||
<a-form :form="form">
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item
|
||||
:labelCol="labelCol"
|
||||
:wrapperCol="wrapperCol"
|
||||
label="供应商"
|
||||
data-step="1"
|
||||
data-title="供应商"
|
||||
data-intro="供应商必须选择,如果发现需要选择的供应商尚未录入,可以在下拉框中点击新增供应商进行录入"
|
||||
>
|
||||
<a-select
|
||||
placeholder="选择供应商"
|
||||
v-decorator="['organId', validatorRules.organId]"
|
||||
:dropdownMatchSelectWidth="false"
|
||||
showSearch
|
||||
>
|
||||
<div slot="dropdownRender" slot-scope="menu">
|
||||
<v-nodes :vnodes="menu" />
|
||||
<a-divider style="margin: 4px 0" />
|
||||
<div
|
||||
v-if="isTenant"
|
||||
style="padding: 4px 8px; cursor: pointer"
|
||||
@mousedown="(e) => e.preventDefault()"
|
||||
@click="addSupplier"
|
||||
>
|
||||
<a-icon type="plus" /> 新增供应商
|
||||
</div>
|
||||
</div>
|
||||
<a-select-option v-for="(item, index) in supList" :key="index" :value="item.id">
|
||||
{{ item.supplier }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="单据日期">
|
||||
<j-date v-decorator="['operTime', validatorRules.operTime]" :show-time="true" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item
|
||||
:labelCol="labelCol"
|
||||
:wrapperCol="wrapperCol"
|
||||
label="单据编号"
|
||||
data-step="2"
|
||||
data-title="单据编号"
|
||||
data-intro="单据编号自动生成、自动累加、开头是单据类型的首字母缩写,累加的规则是每次打开页面会自动占用一个新的编号"
|
||||
>
|
||||
<a-input placeholder="请输入单据编号" v-decorator.trim="['number']" :readOnly="true" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item
|
||||
:labelCol="labelCol"
|
||||
:wrapperCol="wrapperCol"
|
||||
label="关联订单"
|
||||
data-step="3"
|
||||
data-title="关联订单"
|
||||
data-intro="采购入库单据可以通过关联订单来选择已录入的订单,选择之后会自动加载订单的内容,然后继续录入仓库等信息完成单据的提交,
|
||||
提交之后原来的采购订单会对应的改变单据状态。另外本系统支持订单多次入库,只需选择订单之后修改对应的商品数量即可"
|
||||
>
|
||||
<a-input-search
|
||||
placeholder="请选择关联订单"
|
||||
v-decorator="['linkNumber']"
|
||||
@search="onSearchLinkNumber"
|
||||
:readOnly="true"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<j-editable-table
|
||||
id="billModal"
|
||||
:ref="refKeys[0]"
|
||||
:loading="materialTable.loading"
|
||||
:columns="materialTable.columns"
|
||||
:dataSource="materialTable.dataSource"
|
||||
:maxHeight="300"
|
||||
:rowNumber="false"
|
||||
:rowSelection="true"
|
||||
:actionButton="true"
|
||||
:dragSort="true"
|
||||
@valueChange="onValueChange"
|
||||
@added="onAdded"
|
||||
@deleted="onDeleted"
|
||||
>
|
||||
<template #buttonAfter>
|
||||
<a-row
|
||||
:gutter="24"
|
||||
style="float: left"
|
||||
data-step="4"
|
||||
data-title="扫码录入"
|
||||
data-intro="此功能支持扫码枪扫描商品物料编码进行录入"
|
||||
>
|
||||
<a-col v-if="scanStatus" :md="6" :sm="24">
|
||||
<a-button @click="scanEnter">扫码录入</a-button>
|
||||
</a-col>
|
||||
<a-col v-if="!scanStatus" :md="16" :sm="24" style="padding: 0 6px 0 12px">
|
||||
<a-input
|
||||
placeholder="请扫码商品物料编码并回车"
|
||||
v-model="scanBarCode"
|
||||
@pressEnter="scanPressEnter"
|
||||
ref="scanBarCode"
|
||||
/>
|
||||
</a-col>
|
||||
<a-col v-if="!scanStatus" :md="6" :sm="24" style="padding: 0px">
|
||||
<a-button @click="stopScan">收起扫码</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="24" style="float: left">
|
||||
<a-col :md="24" :sm="24">
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" @click="handleBatchSetDepot"><a-icon type="setting" />批量设置</a-menu-item>
|
||||
<a-menu-item v-if="isTenant" key="2" @click="addDepot"><a-icon type="plus" />新增仓库</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button style="margin-left: 8px">仓库操作 <a-icon type="down" /></a-button>
|
||||
</a-dropdown>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-button type="primary" @click="clearKh" style="margin-left: 10px">清空空行</a-button>
|
||||
</template>
|
||||
</j-editable-table>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="24" :md="24" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="{ xs: { span: 24 }, sm: { span: 24 } }" label="">
|
||||
<a-textarea :rows="1" placeholder="请输入备注" v-decorator="['remark']" style="margin-top: 8px" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item
|
||||
:labelCol="labelCol"
|
||||
:wrapperCol="wrapperCol"
|
||||
label="优惠率"
|
||||
data-step="5"
|
||||
data-title="优惠率"
|
||||
data-intro="针对单据明细中商品总金额进行优惠的比例"
|
||||
>
|
||||
<a-input
|
||||
style="width: 185px"
|
||||
placeholder="请输入优惠率"
|
||||
v-decorator.trim="['discount']"
|
||||
suffix="%"
|
||||
@keyup="onKeyUpDiscount"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item
|
||||
:labelCol="labelCol"
|
||||
:wrapperCol="wrapperCol"
|
||||
label="付款优惠"
|
||||
data-step="6"
|
||||
data-title="付款优惠"
|
||||
data-intro="针对单据明细中商品总金额进行优惠的金额"
|
||||
>
|
||||
<a-input
|
||||
placeholder="请输入付款优惠"
|
||||
v-decorator.trim="['discountMoney']"
|
||||
@keyup="onKeyUpDiscountMoney"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item
|
||||
:labelCol="labelCol"
|
||||
:wrapperCol="wrapperCol"
|
||||
label="优惠后金额"
|
||||
data-step="7"
|
||||
data-title="优惠后金额"
|
||||
data-intro="针对单据明细中商品总金额进行优惠后的金额"
|
||||
>
|
||||
<a-input placeholder="请输入优惠后金额" v-decorator.trim="['discountLastMoney']" :readOnly="true" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item
|
||||
:labelCol="labelCol"
|
||||
:wrapperCol="wrapperCol"
|
||||
label="其它费用"
|
||||
data-step="8"
|
||||
data-title="其它费用"
|
||||
data-intro="比如快递费、油费、过路费"
|
||||
>
|
||||
<a-input placeholder="请输入其它费用" v-decorator.trim="['otherMoney']" @keyup="onKeyUpOtherMoney" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item
|
||||
:labelCol="labelCol"
|
||||
:wrapperCol="wrapperCol"
|
||||
label="结算账户"
|
||||
data-step="9"
|
||||
data-title="结算账户"
|
||||
data-intro="如果在下拉框中选择多账户,则可以通过多个结算账户进行结算"
|
||||
>
|
||||
<a-select
|
||||
style="width: 185px"
|
||||
placeholder="选择结算账户"
|
||||
v-decorator="['accountId']"
|
||||
:dropdownMatchSelectWidth="false"
|
||||
allowClear
|
||||
@select="selectAccount"
|
||||
>
|
||||
<div slot="dropdownRender" slot-scope="menu">
|
||||
<v-nodes :vnodes="menu" />
|
||||
<a-divider style="margin: 4px 0" />
|
||||
<div
|
||||
v-if="isTenant"
|
||||
style="padding: 4px 8px; cursor: pointer"
|
||||
@mousedown="(e) => e.preventDefault()"
|
||||
@click="addAccount"
|
||||
>
|
||||
<a-icon type="plus" /> 新增结算账户
|
||||
</div>
|
||||
</div>
|
||||
<a-select-option v-for="(item, index) in accountList" :key="index" :value="item.id">
|
||||
{{ item.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<a-tooltip title="多账户明细">
|
||||
<a-button
|
||||
type="default"
|
||||
icon="folder"
|
||||
style="margin-left: 8px"
|
||||
size="small"
|
||||
v-show="manyAccountBtnStatus"
|
||||
@click="handleManyAccount"
|
||||
/>
|
||||
</a-tooltip>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="本次付款">
|
||||
<a-input placeholder="请输入本次付款" v-decorator.trim="['changeAmount']" @keyup="onKeyUpChangeAmount" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item
|
||||
:labelCol="labelCol"
|
||||
:wrapperCol="wrapperCol"
|
||||
label="本次欠款"
|
||||
data-step="10"
|
||||
data-title="本次欠款"
|
||||
data-intro="欠款产生的费用,后续可以在付款单进行支付"
|
||||
>
|
||||
<a-input placeholder="请输入本次欠款" v-decorator.trim="['debt']" :readOnly="true" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24"> </a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item
|
||||
:labelCol="labelCol"
|
||||
:wrapperCol="wrapperCol"
|
||||
label="附件"
|
||||
data-step="11"
|
||||
data-title="附件"
|
||||
data-intro="可以上传与单据相关的图片、文档,支持多个文件"
|
||||
>
|
||||
<j-upload v-model="fileList" bizPath="bill"></j-upload>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
<many-account-modal ref="manyAccountModalForm" @ok="manyAccountModalFormOk"></many-account-modal>
|
||||
<link-bill-list ref="linkBillList" @ok="linkBillListOk"></link-bill-list>
|
||||
<vendor-modal ref="vendorModalForm" @ok="vendorModalFormOk"></vendor-modal>
|
||||
<depot-modal ref="depotModalForm" @ok="depotModalFormOk"></depot-modal>
|
||||
<account-modal ref="accountModalForm" @ok="accountModalFormOk"></account-modal>
|
||||
<batch-set-depot ref="batchSetDepotModalForm" @ok="batchSetDepotModalFormOk"></batch-set-depot>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import pick from 'lodash.pick'
|
||||
import ManyAccountModal from '../dialog/ManyAccountModal'
|
||||
import LinkBillList from '../dialog/LinkBillList'
|
||||
import VendorModal from '../../system/modules/VendorModal'
|
||||
import DepotModal from '../../system/modules/DepotModal'
|
||||
import AccountModal from '../../system/modules/AccountModal'
|
||||
import BatchSetDepot from '../dialog/BatchSetDepot'
|
||||
import { FormTypes } from '@/utils/JEditableTableUtil'
|
||||
import { JEditableTableMixin } from '@/mixins/JEditableTableMixin'
|
||||
import { BillModalMixin } from '../mixins/BillModalMixin'
|
||||
import { getMpListShort, changeListFmtMinus } from "@/utils/util"
|
||||
import { getAction } from '@/api/manage'
|
||||
import JUpload from '@/components/jeecg/JUpload'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
export default {
|
||||
name: "PurchaseInModal",
|
||||
mixins: [JEditableTableMixin, BillModalMixin],
|
||||
components: {
|
||||
ManyAccountModal,
|
||||
LinkBillList,
|
||||
VendorModal,
|
||||
DepotModal,
|
||||
AccountModal,
|
||||
BatchSetDepot,
|
||||
JUpload,
|
||||
JDate,
|
||||
VNodes: {
|
||||
functional: true,
|
||||
render: (h, ctx) => ctx.props.vnodes,
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
title:"操作",
|
||||
width: '100%',
|
||||
moreStatus: false,
|
||||
// 新增时子表默认添加几行空数据
|
||||
addDefaultRowNum: 10,
|
||||
visible: false,
|
||||
operTimeStr: '',
|
||||
prefixNo: 'CGRK',
|
||||
fileList:[],
|
||||
model: {},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 8 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
refKeys: ['materialDataTable', ],
|
||||
activeKey: 'materialDataTable',
|
||||
materialTable: {
|
||||
loading: false,
|
||||
dataSource: [],
|
||||
columns: [
|
||||
{ title: '仓库名称', key: 'depotId', width: '7%', type: FormTypes.select, placeholder: '请选择${title}', options: [],
|
||||
allowSearch:true, validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '物料编码', key: 'barCode', width: '8%', type: FormTypes.popupJsh, kind: 'material', multi: true,
|
||||
validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '名称', key: 'name', width: '20%', type: FormTypes.normal },
|
||||
{ title: '规格', key: 'standard', width: '5%', type: FormTypes.normal },
|
||||
{ title: '型号', key: 'model', width: '5%', type: FormTypes.normal },
|
||||
{ title: '颜色', key: 'color', width: '5%', type: FormTypes.normal },
|
||||
{ title: '扩展信息', key: 'materialOther', width: '5%', type: FormTypes.normal },
|
||||
{ title: '库存', key: 'stock', width: '5%', type: FormTypes.inputNumber, readonly:true },
|
||||
{ title: '单位', key: 'unit', width: '4%', type: FormTypes.normal },
|
||||
{ title: '序列号', key: 'snList', width: '12%', type: FormTypes.input, placeholder: '多个序列号请用逗号隔开',
|
||||
validateRules: [{ pattern: /^\S{1,100}$/, message: '请小于100位字符' }]
|
||||
},
|
||||
{ title: '批号', key: 'batchNumber', width: '5%', type: FormTypes.input },
|
||||
{ title: '有效期', key: 'expirationDate',width: '7%', type: FormTypes.date },
|
||||
{ title: '多属性', key: 'sku', width: '4%', type: FormTypes.normal },
|
||||
{ title: '原数量', key: 'preNumber', width: '4%', type: FormTypes.normal },
|
||||
{ title: '已入库', key: 'finishNumber', width: '4%', type: FormTypes.normal },
|
||||
{ title: '数量', key: 'operNumber', width: '4%', type: FormTypes.inputNumber, statistics: true,
|
||||
validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '单价', key: 'unitPrice', width: '4%', type: FormTypes.inputNumber, validateRules: [{ required: true, message: '${title}不能为空' }]},
|
||||
{ title: '金额', key: 'allPrice', width: '5%', type: FormTypes.inputNumber, statistics: true },
|
||||
{ title: '税率', key: 'taxRate', width: '3%', type: FormTypes.inputNumber,placeholder: '%'},
|
||||
{ title: '税额', key: 'taxMoney', width: '5%', type: FormTypes.inputNumber, readonly: true, statistics: true },
|
||||
{ title: '价税合计', key: 'taxLastMoney', width: '5%', type: FormTypes.inputNumber, statistics: true },
|
||||
{ title: '备注', key: 'remark', width: '5%', type: FormTypes.input }
|
||||
]
|
||||
},
|
||||
confirmLoading: false,
|
||||
validatorRules:{
|
||||
operTime:{
|
||||
rules: [
|
||||
{ required: true, message: '请输入单据日期!' }
|
||||
]
|
||||
},
|
||||
organId:{
|
||||
rules: [
|
||||
{ required: true, message: '请选择供应商!' }
|
||||
]
|
||||
},
|
||||
accountId:{
|
||||
rules: [
|
||||
{ required: true, message: '请选择结算账户!' }
|
||||
]
|
||||
}
|
||||
},
|
||||
url: {
|
||||
add: '/depotHead/addDepotHeadAndDetail',
|
||||
edit: '/depotHead/updateDepotHeadAndDetail',
|
||||
detailList: '/depotItem/getDetailList'
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
},
|
||||
methods: {
|
||||
//调用完edit()方法之后会自动调用此方法
|
||||
editAfter() {
|
||||
this.changeColumnHide()
|
||||
this.changeFormTypes(this.materialTable.columns, 'snList', 0)
|
||||
this.changeFormTypes(this.materialTable.columns, 'batchNumber', 0)
|
||||
this.changeFormTypes(this.materialTable.columns, 'expirationDate', 0)
|
||||
this.changeFormTypes(this.materialTable.columns, 'preNumber', 0)
|
||||
this.changeFormTypes(this.materialTable.columns, 'finishNumber', 0)
|
||||
if (this.action === 'add') {
|
||||
this.addInit(this.prefixNo)
|
||||
this.fileList = []
|
||||
} else {
|
||||
this.model.operTime = this.model.operTimeStr
|
||||
this.model.debt = (this.model.discountLastMoney + this.model.otherMoney - this.model.changeAmount).toFixed(2)
|
||||
if(this.model.accountId == null) {
|
||||
this.model.accountId = 0
|
||||
this.manyAccountBtnStatus = true
|
||||
this.accountIdList = this.model.accountIdList
|
||||
this.accountMoneyList = this.model.accountMoneyList
|
||||
} else {
|
||||
this.manyAccountBtnStatus = false
|
||||
}
|
||||
this.fileList = this.model.fileName
|
||||
this.$nextTick(() => {
|
||||
|
||||
this.form.setFieldsValue(pick(this.model,'organId', 'operTime', 'number', 'linkNumber', 'remark',
|
||||
'discount','discountMoney','discountLastMoney','otherMoney','accountId','changeAmount','debt'))
|
||||
});
|
||||
// 加载子表数据
|
||||
let params = {
|
||||
headerId: this.model.id,
|
||||
mpList: getMpListShort(Vue.ls.get('materialPropertyList')) //扩展属性
|
||||
}
|
||||
let url = this.readOnly ? this.url.detailList : this.url.detailList;
|
||||
this.requestSubTableData(url, params, this.materialTable);
|
||||
}
|
||||
//复制新增单据-初始化单号和日期
|
||||
if(this.action === 'copyAdd') {
|
||||
this.model.id = ''
|
||||
this.model.tenantId = ''
|
||||
this.copyAddInit(this.prefixNo)
|
||||
}
|
||||
this.initSupplier()
|
||||
this.initDepot()
|
||||
this.initAccount()
|
||||
},
|
||||
//提交单据时整理成formData
|
||||
classifyIntoFormData(allValues) {
|
||||
let totalPrice = 0
|
||||
let billMain = Object.assign(this.model, allValues.formValue)
|
||||
let detailArr = allValues.tablesValue[0].values
|
||||
billMain.type = '入库'
|
||||
billMain.subType = '采购'
|
||||
billMain.defaultNumber = billMain.number
|
||||
for(let item of detailArr){
|
||||
totalPrice += item.allPrice-0
|
||||
}
|
||||
billMain.totalPrice = 0-totalPrice
|
||||
billMain.changeAmount = 0-billMain.changeAmount
|
||||
if(billMain.accountId === 0) {
|
||||
billMain.accountId = ''
|
||||
}
|
||||
this.accountMoneyList = changeListFmtMinus(this.accountMoneyList)
|
||||
billMain.accountIdList = this.accountIdList.length>0 ? JSON.stringify(this.accountIdList) : ""
|
||||
billMain.accountMoneyList = this.accountMoneyList.length>0 ? JSON.stringify(this.accountMoneyList) : ""
|
||||
if(this.fileList && this.fileList.length > 0) {
|
||||
billMain.fileName = this.fileList
|
||||
}
|
||||
if(this.model.id){
|
||||
billMain.id = this.model.id
|
||||
}
|
||||
return {
|
||||
info: billMain,
|
||||
rows: detailArr,
|
||||
}
|
||||
},
|
||||
onSearchLinkNumber() {
|
||||
this.$refs.linkBillList.show('其它', '采购订单', '供应商', "1,3")
|
||||
this.$refs.linkBillList.title = "选择采购订单"
|
||||
},
|
||||
linkBillListOk(selectBillRows) {
|
||||
console.log(selectBillRows,'selectBillRows')
|
||||
this.changeFormTypes(this.materialTable.columns, 'preNumber', 1)
|
||||
this.changeFormTypes(this.materialTable.columns, 'finishNumber', 1)
|
||||
if(selectBillRows && selectBillRows.length>0) {
|
||||
let record = selectBillRows[0]
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({
|
||||
'organId': record.organId,
|
||||
'linkNumber': record.number,
|
||||
'remark': record.remark,
|
||||
'discountLastMoney': record.totalPrice,
|
||||
'changeAmount': record.totalPrice,
|
||||
'operTime': record.operTimeStr
|
||||
})
|
||||
});
|
||||
// 加载子表数据
|
||||
let params = {
|
||||
headerId: record.id,
|
||||
mpList: getMpListShort(Vue.ls.get('materialPropertyList')) //扩展属性
|
||||
}
|
||||
this.requestSubTableDataEx(this.url.detailList, params, this.materialTable);
|
||||
}
|
||||
},
|
||||
/** 查询某个tab的数据,给明细里面的价税合计赋值 */
|
||||
requestSubTableDataEx(url, params, tab, success) {
|
||||
tab.loading = true
|
||||
getAction(url, params).then(res => {
|
||||
if(res && res.code === 200){
|
||||
let list = res.data.rows
|
||||
let listEx = []
|
||||
let discountLastMoney = 0
|
||||
for(let j=0; j<list.length; j++){
|
||||
let info = list[j];
|
||||
if(info.preNumber) {
|
||||
info.operNumber = info.preNumber - info.finishNumber
|
||||
// info.allPrice = info.allPrice;
|
||||
// info.allPrice = info.operNumber * info.unitPrice-0;
|
||||
discountLastMoney += info.allPrice
|
||||
}
|
||||
info.taxMoney = 0
|
||||
info.taxLastMoney = info.allPrice
|
||||
listEx.push(info)
|
||||
this.changeColumnShow(info)
|
||||
}
|
||||
tab.dataSource = listEx
|
||||
//给优惠后金额重新赋值
|
||||
if(discountLastMoney) {
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({
|
||||
'discountLastMoney': discountLastMoney,
|
||||
'changeAmount': discountLastMoney
|
||||
})
|
||||
});
|
||||
}
|
||||
typeof success === 'function' ? success(res) : ''
|
||||
}
|
||||
}).finally(() => {
|
||||
tab.loading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,274 @@
|
||||
<template>
|
||||
<j-modal
|
||||
:title="title"
|
||||
:width="width"
|
||||
:visible="visible"
|
||||
:confirmLoading="confirmLoading"
|
||||
:maskClosable="false"
|
||||
:keyboard="false"
|
||||
:forceRender="true"
|
||||
v-bind:prefixNo="prefixNo"
|
||||
switchHelp
|
||||
switchFullscreen
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
wrapClassName="ant-modal-cust-warp"
|
||||
:id="prefixNo"
|
||||
style="top:5%;height: 100%;overflow-y: hidden">
|
||||
<a-spin :spinning="confirmLoading">
|
||||
<a-form :form="form">
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="供应商" data-step="1" data-title="供应商"
|
||||
data-intro="供应商必须选择,如果发现需要选择的供应商尚未录入,可以在下拉框中点击新增供应商进行录入">
|
||||
<a-select placeholder="选择供应商" v-decorator="[ 'organId', validatorRules.organId ]"
|
||||
:dropdownMatchSelectWidth="false" showSearch optionFilterProp="children">
|
||||
<div slot="dropdownRender" slot-scope="menu">
|
||||
<v-nodes :vnodes="menu" />
|
||||
<a-divider style="margin: 4px 0;" />
|
||||
<div v-if="isTenant" style="padding: 4px 8px; cursor: pointer;"
|
||||
@mousedown="e => e.preventDefault()" @click="addSupplier"><a-icon type="plus" /> 新增供应商</div>
|
||||
</div>
|
||||
<a-select-option v-for="(item,index) in supList" :key="index" :value="Number(item.id)">
|
||||
{{ item.supplier }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="单据日期">
|
||||
<j-date v-decorator="['operTime', validatorRules.operTime]" :show-time="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="单据编号" data-step="2" data-title="单据编号"
|
||||
data-intro="单据编号自动生成、自动累加、开头是单据类型的首字母缩写,累加的规则是每次打开页面会自动占用一个新的编号">
|
||||
<a-input placeholder="请输入单据编号" v-decorator.trim="[ 'number' ]" :readOnly="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24"></a-col>
|
||||
</a-row>
|
||||
<j-editable-table id="billModal"
|
||||
:ref="refKeys[0]"
|
||||
:loading="materialTable.loading"
|
||||
:columns="materialTable.columns"
|
||||
:dataSource="materialTable.dataSource"
|
||||
:maxHeight="300"
|
||||
:rowNumber="false"
|
||||
:rowSelection="true"
|
||||
:actionButton="true"
|
||||
:dragSort="true"
|
||||
@valueChange="onValueChange"
|
||||
@deleted="onDeleted">
|
||||
<template #buttonAfter>
|
||||
<a-row :gutter="24" style="float:left;" data-step="3" data-title="扫码录入" data-intro="此功能支持扫码枪扫描商品物料编码进行录入">
|
||||
<a-col v-if="scanStatus" :md="6" :sm="24">
|
||||
<a-button @click="scanEnter">扫码录入</a-button>
|
||||
</a-col>
|
||||
<a-col v-if="!scanStatus" :md="16" :sm="24" style="padding: 0 6px 0 12px">
|
||||
<a-input placeholder="请扫码商品物料编码并回车" v-model="scanBarCode" @pressEnter="scanPressEnter" ref="scanBarCode"/>
|
||||
</a-col>
|
||||
<a-col v-if="!scanStatus" :md="6" :sm="24" style="padding: 0px">
|
||||
<a-button @click="stopScan">收起扫码</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-button type="primary" @click="clearKh" style="margin-left:10px">清空空行</a-button>
|
||||
</template>
|
||||
</j-editable-table>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="24" :md="24" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="{xs: { span: 24 },sm: { span: 24 }}" label="">
|
||||
<a-textarea :rows="1" placeholder="请输入备注" v-decorator="[ 'remark' ]" style="margin-top:8px;"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="优惠率" data-step="5" data-title="优惠率"
|
||||
data-intro="针对单据明细中商品总金额进行优惠的比例">
|
||||
<a-input style="width:185px;" placeholder="请输入优惠率" v-decorator.trim="[ 'discount' ]" suffix="%" @keyup="onKeyUpDiscount"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="付款优惠" data-step="6" data-title="付款优惠"
|
||||
data-intro="针对单据明细中商品总金额进行优惠的金额">
|
||||
<a-input placeholder="请输入付款优惠" v-decorator.trim="[ 'discountMoney' ]" @keyup="onKeyUpDiscountMoney"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="优惠后金额" data-step="7" data-title="优惠后金额"
|
||||
data-intro="针对单据明细中商品总金额进行优惠后的金额">
|
||||
<a-input placeholder="请输入优惠后金额" v-decorator.trim="[ 'discountLastMoney' ]" :readOnly="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="附件" data-step="4" data-title="附件" data-intro="可以上传与单据相关的图片、文档,支持多个文件">
|
||||
<j-upload v-model="fileList" bizPath="bill"></j-upload>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
<vendor-modal ref="vendorModalForm" @ok="vendorModalFormOk"></vendor-modal>
|
||||
</j-modal>
|
||||
</template>
|
||||
<script>
|
||||
import pick from 'lodash.pick'
|
||||
import VendorModal from '../../system/modules/VendorModal'
|
||||
import { FormTypes } from '@/utils/JEditableTableUtil'
|
||||
import { JEditableTableMixin } from '@/mixins/JEditableTableMixin'
|
||||
import { BillModalMixin } from '../mixins/BillModalMixin'
|
||||
import { getMpListShort } from "@/utils/util"
|
||||
import JUpload from '@/components/jeecg/JUpload'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
export default {
|
||||
name: "PurchaseOrderModal",
|
||||
mixins: [JEditableTableMixin,BillModalMixin],
|
||||
components: {
|
||||
VendorModal,
|
||||
JUpload,
|
||||
JDate,
|
||||
VNodes: {
|
||||
functional: true,
|
||||
render: (h, ctx) => ctx.props.vnodes,
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
title:"操作",
|
||||
width: '100%',
|
||||
moreStatus: false,
|
||||
// 新增时子表默认添加几行空数据
|
||||
addDefaultRowNum: 10,
|
||||
visible: false,
|
||||
supList: [],
|
||||
depotList: [],
|
||||
operTimeStr: '',
|
||||
prefixNo: 'CGDD',
|
||||
fileList:[],
|
||||
model: {},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 8 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
refKeys: ['materialDataTable', ],
|
||||
tableKeys:['materialDataTable', ],
|
||||
activeKey: 'materialDataTable',
|
||||
materialTable: {
|
||||
loading: false,
|
||||
dataSource: [],
|
||||
columns: [
|
||||
{ title: '仓库名称', key: 'depotId', width: '7%', type: FormTypes.hidden },
|
||||
{ title: '物料编码', key: 'barCode', width: '8%', type: FormTypes.popupJsh, kind: 'material', multi: true,
|
||||
validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '名称', key: 'name', width: '20%', type: FormTypes.normal },
|
||||
{ title: '规格', key: 'standard', width: '5%', type: FormTypes.normal },
|
||||
{ title: '型号', key: 'model', width: '5%', type: FormTypes.normal },
|
||||
{ title: '颜色', key: 'color', width: '5%', type: FormTypes.normal },
|
||||
{ title: '扩展信息', key: 'materialOther', width: '5%', type: FormTypes.normal },
|
||||
{ title: '库存', key: 'stock', width: '5%', type: FormTypes.inputNumber, readonly:true},
|
||||
{ title: '单位', key: 'unit', width: '4%', type: FormTypes.normal },
|
||||
{ title: '多属性', key: 'sku', width: '4%', type: FormTypes.normal },
|
||||
{ title: '数量', key: 'operNumber', width: '5%', type: FormTypes.inputNumber, statistics: true,
|
||||
validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '单价', key: 'unitPrice', width: '5%', type: FormTypes.inputNumber },
|
||||
{ title: '金额', key: 'allPrice', width: '5%', type: FormTypes.inputNumber, statistics: true },
|
||||
{ title: '税率', key: 'taxRate', width: '3%', type: FormTypes.inputNumber,placeholder: '%'},
|
||||
{ title: '税额', key: 'taxMoney', width: '5%', type: FormTypes.inputNumber, readonly: true, statistics: true },
|
||||
{ title: '价税合计', key: 'taxLastMoney', width: '5%', type: FormTypes.inputNumber, statistics: true },
|
||||
{ title: '备注', key: 'remark', width: '5%', type: FormTypes.input}
|
||||
]
|
||||
},
|
||||
confirmLoading: false,
|
||||
validatorRules:{
|
||||
operTime:{
|
||||
rules: [
|
||||
{ required: true, message: '请输入单据日期!' }
|
||||
]
|
||||
},
|
||||
organId:{
|
||||
rules: [
|
||||
{ required: true, message: '请选择供应商!' }
|
||||
]
|
||||
}
|
||||
},
|
||||
url: {
|
||||
add: '/depotHead/addDepotHeadAndDetail',
|
||||
edit: '/depotHead/updateDepotHeadAndDetail',
|
||||
detailList: '/depotItem/getDetailList'
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
},
|
||||
methods: {
|
||||
//调用完edit()方法之后会自动调用此方法
|
||||
editAfter() {
|
||||
this.changeColumnHide()
|
||||
if (this.action === 'add') {
|
||||
this.addInit(this.prefixNo)
|
||||
this.fileList = []
|
||||
} else {
|
||||
this.model.operTime = this.model.operTimeStr
|
||||
this.fileList = this.model.fileName
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue(pick(this.model,'organId', 'operTime', 'number', 'remark',
|
||||
'discount','discountMoney','discountLastMoney'))
|
||||
});
|
||||
// 加载子表数据
|
||||
let params = {
|
||||
headerId: this.model.id,
|
||||
mpList: getMpListShort(Vue.ls.get('materialPropertyList')) //扩展属性
|
||||
}
|
||||
let url = this.readOnly ? this.url.detailList : this.url.detailList;
|
||||
this.requestSubTableData(url, params, this.materialTable);
|
||||
}
|
||||
//复制新增单据-初始化单号和日期
|
||||
if(this.action === 'copyAdd') {
|
||||
this.model.id = ''
|
||||
this.model.tenantId = ''
|
||||
this.copyAddInit(this.prefixNo)
|
||||
}
|
||||
this.initSupplier()
|
||||
},
|
||||
/** 整理成formData */
|
||||
classifyIntoFormData(allValues) {
|
||||
let totalPrice = 0
|
||||
let billMain = Object.assign(this.model, allValues.formValue)
|
||||
let detailArr = allValues.tablesValue[0].values
|
||||
billMain.type = '其它'
|
||||
billMain.subType = '采购订单'
|
||||
billMain.defaultNumber = billMain.number
|
||||
for(let item of detailArr){
|
||||
item.depotId = '' //订单不需要仓库
|
||||
totalPrice += item.allPrice-0
|
||||
}
|
||||
billMain.totalPrice = 0-totalPrice
|
||||
if(this.fileList && this.fileList.length > 0) {
|
||||
billMain.fileName = this.fileList
|
||||
}
|
||||
if(this.model.id){
|
||||
billMain.id = this.model.id
|
||||
}
|
||||
return {
|
||||
info: billMain,
|
||||
rows: detailArr,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,409 @@
|
||||
<template>
|
||||
<j-modal
|
||||
:title="title"
|
||||
:width="width"
|
||||
:visible="visible"
|
||||
:confirmLoading="confirmLoading"
|
||||
:maskClosable="false"
|
||||
:keyboard="false"
|
||||
:forceRender="true"
|
||||
switchFullscreen
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
wrapClassName="ant-modal-cust-warp"
|
||||
style="top:5%;height: 100%;overflow-y: hidden">
|
||||
<a-spin :spinning="confirmLoading">
|
||||
<a-form :form="form">
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="会员卡号">
|
||||
<a-select placeholder="选择会员卡号" v-decorator="[ 'organId' ]"
|
||||
:dropdownMatchSelectWidth="false" showSearch optionFilterProp="children">
|
||||
<div slot="dropdownRender" slot-scope="menu">
|
||||
<v-nodes :vnodes="menu" />
|
||||
<a-divider style="margin: 4px 0;" />
|
||||
<div v-if="isTenant" style="padding: 4px 8px; cursor: pointer;"
|
||||
@mousedown="e => e.preventDefault()" @click="addMember"><a-icon type="plus" /> 新增会员</div>
|
||||
</div>
|
||||
<a-select-option v-for="(item,index) in retailList" :key="index" :value="item.id">
|
||||
{{ item.supplier }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="单据日期">
|
||||
<j-date v-decorator="['operTime', validatorRules.operTime]" :show-time="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="单据编号">
|
||||
<a-input placeholder="请输入单据编号" v-decorator.trim="[ 'number' ]" :readOnly="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="关联单据">
|
||||
<a-input-search placeholder="请选择关联单据" v-decorator="[ 'linkNumber' ]" @search="onSearchLinkNumber" :readOnly="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="18" :md="12" :sm="24">
|
||||
<j-editable-table id="billModal"
|
||||
:ref="refKeys[0]"
|
||||
:loading="materialTable.loading"
|
||||
:columns="materialTable.columns"
|
||||
:dataSource="materialTable.dataSource"
|
||||
:minWidth="400"
|
||||
:maxHeight="300"
|
||||
:rowNumber="false"
|
||||
:rowSelection="true"
|
||||
:actionButton="true"
|
||||
:dragSort="true"
|
||||
@valueChange="onValueChange"
|
||||
@added="onAdded"
|
||||
@deleted="onDeleted">
|
||||
<template #buttonAfter>
|
||||
<a-row :gutter="24" style="float:left;" data-step="4" data-title="扫码录入" data-intro="此功能支持扫码枪扫描商品物料编码进行录入">
|
||||
<a-col v-if="scanStatus" :md="6" :sm="24">
|
||||
<a-button @click="scanEnter">扫码录入</a-button>
|
||||
</a-col>
|
||||
<a-col v-if="!scanStatus" :md="16" :sm="24" style="padding: 0 6px 0 12px">
|
||||
<a-input placeholder="请扫码商品物料编码并回车" v-model="scanBarCode" @pressEnter="scanPressEnter" ref="scanBarCode"/>
|
||||
</a-col>
|
||||
<a-col v-if="!scanStatus" :md="6" :sm="24" style="padding: 0px">
|
||||
<a-button @click="stopScan">收起扫码</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="24" style="float:left;">
|
||||
<a-col :md="24" :sm="24">
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" @click="handleBatchSetDepot"><a-icon type="setting"/>批量设置</a-menu-item>
|
||||
<a-menu-item v-if="isTenant" key="2" @click="addDepot"><a-icon type="plus"/>新增仓库</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button style="margin-left: 8px">仓库操作 <a-icon type="down" /></a-button>
|
||||
</a-dropdown>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-button type="primary" @click="clearKh" style="margin-left:10px">清空空行</a-button>
|
||||
</template>
|
||||
</j-editable-table>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="24" :md="24" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="{xs: { span: 24 },sm: { span: 24 }}" label="">
|
||||
<a-textarea :rows="1" placeholder="请输入备注" v-decorator="[ 'remark' ]" style="margin-top:8px;"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="附件">
|
||||
<j-upload v-model="fileList" bizPath="bill"></j-upload>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col >
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<span slot="label" style="font-size: 20px;line-height:20px">单据金额</span>
|
||||
<a-input v-decorator.trim="[ 'changeAmount' ]" :style="{color:'purple'}" :readOnly="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col >
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<span slot="label" style="font-size: 20px;line-height:20px">付款金额</span>
|
||||
<a-input v-decorator.trim="[ 'getAmount' ]" :style="{color:'red'}" defaultValue="0" @keyup="onKeyUpGetAmount"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col >
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<span slot="label" style="font-size: 20px;line-height:20px">找零</span>
|
||||
<a-input v-decorator.trim="[ 'backAmount' ]" :style="{color:'green'}" :readOnly="true" defaultValue="0"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col>
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<span slot="label" style="font-size: 20px;line-height:20px">付款账户</span>
|
||||
<a-select placeholder="选择付款账户" style="font-size:20px;" v-decorator="[ 'accountId']" :dropdownMatchSelectWidth="false">
|
||||
<div slot="dropdownRender" slot-scope="menu">
|
||||
<v-nodes :vnodes="menu" />
|
||||
<a-divider style="margin: 4px 0;" />
|
||||
<div v-if="isTenant" style="padding: 4px 8px; cursor: pointer;"
|
||||
@mousedown="e => e.preventDefault()" @click="addAccount"><a-icon type="plus" /> 新增结算账户</div>
|
||||
</div>
|
||||
<a-select-option v-for="(item,index) in accountList" :key="index" :value="item.id">
|
||||
{{ item.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
<link-bill-list ref="linkBillList" @ok="linkBillListOk"></link-bill-list>
|
||||
<member-modal ref="memberModalForm" @ok="memberModalFormOk"></member-modal>
|
||||
<depot-modal ref="depotModalForm" @ok="depotModalFormOk"></depot-modal>
|
||||
<account-modal ref="accountModalForm" @ok="accountModalFormOk"></account-modal>
|
||||
<batch-set-depot ref="batchSetDepotModalForm" @ok="batchSetDepotModalFormOk"></batch-set-depot>
|
||||
</j-modal>
|
||||
</template>
|
||||
<script>
|
||||
import pick from 'lodash.pick'
|
||||
import LinkBillList from '../dialog/LinkBillList'
|
||||
import MemberModal from '../../system/modules/MemberModal'
|
||||
import DepotModal from '../../system/modules/DepotModal'
|
||||
import AccountModal from '../../system/modules/AccountModal'
|
||||
import BatchSetDepot from '../dialog/BatchSetDepot'
|
||||
import { FormTypes } from '@/utils/JEditableTableUtil'
|
||||
import { JEditableTableMixin } from '@/mixins/JEditableTableMixin'
|
||||
import { BillModalMixin } from '../mixins/BillModalMixin'
|
||||
import { getMpListShort } from "@/utils/util"
|
||||
import { getAccount } from '@/api/api'
|
||||
import { getAction } from '@/api/manage'
|
||||
import JUpload from '@/components/jeecg/JUpload'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
export default {
|
||||
name: "RetailBackModal",
|
||||
mixins: [JEditableTableMixin, BillModalMixin],
|
||||
components: {
|
||||
LinkBillList,
|
||||
MemberModal,
|
||||
DepotModal,
|
||||
AccountModal,
|
||||
BatchSetDepot,
|
||||
JUpload,
|
||||
JDate,
|
||||
VNodes: {
|
||||
functional: true,
|
||||
render: (h, ctx) => ctx.props.vnodes,
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
title:"操作",
|
||||
width: '100%',
|
||||
moreStatus: false,
|
||||
// 新增时子表默认添加几行空数据
|
||||
addDefaultRowNum: 10,
|
||||
visible: false,
|
||||
operTimeStr: '',
|
||||
prefixNo: 'LSTH',
|
||||
fileList:[],
|
||||
model: {},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 8 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
refKeys: ['materialDataTable', ],
|
||||
activeKey: 'materialDataTable',
|
||||
materialTable: {
|
||||
loading: false,
|
||||
dataSource: [],
|
||||
columns: [
|
||||
{ title: '仓库名称', key: 'depotId', width: '7%', type: FormTypes.select, placeholder: '请选择${title}', options: [],
|
||||
allowSearch:true, validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '物料编码', key: 'barCode', width: '12%', type: FormTypes.popupJsh, kind: 'material', multi: true,
|
||||
validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '名称', key: 'name', width: '20%', type: FormTypes.normal },
|
||||
{ title: '规格', key: 'standard', width: '6%', type: FormTypes.normal },
|
||||
{ title: '型号', key: 'model', width: '6%', type: FormTypes.normal },
|
||||
{ title: '颜色', key: 'color', width: '5%', type: FormTypes.normal },
|
||||
{ title: '扩展信息', key: 'materialOther', width: '7%', type: FormTypes.normal },
|
||||
{ title: '库存', key: 'stock', width: '5%', type: FormTypes.inputNumber, readonly:true },
|
||||
{ title: '单位', key: 'unit', width: '4%', type: FormTypes.normal },
|
||||
{ title: '序列号', key: 'snList', width: '12%', type: FormTypes.input, placeholder: '多个序列号请用逗号隔开',
|
||||
validateRules: [{ pattern: /^\S{1,100}$/, message: '请小于100位字符' }]
|
||||
},
|
||||
{ title: '批号', key: 'batchNumber', width: '7%', type: FormTypes.input },
|
||||
{ title: '有效期', key: 'expirationDate',width: '9%', type: FormTypes.date },
|
||||
{ title: '多属性', key: 'sku', width: '5%', type: FormTypes.normal },
|
||||
{ title: '数量', key: 'operNumber', width: '5%', type: FormTypes.inputNumber, statistics: true,
|
||||
validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '单价', key: 'unitPrice', width: '5%', type: FormTypes.inputNumber},
|
||||
{ title: '金额', key: 'allPrice', width: '5%', type: FormTypes.inputNumber, statistics: true },
|
||||
{ title: '备注', key: 'remark', width: '7%', type: FormTypes.input }
|
||||
]
|
||||
},
|
||||
confirmLoading: false,
|
||||
validatorRules:{
|
||||
operTime:{
|
||||
rules: [
|
||||
{ required: true, message: '请输入单据日期!' }
|
||||
]
|
||||
},
|
||||
accountId:{
|
||||
rules: [
|
||||
{ required: true, message: '请选择结算账户!' }
|
||||
]
|
||||
}
|
||||
},
|
||||
url: {
|
||||
add: '/depotHead/addDepotHeadAndDetail',
|
||||
edit: '/depotHead/updateDepotHeadAndDetail',
|
||||
detailList: '/depotItem/getDetailList'
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
},
|
||||
methods: {
|
||||
//调用完edit()方法之后会自动调用此方法
|
||||
editAfter() {
|
||||
this.changeColumnHide()
|
||||
this.changeFormTypes(this.materialTable.columns, 'snList', 0)
|
||||
this.changeFormTypes(this.materialTable.columns, 'batchNumber', 0)
|
||||
this.changeFormTypes(this.materialTable.columns, 'expirationDate', 0)
|
||||
if (this.action === 'add') {
|
||||
this.addInit(this.prefixNo)
|
||||
this.fileList = []
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({'getAmount':0, 'backAmount':0})
|
||||
})
|
||||
} else {
|
||||
this.model.operTime = this.model.operTimeStr
|
||||
if(this.model.backAmount) {
|
||||
this.model.getAmount = (this.model.changeAmount + this.model.backAmount).toFixed(2)
|
||||
} else {
|
||||
this.model.getAmount = this.model.changeAmount
|
||||
}
|
||||
this.fileList = this.model.fileName
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue(pick(this.model,'organId', 'operTime', 'number', 'linkNumber', 'remark',
|
||||
'discount','discountMoney','discountLastMoney','otherMoney','accountId','changeAmount','getAmount','backAmount'))
|
||||
});
|
||||
// 加载子表数据
|
||||
let params = {
|
||||
headerId: this.model.id,
|
||||
mpList: getMpListShort(Vue.ls.get('materialPropertyList')) //扩展属性
|
||||
}
|
||||
let url = this.readOnly ? this.url.detailList : this.url.detailList;
|
||||
this.requestSubTableData(url, params, this.materialTable);
|
||||
}
|
||||
//复制新增单据-初始化单号和日期
|
||||
if(this.action === 'copyAdd') {
|
||||
this.model.id = ''
|
||||
this.model.tenantId = ''
|
||||
this.copyAddInit(this.prefixNo)
|
||||
}
|
||||
this.initRetail()
|
||||
this.initDepot()
|
||||
this.initAccount()
|
||||
},
|
||||
//提交单据时整理成formData
|
||||
classifyIntoFormData(allValues) {
|
||||
let totalPrice = 0
|
||||
let billMain = Object.assign(this.model, allValues.formValue)
|
||||
let detailArr = allValues.tablesValue[0].values
|
||||
billMain.type = '入库'
|
||||
billMain.subType = '零售退货'
|
||||
billMain.defaultNumber = billMain.number
|
||||
for(let item of detailArr){
|
||||
totalPrice += item.allPrice-0
|
||||
}
|
||||
billMain.totalPrice = 0-totalPrice
|
||||
billMain.changeAmount = 0-billMain.changeAmount
|
||||
if(this.fileList && this.fileList.length > 0) {
|
||||
billMain.fileName = this.fileList
|
||||
}
|
||||
if(this.model.id){
|
||||
billMain.id = this.model.id
|
||||
}
|
||||
return {
|
||||
info: billMain,
|
||||
rows: detailArr,
|
||||
}
|
||||
},
|
||||
initAccount(){
|
||||
getAccount({}).then((res)=>{
|
||||
if(res && res.code === 200) {
|
||||
this.accountList = res.data.accountList
|
||||
}
|
||||
})
|
||||
},
|
||||
//改变实收金额、收款金额的值
|
||||
autoChangePrice(target) {
|
||||
let allLastMoney = target.statisticsColumns.allPrice
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({'changeAmount':allLastMoney,'getAmount':allLastMoney,'backAmount':0})
|
||||
});
|
||||
},
|
||||
//改变收款金额
|
||||
onKeyUpGetAmount(e) {
|
||||
const value = e.target.value
|
||||
let changeAmount = this.form.getFieldValue('changeAmount')-0
|
||||
let backAmount = (value - changeAmount).toFixed(2)-0
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({'backAmount':backAmount})
|
||||
});
|
||||
},
|
||||
onSearchLinkNumber() {
|
||||
this.$refs.linkBillList.show('出库', '零售', '会员', "1")
|
||||
this.$refs.linkBillList.title = "选择零售出库"
|
||||
},
|
||||
linkBillListOk(selectBillRows) {
|
||||
if(selectBillRows && selectBillRows.length>0) {
|
||||
let record = selectBillRows[0]
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({
|
||||
'organId': record.organId,
|
||||
'linkNumber': record.number,
|
||||
'remark': record.remark,
|
||||
'getAmount': record.totalPrice,
|
||||
'changeAmount': record.totalPrice,
|
||||
'backAmount': 0
|
||||
})
|
||||
});
|
||||
// 加载子表数据
|
||||
let params = {
|
||||
headerId: record.id,
|
||||
mpList: getMpListShort(Vue.ls.get('materialPropertyList')) //扩展属性
|
||||
}
|
||||
this.requestSubTableDataEx(this.url.detailList, params, this.materialTable);
|
||||
}
|
||||
},
|
||||
/** 查询某个tab的数据,给明细里面的价税合计赋值 */
|
||||
requestSubTableDataEx(url, params, tab, success) {
|
||||
tab.loading = true
|
||||
getAction(url, params).then(res => {
|
||||
if(res && res.code === 200){
|
||||
let list = res.data.rows
|
||||
let listEx = []
|
||||
for(let j=0; j<list.length; j++){
|
||||
let info = list[j];
|
||||
info.taxMoney = 0
|
||||
info.taxLastMoney = info.allPrice
|
||||
listEx.push(info)
|
||||
}
|
||||
tab.dataSource = listEx
|
||||
typeof success === 'function' ? success(res) : ''
|
||||
}
|
||||
}).finally(() => {
|
||||
tab.loading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.ant-input{
|
||||
font-size: 30px;
|
||||
font-weight:bolder;
|
||||
text-align:center;
|
||||
border-left-width:0px!important;
|
||||
border-top-width:0px!important;
|
||||
border-right-width:0px!important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,404 @@
|
||||
<template>
|
||||
<j-modal
|
||||
:title="title"
|
||||
:width="width"
|
||||
:visible="visible"
|
||||
:confirmLoading="confirmLoading"
|
||||
:maskClosable="false"
|
||||
:keyboard="false"
|
||||
:forceRender="true"
|
||||
v-bind:prefixNo="prefixNo"
|
||||
switchHelp
|
||||
switchFullscreen
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
wrapClassName="ant-modal-cust-warp"
|
||||
:id="prefixNo"
|
||||
style="top:5%;height: 100%;overflow-y: hidden">
|
||||
<a-spin :spinning="confirmLoading">
|
||||
<a-form :form="form">
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="会员卡号" data-step="1" data-title="会员卡号"
|
||||
data-intro="如果发现需要选择的会员卡号尚未录入,可以在下拉框中点击新增会员信息进行录入">
|
||||
<a-select placeholder="选择会员卡号" v-decorator="[ 'organId' ]"
|
||||
:dropdownMatchSelectWidth="false" showSearch optionFilterProp="children" @change="onChangeOrgan">
|
||||
<div slot="dropdownRender" slot-scope="menu">
|
||||
<v-nodes :vnodes="menu" />
|
||||
<a-divider style="margin: 4px 0;" />
|
||||
<div v-if="isTenant" style="padding: 4px 8px; cursor: pointer;"
|
||||
@mousedown="e => e.preventDefault()" @click="addMember"><a-icon type="plus" /> 新增会员</div>
|
||||
</div>
|
||||
<a-select-option v-for="(item,index) in retailList" :key="index" :value="item.id">
|
||||
{{ item.supplier }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="单据日期">
|
||||
<j-date v-decorator="['operTime', validatorRules.operTime]" :show-time="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="单据编号" data-step="2" data-title="单据编号"
|
||||
data-intro="单据编号自动生成、自动累加、开头是单据类型的首字母缩写,累加的规则是每次打开页面会自动占用一个新的编号">
|
||||
<a-input placeholder="请输入单据编号" v-decorator.trim="[ 'number' ]" :readOnly="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="收款类型" data-step="3" data-title="收款类型"
|
||||
data-intro="收款类型可以有现付和预付款两种类型,当选择了会员之后,如果该会员有预付款,在此处会显示具体预付款的金额,而且系统会优先默认选中预付款">
|
||||
<a-select placeholder="请选择付款类型" v-decorator="[ 'payType' ]" :dropdownMatchSelectWidth="false">
|
||||
<a-select-option v-for="(item,index) in payTypeList" :key="index" :value="item.value">
|
||||
{{ item.text }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="16" :md="12" :sm="24">
|
||||
<j-editable-table id="billModal"
|
||||
:ref="refKeys[0]"
|
||||
:loading="materialTable.loading"
|
||||
:columns="materialTable.columns"
|
||||
:dataSource="materialTable.dataSource"
|
||||
:minWidth="400"
|
||||
:maxHeight="300"
|
||||
:rowNumber="false"
|
||||
:rowSelection="true"
|
||||
:actionButton="true"
|
||||
:dragSort="true"
|
||||
@valueChange="onValueChange"
|
||||
@added="onAdded"
|
||||
@deleted="onDeleted">
|
||||
<template #buttonAfter>
|
||||
<a-row :gutter="24" style="float:left;" data-step="4" data-title="扫码录入" data-intro="此功能支持扫码枪扫描商品物料编码进行录入">
|
||||
<a-col v-if="scanStatus" :md="6" :sm="24">
|
||||
<a-button @click="scanEnter">扫码录入</a-button>
|
||||
</a-col>
|
||||
<a-col v-if="!scanStatus" :md="16" :sm="24" style="padding: 0 6px 0 12px">
|
||||
<a-input placeholder="请扫码商品物料编码并回车" v-model="scanBarCode" @pressEnter="scanPressEnter" ref="scanBarCode"/>
|
||||
</a-col>
|
||||
<a-col v-if="!scanStatus" :md="6" :sm="24" style="padding: 0px">
|
||||
<a-button @click="stopScan">收起扫码</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="24" style="float:left;">
|
||||
<a-col :md="24" :sm="24">
|
||||
<a-dropdown>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1" @click="handleBatchSetDepot"><a-icon type="setting"/>批量设置</a-menu-item>
|
||||
<a-menu-item v-if="isTenant" key="2" @click="addDepot"><a-icon type="plus"/>新增仓库</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button style="margin-left: 8px">仓库操作 <a-icon type="down" /></a-button>
|
||||
</a-dropdown>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-button type="primary" @click="clearKh" style="margin-left:10px">清空空行</a-button>
|
||||
</template>
|
||||
</j-editable-table>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="24" :md="24" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="{xs: { span: 24 },sm: { span: 24 }}" label="">
|
||||
<a-textarea :rows="1" placeholder="请输入备注" v-decorator="[ 'remark' ]" style="margin-top:8px;"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col :lg="6" :md="12" :sm="24">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="附件" data-step="9" data-title="附件"
|
||||
data-intro="可以上传与单据相关的图片、文档,支持多个文件">
|
||||
<j-upload v-model="fileList" bizPath="bill"></j-upload>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-col>
|
||||
|
||||
<a-col :lg="8" :md="12" :sm="24">
|
||||
<a-row class="form-row" :gutter="24">
|
||||
<a-col>
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" data-step="5" data-title="单据金额"
|
||||
data-intro="单据金额等于左侧商品的总金额">
|
||||
<span slot="label" style="font-size: 24px;line-height:24px">单据金额</span>
|
||||
<a-input v-decorator.trim="[ 'changeAmount' ]" :style="{color:'purple'}" :readOnly="true"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col >
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" data-step="6" data-title="收款金额"
|
||||
data-intro="收款金额为收银员收取用户的实际金额">
|
||||
<span slot="label" style="font-size: 24px;line-height:24px">收款金额</span>
|
||||
<a-input v-decorator.trim="[ 'getAmount' ]" :style="{color:'red'}" @keyup="onKeyUpGetAmount"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col >
|
||||
<!-- <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" data-step="7" data-title="找零"
|
||||
data-intro="找零等于收款金额减去实收金额">
|
||||
<span slot="label" style="font-size: 24px;line-height:24px">找零</span>
|
||||
<a-input v-decorator.trim="[ 'backAmount' ]" :style="{color:'green'}" :readOnly="true" />
|
||||
</a-form-item> -->
|
||||
</a-col>
|
||||
<a-col >
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" data-step="8" data-title="收款账户"
|
||||
data-intro="收款账户的信息来自基本资料菜单下的【结算账户】">
|
||||
<span slot="label" style="font-size: 24px;line-height:24px">收款账户</span>
|
||||
<a-select placeholder="选择收款账户" style="font-size:20px;" v-decorator="[ 'accountId']" :dropdownMatchSelectWidth="false">
|
||||
<div slot="dropdownRender" slot-scope="menu">
|
||||
<v-nodes :vnodes="menu" />
|
||||
<a-divider style="margin: 4px 0;" />
|
||||
<div v-if="isTenant" style="padding: 4px 8px; cursor: pointer;"
|
||||
@mousedown="e => e.preventDefault()" @click="addAccount"><a-icon type="plus" /> 新增结算账户</div>
|
||||
</div>
|
||||
<a-select-option v-for="(item,index) in accountList" :key="index" :value="item.id">
|
||||
{{ item.name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
<member-modal ref="memberModalForm" @ok="memberModalFormOk"></member-modal>
|
||||
<depot-modal ref="depotModalForm" @ok="depotModalFormOk"></depot-modal>
|
||||
<account-modal ref="accountModalForm" @ok="accountModalFormOk"></account-modal>
|
||||
<batch-set-depot ref="batchSetDepotModalForm" @ok="batchSetDepotModalFormOk"></batch-set-depot>
|
||||
</j-modal>
|
||||
</template>
|
||||
<script>
|
||||
import pick from 'lodash.pick'
|
||||
import MemberModal from '../../system/modules/MemberModal'
|
||||
import DepotModal from '../../system/modules/DepotModal'
|
||||
import AccountModal from '../../system/modules/AccountModal'
|
||||
import BatchSetDepot from '../dialog/BatchSetDepot'
|
||||
import { FormTypes} from '@/utils/JEditableTableUtil'
|
||||
import { JEditableTableMixin } from '@/mixins/JEditableTableMixin'
|
||||
import { BillModalMixin } from '../mixins/BillModalMixin'
|
||||
import { getMpListShort } from "@/utils/util"
|
||||
import { getAccount } from '@/api/api'
|
||||
import { getAction } from '@/api/manage'
|
||||
import JUpload from '@/components/jeecg/JUpload'
|
||||
import JDate from '@/components/jeecg/JDate'
|
||||
import Vue from 'vue'
|
||||
|
||||
export default {
|
||||
name: "RetailOutModal",
|
||||
mixins: [JEditableTableMixin, BillModalMixin],
|
||||
components: {
|
||||
MemberModal,
|
||||
DepotModal,
|
||||
AccountModal,
|
||||
BatchSetDepot,
|
||||
JUpload,
|
||||
JDate,
|
||||
VNodes: {
|
||||
functional: true,
|
||||
render: (h, ctx) => ctx.props.vnodes,
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
title:"操作",
|
||||
width: '100%',
|
||||
moreStatus: false,
|
||||
// 新增时子表默认添加几行空数据
|
||||
addDefaultRowNum: 10,
|
||||
visible: false,
|
||||
operTimeStr: '',
|
||||
prefixNo: 'LSCK',
|
||||
fileList:[],
|
||||
payTypeList: [],
|
||||
model: {},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 8 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
refKeys: ['materialDataTable', ],
|
||||
activeKey: 'materialDataTable',
|
||||
materialTable: {
|
||||
loading: false,
|
||||
dataSource: [],
|
||||
columns: [
|
||||
{ title: '仓库名称', key: 'depotId', width: '7%', type: FormTypes.select, placeholder: '请选择${title}', options: [],
|
||||
allowSearch:true, validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '物料编码', key: 'barCode', width: '12%', type: FormTypes.popupJsh, kind: 'material', multi: true,
|
||||
validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '名称', key: 'name', width: '20%', type: FormTypes.normal },
|
||||
{ title: '规格', key: 'standard', width: '6%', type: FormTypes.normal },
|
||||
{ title: '型号', key: 'model', width: '5%', type: FormTypes.normal },
|
||||
{ title: '颜色', key: 'color', width: '5%', type: FormTypes.normal },
|
||||
{ title: '扩展信息', key: 'materialOther', width: '7%', type: FormTypes.normal },
|
||||
{ title: '库存', key: 'stock', width: '5%', type: FormTypes.inputNumber, readonly:true },
|
||||
{ title: '单位', key: 'unit', width: '4%', type: FormTypes.normal },
|
||||
{ title: '序列号', key: 'snList', width: '12%', type: FormTypes.popupJsh, kind: 'sn', multi: true },
|
||||
{ title: '批号', key: 'batchNumber', width: '7%', type: FormTypes.popupJsh, kind: 'batch', multi: false },
|
||||
{ title: '有效期', key: 'expirationDate',width: '7%', type: FormTypes.normal },
|
||||
{ title: '多属性', key: 'sku', width: '5%', type: FormTypes.normal },
|
||||
{ title: '数量', key: 'operNumber', width: '5%', type: FormTypes.inputNumber, statistics: true,
|
||||
validateRules: [{ required: true, message: '${title}不能为空' }]
|
||||
},
|
||||
{ title: '单价', key: 'unitPrice', width: '5%', type: FormTypes.inputNumber},
|
||||
{ title: '金额', key: 'allPrice', width: '5%', type: FormTypes.inputNumber, statistics: true },
|
||||
{ title: '备注', key: 'remark', width: '7%', type: FormTypes.input }
|
||||
]
|
||||
},
|
||||
confirmLoading: false,
|
||||
validatorRules:{
|
||||
operTime:{
|
||||
rules: [
|
||||
{ required: true, message: '请输入单据日期!' }
|
||||
]
|
||||
},
|
||||
accountId:{
|
||||
rules: [
|
||||
{ required: true, message: '请选择结算账户!' }
|
||||
]
|
||||
}
|
||||
},
|
||||
url: {
|
||||
add: '/depotHead/addDepotHeadAndDetail',
|
||||
edit: '/depotHead/updateDepotHeadAndDetail',
|
||||
detailList: '/depotItem/getDetailList'
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.initPayTypeList()
|
||||
},
|
||||
methods: {
|
||||
//调用完edit()方法之后会自动调用此方法
|
||||
editAfter() {
|
||||
this.changeColumnHide()
|
||||
this.changeFormTypes(this.materialTable.columns, 'snList', 0)
|
||||
this.changeFormTypes(this.materialTable.columns, 'batchNumber', 0)
|
||||
this.changeFormTypes(this.materialTable.columns, 'expirationDate', 0)
|
||||
if (this.action === 'add') {
|
||||
this.addInit(this.prefixNo)
|
||||
this.fileList = []
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({'payType': '现付', 'getAmount':0, 'backAmount':0})
|
||||
})
|
||||
} else {
|
||||
this.model.operTime = this.model.operTimeStr
|
||||
if(this.model.backAmount) {
|
||||
this.model.getAmount = (this.model.changeAmount + this.model.backAmount).toFixed(2)
|
||||
} else {
|
||||
this.model.getAmount = this.model.changeAmount
|
||||
}
|
||||
this.fileList = this.model.fileName
|
||||
if(this.model.payType === '预付款'){
|
||||
this.payTypeList = []
|
||||
this.payTypeList.push({"value":"预付款", "text":"预付款"})
|
||||
this.payTypeList.push({"value":"现付", "text":"现付"})
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue(pick(this.model,'organId', 'operTime', 'number', 'payType', 'remark',
|
||||
'discount','discountMoney','discountLastMoney','otherMoney','accountId','changeAmount','getAmount','backAmount'))
|
||||
});
|
||||
// 加载子表数据
|
||||
let params = {
|
||||
headerId: this.model.id,
|
||||
mpList: getMpListShort(Vue.ls.get('materialPropertyList')) //扩展属性
|
||||
}
|
||||
let url = this.readOnly ? this.url.detailList : this.url.detailList;
|
||||
this.requestSubTableData(url, params, this.materialTable);
|
||||
}
|
||||
//复制新增单据-初始化单号和日期
|
||||
if(this.action === 'copyAdd') {
|
||||
this.model.id = ''
|
||||
this.model.tenantId = ''
|
||||
this.copyAddInit(this.prefixNo)
|
||||
}
|
||||
this.initRetail()
|
||||
this.initDepot()
|
||||
this.initAccount()
|
||||
},
|
||||
//提交单据时整理成formData
|
||||
classifyIntoFormData(allValues) {
|
||||
let totalPrice = 0
|
||||
let billMain = Object.assign(this.model, allValues.formValue)
|
||||
let detailArr = allValues.tablesValue[0].values
|
||||
billMain.type = '出库'
|
||||
billMain.subType = '零售'
|
||||
billMain.defaultNumber = billMain.number
|
||||
for(let item of detailArr){
|
||||
totalPrice += item.allPrice-0
|
||||
}
|
||||
billMain.totalPrice = totalPrice
|
||||
if(this.fileList && this.fileList.length > 0) {
|
||||
billMain.fileName = this.fileList
|
||||
}
|
||||
if(this.model.id){
|
||||
billMain.id = this.model.id
|
||||
}
|
||||
return {
|
||||
info: billMain,
|
||||
rows: detailArr,
|
||||
}
|
||||
},
|
||||
//加载收款类型
|
||||
initPayTypeList() {
|
||||
this.payTypeList.push({"value":"现付", "text":"现付"})
|
||||
},
|
||||
initAccount(){
|
||||
getAccount({}).then((res)=>{
|
||||
if(res && res.code === 200) {
|
||||
this.accountList = res.data.accountList
|
||||
}
|
||||
})
|
||||
},
|
||||
//选择会员的触发事件
|
||||
onChangeOrgan(value) {
|
||||
getAction("/supplier/info", {id: value}).then(res=>{
|
||||
if(res && res.code === 200){
|
||||
this.payTypeList = []
|
||||
let info = res.data.info
|
||||
if(info.advanceIn) {
|
||||
this.payTypeList.push({"value":"预付款", "text":"预付款(" + info.advanceIn + ")"})
|
||||
this.payTypeList.push({"value":"现付", "text":"现付"})
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({'payType': '预付款'})
|
||||
})
|
||||
} else {
|
||||
this.payTypeList.push({"value":"现付", "text":"现付"})
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
//改变实收金额、收款金额的值
|
||||
autoChangePrice(target) {
|
||||
let allLastMoney = target.statisticsColumns.allPrice
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({'changeAmount':allLastMoney,'getAmount':allLastMoney,'backAmount':0})
|
||||
});
|
||||
},
|
||||
//改变收款金额
|
||||
onKeyUpGetAmount(e) {
|
||||
const value = e.target.value
|
||||
let changeAmount = this.form.getFieldValue('changeAmount')-0
|
||||
let backAmount = (value - changeAmount).toFixed(2)-0
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({'backAmount':backAmount})
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.ant-input{
|
||||
font-size: 30px;
|
||||
font-weight:bolder;
|
||||
text-align:center;
|
||||
border-left-width:0px!important;
|
||||
border-top-width:0px!important;
|
||||
border-right-width:0px!important;
|
||||
}
|
||||
</style>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user