192 changed files with 43814 additions and 10497 deletions
			
			
		| @ -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,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,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> | ||||
| @ -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 | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -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> | ||||
Some files were not shown because too many files have changed in this diff Show More
					Loading…
					
					
				
		Reference in new issue