From e3aaa6c1612c5f01e975a204e81c2f3fdb114f81 Mon Sep 17 00:00:00 2001
From: zxf <1532322479@qq.com>
Date: Sun, 10 May 2026 16:44:15 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E5=87=BA=E5=85=A5=E5=BA=93=E5=AF=BC?=
=?UTF-8?q?=E5=85=A5=E5=AF=BC=E5=87=BA=E4=BF=AE=E6=94=B9=E3=80=81=E7=89=A9?=
=?UTF-8?q?=E8=B5=84=E7=9B=98=E7=82=B9=E6=98=BE=E7=A4=BA=E5=92=8C=E5=AF=BC?=
=?UTF-8?q?=E5=87=BA=E4=BF=AE=E6=94=B9=E3=80=81=E6=B7=BB=E5=8A=A0=E7=82=B9?=
=?UTF-8?q?=E8=B8=A9=E7=90=86=E7=94=B1=E6=98=BE=E7=A4=BA=E3=80=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
admin/package.json | 1 +
admin/src/api/ckbillcargo.js | 14 +-
admin/src/api/ckstockchange.js | 12 +
admin/src/api/pmdailymenu.js | 39 +
admin/src/api/pmdailymenudtllike.js | 8 +-
admin/src/api/pmproductclass.js | 12 +
admin/src/api/systemadmin.js | 8 +-
admin/src/directive/dialog/drag.js | 101 +-
.../components/StockChoose/index.vue | 4 +-
.../ckoutbound/components/StockOut/index.vue | 63 +-
admin/src/views/ck/ckoutbound/index.vue | 243 +++-
.../src/views/ck/ckstock/index-inventory.vue | 663 +++++++++
admin/src/views/ck/ckstock/index.vue | 120 +-
.../ckwarehouse/components/BillEdit/index.vue | 35 +-
.../ckwarehouse/components/BillList/index.vue | 51 +-
admin/src/views/ck/ckwarehouse/index.vue | 738 ++++++++--
admin/src/views/ck/instock/index.vue | 421 +++---
admin/src/views/ck/outstock/index.vue | 705 ++++++++++
.../views/cm/cust/cmcust-add-and-update.vue | 6 +-
.../product/cmcustproduct-add-and-update.vue | 18 +-
.../src/views/cm/cust/product/index-cust.vue | 4 +-
admin/src/views/cm/cust/product/index.vue | 4 +-
.../qualify/cmcustqualify-add-and-update.vue | 4 +-
.../cmstoragelocation-add-and-update.vue | 4 +-
.../warehouse/cmwarehouse-add-and-update.vue | 3 +-
.../charge/fmbillcharge-add-and-update.vue | 4 +-
admin/src/views/fm/bill/charge/index.vue | 4 +-
.../fm/cash/writeoff/components/Charge.vue | 2 +-
.../views/pm/canteen/demand/DispatchList.vue | 4 +-
.../demand/pmcanteendemand-add-and-update.vue | 5 +-
...pmcanteenpurchasedetail-add-and-update.vue | 4 +-
.../purchase/order/OrderDetailList.vue | 4 +-
.../pmcanteenpurchaseorder-add-and-update.vue | 8 +-
.../pm/canteen/purchase/plan/DispatchList.vue | 4 +-
.../views/pm/canteen/purchase/plan/index.vue | 2 +-
.../pmcanteenpurchaseplan-add-and-update.vue | 8 +-
.../views/pm/daily/menu/dtl/index-like.vue | 126 +-
.../dtl/pmdailymenudtl-add-and-update.vue | 4 +-
admin/src/views/pm/daily/menu/index.vue | 141 +-
.../pm/houser/pmhouse-add-and-update.vue | 4 +-
.../pmmaintenancedispatch-add-and-update.vue | 2 +-
.../src/views/pm/maintenance/order/index.vue | 26 +-
.../pmmaintenanceorder-add-and-update.vue | 4 +-
.../class/pmproductclass-add-and-update.vue | 3 +-
app/pages/supply_chain/dispatch/index.vue | 2 +-
.../controller/AdminLoginController.java | 6 +
.../controller/SystemAdminController.java | 1 -
.../zbkj/admin/service/AdminLoginService.java | 5 +
.../service/impl/AdminLoginServiceImpl.java | 85 +-
.../common/request/QuickOutBillRequest.java | 12 +
.../common/response/InventoryResponse.java | 117 ++
.../controller/CkBillCargoController.java | 1044 +++++++++++++-
.../controller/CkBillController.java | 1232 ++++++++++++++++-
.../controller/CkCargoStockController.java | 73 +-
.../controller/CkStockChangeController.java | 29 +
.../controller/CmCustController.java | 2 +
.../controller/CmCustProductController.java | 2 +-
.../controller/PmDailyMenuController.java | 718 +++++++++-
.../PmDailyMenuDtlLikeController.java | 28 +-
.../PmMaintenanceDispatchController.java | 3 +
.../PmMaintenanceOrderController.java | 101 +-
.../autogencode/entity/CkBillCargo.java | 33 +
.../autogencode/entity/CkCargoStock.java | 29 +
.../autogencode/entity/CkStockChange.java | 13 +
.../entity/PmDailyMenuDtlLike.java | 13 +
.../autogencode/entity/vo/ImportItemVO.java | 23 +
.../service/CkStockChangeService.java | 15 +
.../service/PmDailyMenuService.java | 9 +
.../service/SysDictDataService.java | 7 +
.../service/impl/CkBillServiceImpl.java | 212 ++-
.../impl/CkStockChangeServiceImpl.java | 620 ++++++++-
.../service/impl/PmDailyMenuServiceImpl.java | 16 +
.../service/impl/SysDictDataServiceImpl.java | 6 +
.../common/constants/NotifyConstants.java | 5 +
.../zbkj/common/model/wechat/WechatFans.java | 82 ++
.../zbkj/common/request/PageParamRequest.java | 10 +
.../request/RegisterThirdUserRequest.java | 3 +
.../request/SubscribeMessageRequest.java | 61 +
.../response/SubscribeMessageResponse.java | 26 +
.../common/token/FrontTokenComponent.java | 4 +-
.../com/zbkj/front/CrmebFrontApplication.java | 2 +
.../front/controller/WeChatController.java | 51 +-
.../service/impl/UserCenterServiceImpl.java | 1 +
.../com/zbkj/service/dao/SystemMenuDao.java | 2 +
.../com/zbkj/service/dao/WechatFansDao.java | 21 +
.../service/service/SystemMenuService.java | 7 +
.../service/service/WechatFansService.java | 60 +
.../service/impl/SystemAdminServiceImpl.java | 2 +
.../service/impl/SystemMenuServiceImpl.java | 10 +
.../service/service/impl/UserServiceImpl.java | 1 +
.../service/impl/WechatFansServiceImpl.java | 270 ++++
.../com/zbkj/service/util/WeiXinUtil.java | 8 +-
.../mapper/system/SystemMenuMapper.xml | 11 +
93 files changed, 8039 insertions(+), 694 deletions(-)
create mode 100644 admin/src/views/ck/ckstock/index-inventory.vue
create mode 100644 admin/src/views/ck/outstock/index.vue
create mode 100644 crmeb/crmeb-admin/src/main/java/com/zbkj/common/response/InventoryResponse.java
create mode 100644 crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/entity/vo/ImportItemVO.java
create mode 100644 crmeb/crmeb-common/src/main/java/com/zbkj/common/model/wechat/WechatFans.java
create mode 100644 crmeb/crmeb-common/src/main/java/com/zbkj/common/request/SubscribeMessageRequest.java
create mode 100644 crmeb/crmeb-common/src/main/java/com/zbkj/common/response/SubscribeMessageResponse.java
create mode 100644 crmeb/crmeb-service/src/main/java/com/zbkj/service/dao/WechatFansDao.java
create mode 100644 crmeb/crmeb-service/src/main/java/com/zbkj/service/service/WechatFansService.java
create mode 100644 crmeb/crmeb-service/src/main/java/com/zbkj/service/service/impl/WechatFansServiceImpl.java
diff --git a/admin/package.json b/admin/package.json
index 1842ea9..c6736a3 100644
--- a/admin/package.json
+++ b/admin/package.json
@@ -38,6 +38,7 @@
},
"dependencies": {
"@babel/parser": "^7.9.6",
+ "@element-plus/icons-vue": "^2.3.2",
"@riophae/vue-treeselect": "0.4.0",
"async-validator": "^1.11.2",
"axios": "^0.24.0",
diff --git a/admin/src/api/ckbillcargo.js b/admin/src/api/ckbillcargo.js
index ccf833f..b994593 100644
--- a/admin/src/api/ckbillcargo.js
+++ b/admin/src/api/ckbillcargo.js
@@ -42,9 +42,8 @@ export function ckbillcargoDetailApi(id) {
*/
export function ckbillcargoDeleteApi(ids) {
return request({
- url: `autogencode/ckbillcargo/delete`,
- method: 'POST',
- data: ids
+ url: `autogencode/ckbillcargo/` + ids.join(','),
+ method: 'DELETE'
})
}
@@ -99,6 +98,15 @@ export function selectTotalWt(query) {
})
}
+// 查询出库合计(数量和金额)
+export function selectTotal(query) {
+ return request({
+ url: 'autogencode/ckbillcargo/selectTotal',
+ method: 'get',
+ params: query
+ })
+}
+
export function recallOutBill(id) {
return request({
url: 'autogencode/ckbillcargo/recallOutBill/' + id,
diff --git a/admin/src/api/ckstockchange.js b/admin/src/api/ckstockchange.js
index 08a808b..15adabb 100644
--- a/admin/src/api/ckstockchange.js
+++ b/admin/src/api/ckstockchange.js
@@ -61,3 +61,15 @@ export function ckstockchangeListApi(params) {
})
}
+/**
+ * 物资盘点表查询
+ * @param data 查询条件
+ */
+export function inventoryListApi(data) {
+ return request({
+ url: `autogencode/ckstockchange/inventory`,
+ method: 'POST',
+ data
+ })
+}
+
diff --git a/admin/src/api/pmdailymenu.js b/admin/src/api/pmdailymenu.js
index 21d9b3f..852cac4 100644
--- a/admin/src/api/pmdailymenu.js
+++ b/admin/src/api/pmdailymenu.js
@@ -144,3 +144,42 @@ export function pmdailymenuListByAll(params) {
})
}
+/**
+ * pmdailymenu导出
+ * @param params
+ */
+export function pmdailymenuExportApi(params) {
+ return request({
+ url: `autogencode/pmdailymenu/export`,
+ method: 'GET',
+ params,
+ responseType: 'blob'
+ })
+}
+
+/**
+ * pmdailymenu导入
+ * @param formData
+ */
+export function pmdailymenuImportApi(formData) {
+ return request({
+ url: `autogencode/pmdailymenu/import`,
+ method: 'POST',
+ data: formData,
+ headers: {
+ 'Content-Type': 'multipart/form-data'
+ }
+ })
+}
+
+/**
+ * pmdailymenu导入模板下载
+ */
+export function pmdailymenuImportTemplateApi() {
+ return request({
+ url: `autogencode/pmdailymenu/import/template`,
+ method: 'GET',
+ responseType: 'blob'
+ })
+}
+
diff --git a/admin/src/api/pmdailymenudtllike.js b/admin/src/api/pmdailymenudtllike.js
index b573d04..5bc8bdf 100644
--- a/admin/src/api/pmdailymenudtllike.js
+++ b/admin/src/api/pmdailymenudtllike.js
@@ -65,14 +65,18 @@ export function pmdailymenudtllikeListApi(params) {
* 对菜单明细进行点赞/点踩
* @param menuDtlId 菜单明细ID
* @param likeType 评价类型:1-点赞,2-点踩
+ * @param remark 备注(可选)
+ * @param uid 手机端用户ID(可选)
*/
-export function pmdailymenudtllikeLikeApi(menuDtlId, likeType) {
+export function pmdailymenudtllikeLikeApi(menuDtlId, likeType, remark, uid) {
return request({
url: `autogencode/pmdailymenudtllike/like`,
method: 'POST',
params: {
menuDtlId,
- likeType
+ likeType,
+ remark,
+ uid
}
})
}
diff --git a/admin/src/api/pmproductclass.js b/admin/src/api/pmproductclass.js
index 7852f22..5544b5e 100644
--- a/admin/src/api/pmproductclass.js
+++ b/admin/src/api/pmproductclass.js
@@ -73,3 +73,15 @@ export function pmproductclassTreeSelect(params) {
})
}
+/**
+ * 获取商品类别列表
+ * @param params
+ */
+export function listProductClass(params) {
+ return request({
+ url: `autogencode/pmproductclass/list`,
+ method: 'GET',
+ params
+ })
+}
+
diff --git a/admin/src/api/systemadmin.js b/admin/src/api/systemadmin.js
index c4023fe..b569bdd 100644
--- a/admin/src/api/systemadmin.js
+++ b/admin/src/api/systemadmin.js
@@ -63,7 +63,8 @@ export function adminAdd(pram) {
status: pram.status,
phone: pram.phone,
depts: pram.depts,
- posts: pram.posts
+ posts: pram.posts,
+ isDefaultReceiver: pram.isDefaultReceiver
}
return request({
url: '/admin/system/admin/save',
@@ -84,7 +85,8 @@ export function adminUpdate(pram) {
isDel: pram.isDel,
phone: pram.phone,
depts: pram.depts,
- posts: pram.posts
+ posts: pram.posts,
+ isDefaultReceiver: pram.isDefaultReceiver
}
return request({
url: '/admin/system/admin/update',
@@ -204,4 +206,4 @@ export function updateIsSmsApi(params) {
method: 'get',
params
})
-}
\ No newline at end of file
+}
diff --git a/admin/src/directive/dialog/drag.js b/admin/src/directive/dialog/drag.js
index 2e82346..16fe59d 100644
--- a/admin/src/directive/dialog/drag.js
+++ b/admin/src/directive/dialog/drag.js
@@ -1,64 +1,57 @@
/**
-* v-dialogDrag 弹窗拖拽
-* Copyright (c) 2019 ruoyi
-*/
-
+ * v-dialogDrag 弹窗拖拽(终极稳定版)
+ * 解决:初始居中 + 按下闪烁、偏移错误、飞到右下角
+ */
export default {
- bind(el, binding, vnode, oldVnode) {
+ bind(el, binding) {
const value = binding.value
- if (value == false) return
- // 获取拖拽内容头部
- const dialogHeaderEl = el.querySelector('.el-dialog__header');
- const dragDom = el.querySelector('.el-dialog');
- dialogHeaderEl.style.cursor = 'move';
- // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
- const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null);
- dragDom.style.position = 'absolute';
- dragDom.style.marginTop = 0;
- let width = dragDom.style.width;
- if (width.includes('%')) {
- width = +document.body.clientWidth * (+width.replace(/\%/g, '') / 100);
- } else {
- width = +width.replace(/\px/g, '');
- }
- dragDom.style.left = `${(document.body.clientWidth - width) / 2}px`;
- // 鼠标按下事件
- dialogHeaderEl.onmousedown = (e) => {
- // 鼠标按下,计算当前元素距离可视区的距离 (鼠标点击位置距离可视窗口的距离)
- const disX = e.clientX - dialogHeaderEl.offsetLeft;
- const disY = e.clientY - dialogHeaderEl.offsetTop;
+ if (value === false) return
- // 获取到的值带px 正则匹配替换
- let styL, styT;
+ const dialogHeaderEl = el.querySelector('.el-dialog__header')
+ const dragDom = el.querySelector('.el-dialog')
- // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
- if (sty.left.includes('%')) {
- styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100);
- styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100);
- } else {
- styL = +sty.left.replace(/\px/g, '');
- styT = +sty.top.replace(/\px/g, '');
- };
+ if (!dialogHeaderEl || !dragDom) return
- // 鼠标拖拽事件
- document.onmousemove = function (e) {
- // 通过事件委托,计算移动的距离 (开始拖拽至结束拖拽的距离)
- const l = e.clientX - disX;
- const t = e.clientY - disY;
+ dialogHeaderEl.style.cursor = 'move'
- let finallyL = l + styL
- let finallyT = t + styT
+ // 初始化:绝对居中
+ dragDom.style.position = 'fixed'
+ dragDom.style.margin = '0'
+ dragDom.style.left = '50%'
+ dragDom.style.top = '50%'
+ dragDom.style.transform = 'translate(-50%, -50%)'
- // 移动当前元素
- dragDom.style.left = `${finallyL}px`;
- dragDom.style.top = `${finallyT}px`;
-
- };
-
- document.onmouseup = function (e) {
- document.onmousemove = null;
- document.onmouseup = null;
- };
+ // 鼠标按下
+ dialogHeaderEl.onmousedown = (e) => {
+ e.preventDefault()
+
+ // 先拿到当前弹窗真实的 left / top(去掉 translate 影响)
+ const currLeft = dragDom.getBoundingClientRect().left
+ const currTop = dragDom.getBoundingClientRect().top
+
+ // 按下瞬间立刻清除居中,重新设置真实 left top
+ dragDom.style.transform = 'none'
+ dragDom.style.left = currLeft + 'px'
+ dragDom.style.top = currTop + 'px'
+
+ // 计算正确偏移(这是唯一不飞的算法)
+ const disX = e.clientX - currLeft
+ const disY = e.clientY - currTop
+
+ // 移动
+ document.onmousemove = (e) => {
+ let left = e.clientX - disX
+ let top = e.clientY - disY
+
+ dragDom.style.left = left + 'px'
+ dragDom.style.top = top + 'px'
+ }
+
+ // 抬起
+ document.onmouseup = () => {
+ document.onmousemove = null
+ document.onmouseup = null
+ }
}
}
-};
\ No newline at end of file
+}
diff --git a/admin/src/views/ck/ckoutbound/components/StockChoose/index.vue b/admin/src/views/ck/ckoutbound/components/StockChoose/index.vue
index c900d8a..ff54302 100644
--- a/admin/src/views/ck/ckoutbound/components/StockChoose/index.vue
+++ b/admin/src/views/ck/ckoutbound/components/StockChoose/index.vue
@@ -170,11 +170,11 @@ export default {
},
getList() {
this.list = [];
- if (!this.custId) return;
this.loading = true;
listCkstock({
- custId: this.custId,
+ custId: this.custId || '',
gdsSeqno: this.searchGdsSeqno,
+ isShow: false, // 不显示库存为0的商品
}).then(res => {
this.loading = false;
this.list = res || [];
diff --git a/admin/src/views/ck/ckoutbound/components/StockOut/index.vue b/admin/src/views/ck/ckoutbound/components/StockOut/index.vue
index a3712a3..2446fb7 100644
--- a/admin/src/views/ck/ckoutbound/components/StockOut/index.vue
+++ b/admin/src/views/ck/ckoutbound/components/StockOut/index.vue
@@ -206,17 +206,31 @@
+
+
+ {{ scope.row.unitPrice || 0 }}
+
+
+
{{ scope.row.cargoWt }}
+ :precision="2" :max="getMaxData(scope.row).cargoWt" placeholder="输入数量" @change="onCargoWtChange(scope.row)" />
+
+
+ {{ scope.row && getCargoValue(scope.row) }}
+
+
+
+
@@ -323,9 +337,7 @@ export default {
billNumber: [
{ required: true, message: '单据编号不能为空', trigger: 'blur' }
],
- custId: [
- { required: true, message: '供应商不能为空', trigger: 'blur' }
- ],
+ custId: [],
cargoName: [
{ required: true, message: '商品名称不能为空', trigger: 'blur' }
],
@@ -407,11 +419,34 @@ export default {
// this.getVesselList();
},
methods: {
- // getCargoValue(row){
- // const value = row.unitPrice * row.cargoWt;
- // row.cargoValue = isNaN(value) ? 0 : value.toFixed(4);
- // return row.cargoValue;
- // },
+ getCargoValue(row){
+ if (!row) return 0;
+ const value = (row.unitPrice || 0) * (row.cargoWt || 0);
+ row.cargoValue = isNaN(value) ? 0 : value.toFixed(4);
+ return row.cargoValue;
+ },
+ // 领用数量变化时更新金额
+ onCargoWtChange(row) {
+ if (row) {
+ const value = (row.unitPrice || 0) * (row.cargoWt || 0);
+ row.cargoValue = isNaN(value) ? 0 : value.toFixed(4);
+ }
+ },
+ // 获取最大金额(库存数量 × 单价)
+ getMaxCargoValue(row) {
+ if (!row) return Infinity;
+ const maxWt = this.getMaxData(row).cargoWt;
+ const value = (row.unitPrice || 0) * maxWt;
+ return isNaN(value) ? Infinity : value;
+ },
+ // 金额输入处理,限制不超过最大值
+ onCargoValueInput(row, event) {
+ const value = parseFloat(event);
+ const maxValue = this.getMaxCargoValue(row);
+ if (!isNaN(value) && value > maxValue) {
+ row.cargoValue = maxValue.toFixed(4);
+ }
+ },
init() {
this.getCustList();
this.getMenuList();
@@ -838,10 +873,6 @@ export default {
});
},
addStockOut() {
- if (!this.form.custId) {
- this.$message('请先选择供应商');
- return;
- }
this.open = true;
},
// 获取领用明细列表
@@ -908,11 +939,9 @@ export default {
},
// 获取仓库库存列表
getStockList() {
- if (!this.form.custId) {
- return;
- }
listCkstock({
- custId: this.form.custId,
+ custId: this.form.custId || '',
+ isShow: false, // 不显示库存为0的商品
}).then(res => {
this.stockList = res || [];
}).catch(e => {
diff --git a/admin/src/views/ck/ckoutbound/index.vue b/admin/src/views/ck/ckoutbound/index.vue
index 78a1403..b49f614 100644
--- a/admin/src/views/ck/ckoutbound/index.vue
+++ b/admin/src/views/ck/ckoutbound/index.vue
@@ -3,13 +3,40 @@
+
+ 导入
+
+
+
+ 导出
+
+
-
- 单据列表
-
+
+
+ ›
+ ‹
+
+
+ 单据列表
+
@@ -120,6 +147,8 @@
+
+
@@ -128,7 +157,7 @@
-
+
查看
@@ -136,6 +165,9 @@
修改
+ 删除
+
@@ -148,6 +180,38 @@
+
+
+
+
+
+ 将文件拖到此处,或点击上传
+
+
+
+ 是否更新已经存在的数据
+
+
仅允许导入xls、xlsx格式文件。
+
下载模板
+
+
+
+
@@ -172,6 +236,7 @@ import { ckbillDeleteApi as delCkbill, auditBill, cancelAuditBill, rejectBill} f
import SearchBlock from '@/components/SearchBlock';
// import { listVessel } from "@/api/jxc/vessel";
import { pmdailymenuListByAll } from "@/api/pmdailymenu.js";
+import request from '@/utils/request';
export default {
name: 'Ckoutbound',
@@ -341,6 +406,25 @@ export default {
readonly: false,
// 表单参数
form: {},
+ // 导入参数
+ upload: {
+ // 是否显示弹出层
+ open: false,
+ // 弹出层标题
+ title: "出库信息导入",
+ // 是否禁用上传
+ isUploading: false,
+ // 是否更新已存在数据
+ updateSupport: 0,
+ // 请求头
+ headers: {
+ Authorization: ""
+ },
+ // 上传的文件列表
+ fileList: []
+ },
+ // 左侧列是否折叠
+ isCollapse: false,
}
},
created() {
@@ -358,20 +442,37 @@ export default {
// });
// },
// 点击单据
- billClick(row) {
- const isChange = this.selectedBill.id !== row.id;
- this.selectedBill = row || {};
- this.queryParams.billNumber = this.selectedBill.billNumber;
- // 切换的时候重新搜索,否则刷新当前
- if (isChange) {
+ billClick(row, isAutoRestore = false) {
+ if (row && Object.keys(row).length > 0) {
+ if (isAutoRestore) {
+ // 如果是自动恢复选中状态,直接更新selectedBill和查询参数
+ this.selectedBill = row || {};
+ this.queryParams.pageNum = 1;
+ this.queryParams.billNumber = this.selectedBill.billNumber;
+ // 触发右侧的查询
+ this.getList();
+ } else {
+ const isChange = this.selectedBill.id !== row.id;
+ this.selectedBill = row || {};
+ this.queryParams.billNumber = this.selectedBill.billNumber;
+ // 切换的时候重新搜索,否则刷新当前
+ if (isChange) {
+ this.queryParams.pageNum = 1;
+ }
+ if (this.queryParams.billNumber) {
+ this.getList();
+ } else {
+ this.ckcargoList = [];
+ }
+ }
+ } else if (!row || Object.keys(row).length === 0) {
+ // 清空选中状态
+ this.selectedBill = {};
this.queryParams.pageNum = 1;
- }
- if (this.queryParams.billNumber) {
+ this.queryParams.billNumber = null;
+ // 触发右侧的查询
this.getList();
- } else {
- this.ckcargoList = [];
}
-
},
handleClose(show) {
if (!show) {
@@ -455,6 +556,9 @@ export default {
this.handleQuery()
},
backBill() {
+ // 保存当前选中的单据ID和单据编号
+ const selectedBillId = this.selectedBill.id;
+ const billNumber = this.selectedBill.billNumber;
this.$confirm(`确定撤销当前单据吗?`, '温馨提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
@@ -467,14 +571,27 @@ export default {
message: '撤销成功!',
type: 'success'
});
+ // 更新selectedBill的状态,使按钮状态立即变化
+ this.selectedBill.billStatus = '0';
this.loading = false;
+ // 刷新列表并保持选中状态
this.refreshList();
+ // 刷新右侧商品列表
+ this.$nextTick(() => {
+ if (billNumber) {
+ this.queryParams.billNumber = billNumber;
+ this.getList();
+ }
+ });
}).catch(e => {
this.loading = false;
});
});
},
confirm() {
+ // 保存当前选中的单据ID和单据编号
+ const selectedBillId = this.selectedBill.id;
+ const billNumber = this.selectedBill.billNumber;
// 检查是否自动出库
if (this.selectedBill.autoOut === '1') {
this.$confirm(`当前单据设置为自动出库,确认后将会自动生成出库单据。\n确定提交当前单据吗?`, '温馨提示', {
@@ -489,8 +606,18 @@ export default {
message: '提交成功!',
type: 'success'
});
+ // 更新selectedBill的状态,使按钮状态立即变化
+ this.selectedBill.billStatus = '1';
this.loading = false;
+ // 刷新列表并保持选中状态
this.refreshList();
+ // 刷新右侧商品列表
+ this.$nextTick(() => {
+ if (billNumber) {
+ this.queryParams.billNumber = billNumber;
+ this.getList();
+ }
+ });
}).catch(e => {
this.loading = false;
});
@@ -508,8 +635,18 @@ export default {
message: '提交成功!',
type: 'success'
});
+ // 更新selectedBill的状态,使按钮状态立即变化
+ this.selectedBill.billStatus = '1';
this.loading = false;
+ // 刷新列表并保持选中状态
this.refreshList();
+ // 刷新右侧商品列表
+ this.$nextTick(() => {
+ if (billNumber) {
+ this.queryParams.billNumber = billNumber;
+ this.getList();
+ }
+ });
}).catch(e => {
this.loading = false;
});
@@ -616,7 +753,13 @@ export default {
this.$modal.confirm('是否确认删除"' + this.selectedBill.billNumber+ '"的领用单据?').then(() => {
return delCkbill(ids);
}).then(() => {
+ // 清空选中状态和查询参数
+ this.selectedBill = {};
+ this.queryParams.billNumber = null;
+ // 刷新左侧单据列表
this.refreshList();
+ // 刷新右侧商品列表
+ this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
}
@@ -700,6 +843,76 @@ export default {
this.download('jxc/ckcargo/export', {
...this.queryParams
}, `仓库领用管理_${new Date().getTime()}.xlsx`)
+ },
+ /** 导入按钮操作 */
+ handleImport() {
+ this.upload.title = "出库信息导入";
+ this.upload.open = true;
+ },
+ /** 下载模板操作 */
+ importTemplate() {
+ // 调用后端API下载出库模板
+ request({
+ url: '/autogencode/ckbill/downloadOutTemplate',
+ method: 'get',
+ responseType: 'blob'
+ }).then(blob => {
+ // 直接使用blob数据
+ const url = window.URL.createObjectURL(blob);
+ const link = document.createElement('a');
+ link.href = url;
+ link.setAttribute('download', `出库导入模板_${new Date().getTime()}.xlsx`);
+ document.body.appendChild(link);
+ link.click();
+ // 清理
+ document.body.removeChild(link);
+ window.URL.revokeObjectURL(url);
+ }).catch(error => {
+ console.error('下载模板失败:', error);
+ this.$modal.msgError('下载模板失败,请重试');
+ });
+ },
+ // 文件上传中处理
+ handleFileUploadProgress(event, file, fileList) {
+ this.upload.isUploading = true;
+ },
+ // 文件上传成功处理
+ handleFileSuccess(response, file, fileList) {
+ this.upload.open = false;
+ this.upload.isUploading = false;
+ this.$refs.upload.clearFiles();
+ this.$alert("
{
+ this.$modal.msgSuccess('导入成功');
+ this.upload.open = false;
+ this.upload.fileList = [];
+ // 导入成功后刷新列表
+ this.refreshList();
+ }).catch(error => {
+ this.$modal.msgError('导入失败:' + (error.response?.data?.message || '未知错误'));
+ }).finally(() => {
+ this.upload.isUploading = false;
+ });
}
}
}
diff --git a/admin/src/views/ck/ckstock/index-inventory.vue b/admin/src/views/ck/ckstock/index-inventory.vue
new file mode 100644
index 0000000..81e9e85
--- /dev/null
+++ b/admin/src/views/ck/ckstock/index-inventory.vue
@@ -0,0 +1,663 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+ {{ $index + 1 }}
+
+
+
+
+ {{ row.cargoName }}
+ {{ row.cargoSpec }}
+
+
+
+
+
+ {{ row.unit || '-' }}
+
+
+
+
+ {{ row.lastCargoNum }}
+
+
+
+
+
+
+
+ {{ row.unit || '-' }}
+
+
+
+
+ {{ row.inCargoNum }}
+
+
+
+
+
+
+
+ {{ row.unit || '-' }}
+
+
+
+
+ {{ row.outCargoNum }}
+
+
+
+
+
+
+
+ {{ row.unit || '-' }}
+
+
+
+
+ {{ row.cargoNum }}
+
+
+
+
+
+
+
+
+
+
+
返 回
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.stockDate, '{y}-{m}-{d} {h}:{i}:{s}') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.expiryDate, '{y}-{m}-{d} {h}:{i}:{s}') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/admin/src/views/ck/ckstock/index.vue b/admin/src/views/ck/ckstock/index.vue
index 4bc06cf..673c64b 100644
--- a/admin/src/views/ck/ckstock/index.vue
+++ b/admin/src/views/ck/ckstock/index.vue
@@ -55,29 +55,37 @@
-
-
+
+
+
-
-
-
+
+
+
+
+
+
+
{{ parseTime(row.stockDate, '{y}-{m}-{d}') }}
-
-
- 库存明细
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
this.warehouses,
+ optionsProp: 'id',
+ optionsLabel: 'stockName',
+ },
+ {
+ label: '商品类别',
+ prop: 'classId',
+ type: 'select',
+ getOptions: () => this.productClassList,
+ optionsProp: 'id',
+ optionsLabel: 'className',
+ },
{
label: '商品名称',
prop: 'cargoName',
@@ -209,6 +232,8 @@ export default {
// 仓库名称数据
warehouses: [],
+ // 商品类别数据
+ productClassList: [],
// 遮罩层
loading: true,
// 选中数组
@@ -329,16 +354,13 @@ export default {
},
created() {
this.getList();
- this.getStockList();
- this.getCustList();
- this.getCargoList();
- this.getVesselList();
- this.getBmvoyage();
this.getNewListCkstock();
listWarehouse({}).then(response => {
- this.warehouses = response.data;
+ this.warehouses = response;
});
+ this.getProductClassList();
+
},
methods: {
getNewListCkstock() {
@@ -365,34 +387,6 @@ export default {
// }
// })
// },
- getBmvoyage() {
- let param = {};
- listBmvoyage(param).then(response => {
- this.bmvoyageList = response.data;
- }).catch(e => {
- });
- },
-
- //船舶
- setVesselDetail(vesselId) {
- console.log(vesselId);
- this.vesselList.forEach(ele => {
- if (ele.id == vesselId) {
- console.log("aa:", ele.vesselName);
- this.form.vesselName = ele.vesselName;
-
- }
- })
- },
-
- getVesselList() {
- let param = {};
- listVessel(param).then(response => {
- this.vesselList = response.data;
- }).catch(e => {
- });
- },
-
//商品
setCargoDetail(cargoId) {
@@ -407,14 +401,6 @@ export default {
})
},
- getCargoList() {
- let param = {};
- listCargo(param).then(response => {
- this.cargoList = response.data;
- }).catch(e => {
- });
- },
-
//客户
setCustDetail(custId) {
this.custList.forEach(ele => {
@@ -443,11 +429,13 @@ export default {
})
},
- getStockList() {
- let param = {};
- listStock(param).then(response => {
- this.stockList = response.data;
+ getProductClassList() {
+ pmproductclassTreeSelect({}).then(response => {
+ // 只取最顶级的分类
+ this.productClassList = response || [];
}).catch(e => {
+ console.error('获取物品类别列表失败:', e);
+ this.productClassList = [];
});
},
diff --git a/admin/src/views/ck/ckwarehouse/components/BillEdit/index.vue b/admin/src/views/ck/ckwarehouse/components/BillEdit/index.vue
index 51af97e..0f8e038 100644
--- a/admin/src/views/ck/ckwarehouse/components/BillEdit/index.vue
+++ b/admin/src/views/ck/ckwarehouse/components/BillEdit/index.vue
@@ -86,7 +86,11 @@
- {{ scope.row.unitPrice }}
+ {{ scope.row.unitPrice }}
+
+
+
@@ -94,7 +98,16 @@
{{ scope.row.cargoWt }}
+ :min="0" controls-position="right" @change="updateCargoValue(scope.row)"/>
+
+
+
+
+
+ {{ scope.row.cargoValue }}
+
+
@@ -216,7 +229,7 @@
label="单位"
>
-
+
{
this.list = response.list || [];
@@ -129,18 +146,32 @@ export default {
this.loading = false;
if (this.list.length) {
- let currentItem = this.list[0];
- if (this.selectItem.id) {
+ if (currentSelectedId) {
// 如果当前有选中的则选中上次保存的单据
- const findIndex = this.list.findIndex(val => val.id === this.selectItem.id);
+ const findIndex = this.list.findIndex(val => val.id === currentSelectedId);
if (findIndex > -1) {
- currentItem = this.list[findIndex];
+ const currentItem = this.list[findIndex];
+ // 直接更新selectItem,不调用rowClick,避免触发父组件的billClick方法
+ this.selectItem = currentItem;
+ // 设置表格选中状态
+ this.$refs.table.setCurrentRow(currentItem);
+ // 通知父组件选中状态变化,但传递一个参数表示这是自动恢复选中状态
+ this.$emit('rowClick', currentItem, true);
+ return;
}
}
- this.rowClick(currentItem);
- this.$refs.table.setCurrentRow(currentItem);
- } else {
- this.rowClick({});
+
+ if (this.autoSelectFirst) {
+ // 只有在没有之前选中的单据时,才自动选择第一个
+ const currentItem = this.list[0];
+ this.selectItem = currentItem;
+ this.$refs.table.setCurrentRow(currentItem);
+ this.$emit('rowClick', currentItem, true);
+ }
+ } else if (!this.list.length) {
+ this.selectItem = {};
+ this.$refs.table.setCurrentRow(null);
+ this.$emit('rowClick', {}, true);
}
}).catch(e => {
this.loading = false;
diff --git a/admin/src/views/ck/ckwarehouse/index.vue b/admin/src/views/ck/ckwarehouse/index.vue
index bc2cdf8..e399081 100644
--- a/admin/src/views/ck/ckwarehouse/index.vue
+++ b/admin/src/views/ck/ckwarehouse/index.vue
@@ -2,7 +2,13 @@
-
+
+
+ 新增单据
+
+
导入
+ >导入
+
导出
+ >导出
+
-
- 单据列表
-
+
+
+ ›
+ ‹
+
+
+ 单据列表
+
+
+
+
+
+
+
+
+
- 新增单据
-
-
-
+
新增明细
+ v-if="(!isCollapse && (this.selectedBill.sourceType == '1' && this.selectedBill.billStatus == '0'))" plain
+ icon="el-icon-plus"
+ @click="handleAdd('out')" v-hasPermi="['jxc:ckcargo:add']">新增明细
+
-
+
删除单据
+ v-if="(!isCollapse && this.selectedBill.sourceType == '1' && this.selectedBill.billStatus == '0') || (isCollapse && this.modifyData.id)" plain
+ icon="el-icon-delete"
+ @click="handleDel" v-hasPermi="['jxc:ckcargo:remove']">{{ !isCollapse ? '删除单据' : '删除明细' }}
+
-
-
- 单据撤销
+
+ 单据撤销
+
-
-
- 单据确认
+
+ 单据确认
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+ {{ parseTime(scope.row.billDate, '{y}-{m}-{d}') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- {{ scope.row.sourceType == '0' ? '载货清单' : scope.row.sourceType == '2' ? '转场' : scope.row.sourceType == '3' ? '混配' : '直接入库' }}
+ {{ scope.row.autoOut == '1' ? '是' : '否' }}
+
+
+
+
+
+
+
+
+
{{ scope.row.billStatus == '1' ? '已确认' : '未确认' }}
-
-
-
-
+
+
+
-
-
-
-
+
查看
+ v-hasPermi="['jxc:ckcargo:edit']">查看
+
修改
+ v-if="scope.row.billStatus == '0' && scope.row.sourceType == '1'"
+ icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['jxc:ckcargo:edit']">修改
+
+ 删除
+
+ @pagination="getList"/>
+ :visible.sync="open" fullscreen append-to-body>
@@ -128,6 +190,7 @@
:limit="1"
accept=".xlsx, .xls"
:headers="upload.headers"
+ :action="''"
:disabled="upload.isUploading"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
@@ -139,10 +202,13 @@
将文件拖到此处,或点击上传
- 是否更新已经存在的数据
+
+ 是否更新已经存在的数据
仅允许导入xls、xlsx格式文件。
-
下载模板
+
下载模板
+
@@ -156,11 +192,26 @@
pageSize: 10,
totalPage: 0,
dataListLoading: false,
- dataListSelections: [],
+ dataListSelections: [],
addOrUpdateVisible: false,
menuDtlAddOrUpdateVisible: false,
refreshKey: 0,
- expandedRowKeys: [] // 存储展开的行的ID
+ expandedRowKeys: [], // 存储展开的行的ID
+ // 导入参数
+ upload: {
+ // 是否显示弹出层
+ open: false,
+ // 弹出层标题
+ title: "",
+ // 是否禁用上传
+ isUploading: false,
+ // 是否更新已经存在的数据
+ updateSupport: 0,
+ // 设置上传的请求头部
+ headers: {Authorization: "Bearer " + sessionStorage.getItem('token')},
+ // 上传的地址
+ url: process.env.VUE_APP_BASE_API + "/api/autogencode/pmdailymenu/import"
+ }
}
},
components: {
@@ -326,6 +377,92 @@
})
})
},
+ // 导出菜单
+ exportHandle () {
+ // 构建导出参数
+ const params = {}
+
+ // 将查询条件添加到参数中
+ if (this.dataForm.menuDate) params.menuDate = this.dataForm.menuDate;
+ if (this.dataForm.canteenName) params.canteenName = this.dataForm.canteenName;
+ if (this.dataForm.mealType) params.mealType = this.dataForm.mealType;
+ if (this.dataForm.status) params.status = this.dataForm.status;
+ if (this.dataForm.remark) params.remark = this.dataForm.remark;
+
+ // 调用导出API
+ api.pmdailymenuExportApi(params).then(res => {
+ // 创建下载链接
+ const url = window.URL.createObjectURL(new Blob([res]))
+ const link = document.createElement('a')
+ link.style.display = 'none'
+ link.href = url
+ link.setAttribute('download', `菜单导出_${new Date().getTime()}.xlsx`)
+ document.body.appendChild(link)
+ link.click()
+ document.body.removeChild(link)
+ this.$message.success('导出成功')
+ }).catch(e => {
+ this.$message.error('导出失败')
+ })
+ },
+ // 导入按钮操作
+ handleImport() {
+ this.upload.title = "菜单信息导入"
+ this.upload.open = true
+ },
+ // 下载模板操作
+ importTemplate() {
+ // 调用后端API下载模板
+ api.pmdailymenuImportTemplateApi().then(blob => {
+ // 直接使用blob数据
+ const url = window.URL.createObjectURL(blob)
+ const link = document.createElement('a')
+ link.href = url
+ link.setAttribute('download', `菜单导入模板_${new Date().getTime()}.xlsx`)
+ document.body.appendChild(link)
+ link.click()
+ // 清理
+ document.body.removeChild(link)
+ window.URL.revokeObjectURL(url)
+ }).catch(error => {
+ console.error('下载模板失败:', error)
+ this.$message.error('下载模板失败,请重试')
+ })
+ },
+ // 文件上传中处理
+ handleFileUploadProgress(event, file, fileList) {
+ this.upload.isUploading = true
+ },
+ // 文件上传成功处理
+ handleFileSuccess(response, file, fileList) {
+ this.upload.open = false
+ this.upload.isUploading = false
+ this.$refs.upload.clearFiles()
+ this.$alert("" + response.msg + "
", "导入结果", {dangerouslyUseHTMLString: true})
+ this.getDataList()
+ },
+ // 提交上传文件
+ submitFileForm() {
+ this.$refs.upload.submit()
+ },
+ // 自定义上传方法
+ uploadFile(file) {
+ const formData = new FormData()
+ formData.append('file', file.file)
+ formData.append('updateSupport', this.upload.updateSupport)
+
+ api.pmdailymenuImportApi(formData).then(response => {
+ this.$message.success('导入成功')
+ this.upload.open = false
+ this.upload.fileList = []
+ // 导入成功后刷新列表
+ this.getDataList()
+ }).catch(error => {
+ this.$message.error('导入失败:' + (error.response?.data?.message || '未知错误'))
+ }).finally(() => {
+ this.upload.isUploading = false
+ })
+ },
}
}
diff --git a/admin/src/views/pm/houser/pmhouse-add-and-update.vue b/admin/src/views/pm/houser/pmhouse-add-and-update.vue
index b3ff3cf..bfa4673 100644
--- a/admin/src/views/pm/houser/pmhouse-add-and-update.vue
+++ b/admin/src/views/pm/houser/pmhouse-add-and-update.vue
@@ -4,7 +4,9 @@
:title="!dataForm.id ? '添加' : '修改'"
:close-on-click-modal="false"
:append-to-body="true"
- :visible.sync="visible">
+ :visible.sync="visible"
+ v-dialogDrag
+ >
diff --git a/admin/src/views/pm/maintenance/dispatch/pmmaintenancedispatch-add-and-update.vue b/admin/src/views/pm/maintenance/dispatch/pmmaintenancedispatch-add-and-update.vue
index 52b2446..4904981 100644
--- a/admin/src/views/pm/maintenance/dispatch/pmmaintenancedispatch-add-and-update.vue
+++ b/admin/src/views/pm/maintenance/dispatch/pmmaintenancedispatch-add-and-update.vue
@@ -186,7 +186,7 @@ export default {
costAmount: '' ,
completePhoto: '' ,
ownerConfirm: '否' ,
- status: '0' ,
+ status: '1' ,
files: []
},
diff --git a/admin/src/views/pm/maintenance/order/index.vue b/admin/src/views/pm/maintenance/order/index.vue
index 8723038..ce4ce60 100644
--- a/admin/src/views/pm/maintenance/order/index.vue
+++ b/admin/src/views/pm/maintenance/order/index.vue
@@ -144,11 +144,12 @@
{{ '修改' }}
- {{ '办结' }}
+ {{ '提交' }}
+ {{ '办结' }}
{{ '重新处理' }}
删除
@@ -397,6 +398,27 @@ import DictTag from '@/components/DictTag'
}).catch(() => {
})
},
+ // 提交订单(从草稿到待处理)
+ submitOrder (id) {
+ this.$confirm('确定要提交订单吗?提交后状态将变为待处理', '提示', {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: 'warning'
+ }).then(() => {
+ // 调用更新状态的API
+ api.pmmaintenanceorderUpdateStatusAndRemarkApi({
+ id: id,
+ status: '0', // 0是待处理状态
+ remark: ''
+ }).then(res => {
+ this.$message.success('提交成功')
+ this.getDataList()
+ }).catch(() => {
+ this.$message.error('提交失败')
+ })
+ }).catch(() => {
+ })
+ },
}
}
diff --git a/admin/src/views/pm/maintenance/order/pmmaintenanceorder-add-and-update.vue b/admin/src/views/pm/maintenance/order/pmmaintenanceorder-add-and-update.vue
index 57d4bfc..12969f8 100644
--- a/admin/src/views/pm/maintenance/order/pmmaintenanceorder-add-and-update.vue
+++ b/admin/src/views/pm/maintenance/order/pmmaintenanceorder-add-and-update.vue
@@ -256,7 +256,7 @@ export default {
reportChannel: '',
reportTime: '',
urgencyLevel: '',
- status: '0',
+ status: '1',
remark: '',
files: [], // 故障照片文件
afterProcessFiles: [] // 修复凭证文件
@@ -632,7 +632,7 @@ export default {
}.bind(this))
} else {
// 新增时设置默认文件上传权限
- this.setFileUploadPermissions('0'); // 默认为待处理状态
+ this.setFileUploadPermissions('1'); // 默认为草稿状态
// 新增时清空故障照片和修复照片文件列表
this.faultPhotoFiles = []
this.afterProcessFiles = []
diff --git a/admin/src/views/pm/product/class/pmproductclass-add-and-update.vue b/admin/src/views/pm/product/class/pmproductclass-add-and-update.vue
index 4d9b7f2..7bf3c90 100644
--- a/admin/src/views/pm/product/class/pmproductclass-add-and-update.vue
+++ b/admin/src/views/pm/product/class/pmproductclass-add-and-update.vue
@@ -5,7 +5,8 @@
:close-on-click-modal="false"
:append-to-body="true"
:visible.sync="visible"
- width="600px">
+ width="600px"
+ v-dialogDrag>
diff --git a/app/pages/supply_chain/dispatch/index.vue b/app/pages/supply_chain/dispatch/index.vue
index e78183c..ba92c26 100644
--- a/app/pages/supply_chain/dispatch/index.vue
+++ b/app/pages/supply_chain/dispatch/index.vue
@@ -454,7 +454,7 @@ export default {
assigneContext: this.form.handleContent,
dispatchNote: this.form.dispatchNote,
expectedCompleteTime: this.form.expectedCompleteTime,
- status: '0',
+ status: '1',
assignTime: this.getCurrentTime(),
files: []
};
diff --git a/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/controller/AdminLoginController.java b/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/controller/AdminLoginController.java
index 110bc28..922fe2e 100644
--- a/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/controller/AdminLoginController.java
+++ b/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/controller/AdminLoginController.java
@@ -62,6 +62,12 @@ public class AdminLoginController {
public CommonResult getAdminInfo() {
return CommonResult.success(adminLoginService.getInfoByToken());
}
+
+ @ApiOperation(value="根据uid获取用户详情")
+ @GetMapping(value = "/getAdminInfoByUid")
+ public CommonResult getAdminInfoByUid(@RequestParam Long uid) {
+ return CommonResult.success(adminLoginService.getInfoByUid(uid));
+ }
/**
* 获取登录页图片
diff --git a/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/controller/SystemAdminController.java b/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/controller/SystemAdminController.java
index 81b2605..ed3eecd 100644
--- a/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/controller/SystemAdminController.java
+++ b/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/controller/SystemAdminController.java
@@ -46,7 +46,6 @@ public class SystemAdminController {
* @param systemAdminRequest 搜索条件
* @param pageParamRequest 分页参数
*/
- @PreAuthorize("hasAuthority('admin:system:admin:list')")
@ApiOperation(value = "分页列表")
@RequestMapping(value = "/list", method = RequestMethod.GET)
@ResponseBody
diff --git a/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/service/AdminLoginService.java b/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/service/AdminLoginService.java
index c01ce38..4db3135 100644
--- a/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/service/AdminLoginService.java
+++ b/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/service/AdminLoginService.java
@@ -48,4 +48,9 @@ public interface AdminLoginService {
* 根据Token获取对应用户信息
*/
SystemAdminResponse getInfoByToken();
+
+ /**
+ * 根据uid获取管理员信息
+ */
+ SystemAdminResponse getInfoByUid(Long uid);
}
diff --git a/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/service/impl/AdminLoginServiceImpl.java b/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/service/impl/AdminLoginServiceImpl.java
index 58ba227..6f49be9 100644
--- a/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/service/impl/AdminLoginServiceImpl.java
+++ b/crmeb/crmeb-admin/src/main/java/com/zbkj/admin/service/impl/AdminLoginServiceImpl.java
@@ -2,6 +2,7 @@ package com.zbkj.admin.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
import com.zbkj.admin.filter.TokenComponent;
import com.zbkj.admin.service.AdminLoginService;
import com.zbkj.admin.service.ValidateCodeService;
@@ -11,6 +12,8 @@ import com.zbkj.common.exception.CrmebException;
import com.zbkj.common.model.system.SystemAdmin;
import com.zbkj.common.model.system.SystemMenu;
import com.zbkj.common.model.system.SystemPermissions;
+import com.zbkj.common.model.system.SystemRole;
+import com.zbkj.common.model.user.User;
import com.zbkj.common.request.SystemAdminLoginRequest;
import com.zbkj.common.response.MenusResponse;
import com.zbkj.common.response.SystemAdminResponse;
@@ -19,10 +22,8 @@ import com.zbkj.common.response.SystemLoginResponse;
import com.zbkj.common.utils.SecurityUtil;
import com.zbkj.common.vo.LoginUserVo;
import com.zbkj.common.vo.MenuTree;
-import com.zbkj.service.service.SystemAdminService;
-import com.zbkj.service.service.SystemConfigService;
-import com.zbkj.service.service.SystemGroupDataService;
-import com.zbkj.service.service.SystemMenuService;
+import com.zbkj.service.dao.SystemMenuDao;
+import com.zbkj.service.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
@@ -33,6 +34,7 @@ import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -75,6 +77,16 @@ public class AdminLoginServiceImpl implements AdminLoginService {
@Autowired
private SystemMenuService systemMenuService;
+
+ @Autowired
+ private SystemMenuDao systemMenuDao;
+
+ @Autowired
+ private SystemRoleService systemRoleService;
+
+ @Autowired
+ private UserService userService;
+
/**
* PC登录
*/
@@ -184,4 +196,69 @@ public class AdminLoginServiceImpl implements AdminLoginService {
systemAdminResponse.setPermissionsList(permList);
return systemAdminResponse;
}
+
+ /**
+ * 根据uid获取管理员信息
+ */
+ @Override
+ public SystemAdminResponse getInfoByUid(Long uid) {
+ // 先查询sysUser,然后用其中的adminId查询对应的管理员
+ User user = userService.getById(uid);
+ if (user == null) {
+ throw new CrmebException("用户不存在");
+ }
+
+ Integer adminId = user.getAdminid();
+ if (adminId == null) {
+ throw new CrmebException("用户不是管理员");
+ }
+
+ SystemAdmin systemAdmin = systemAdminService.getById(adminId);
+ if (systemAdmin == null) {
+ throw new CrmebException("管理员不存在");
+ }
+
+ SystemAdminResponse systemAdminResponse = new SystemAdminResponse();
+ BeanUtils.copyProperties(systemAdmin, systemAdminResponse);
+ List roleList = Stream.of(systemAdmin.getRoles().split(",")).collect(Collectors.toList());
+ List permList = CollUtil.newArrayList();
+ if (roleList.contains("1")) {
+ permList.add("*:*:*");
+ } else {
+ // 获取用户权限
+ permList = getPermissionsByAdminId(systemAdmin.getId());
+ }
+ systemAdminResponse.setPermissionsList(permList);
+ return systemAdminResponse;
+ }
+
+ /**
+ * 根据管理员ID获取权限列表
+ * @param adminId 管理员ID
+ * @return 权限列表
+ */
+ private List getPermissionsByAdminId(Integer adminId) {
+ SystemAdmin systemAdmin = systemAdminService.getById(adminId);
+ if (systemAdmin == null || systemAdmin.getIsDel()) {
+ throw new CrmebException("管理员不存在");
+ }
+
+ // 获取角色列表
+ List roleList = new ArrayList<>();
+ if (StrUtil.isNotBlank(systemAdmin.getRoles())) {
+ roleList = Stream.of(systemAdmin.getRoles().split(",")).collect(Collectors.toList());
+ }
+
+ // 如果是超管,返回所有权限
+ if (roleList.contains("1")) {
+ return CollUtil.newArrayList("*:*:*");
+ }
+
+ // 获取用户权限
+ List menuList =systemMenuDao.getMenusByUserIdAndPhoto(adminId);
+ menuList = menuList.stream().filter(e -> StrUtil.isNotEmpty(e.getPerms())).collect(Collectors.toList());
+ List permissions = menuList.stream().map(SystemMenu::getPerms).collect(Collectors.toList());
+
+ return permissions;
+ }
}
diff --git a/crmeb/crmeb-admin/src/main/java/com/zbkj/common/request/QuickOutBillRequest.java b/crmeb/crmeb-admin/src/main/java/com/zbkj/common/request/QuickOutBillRequest.java
index bb19872..b106dab 100644
--- a/crmeb/crmeb-admin/src/main/java/com/zbkj/common/request/QuickOutBillRequest.java
+++ b/crmeb/crmeb-admin/src/main/java/com/zbkj/common/request/QuickOutBillRequest.java
@@ -24,6 +24,12 @@ public class QuickOutBillRequest {
@ApiModelProperty(value = "商品列表")
private List items;
+ /**
+ * 用户id
+ */
+ @ApiModelProperty(value = "用户id")
+ private Long uid;
+
/**
* 快速出库商品项
*/
@@ -42,6 +48,12 @@ public class QuickOutBillRequest {
@ApiModelProperty(value = "数量")
private BigDecimal quantity;
+ /**
+ * 入库单据id
+ */
+ @ApiModelProperty(value = "入库单据id")
+ private Long ckCargoStockId;
+
}
}
diff --git a/crmeb/crmeb-admin/src/main/java/com/zbkj/common/response/InventoryResponse.java b/crmeb/crmeb-admin/src/main/java/com/zbkj/common/response/InventoryResponse.java
new file mode 100644
index 0000000..e72e1d3
--- /dev/null
+++ b/crmeb/crmeb-admin/src/main/java/com/zbkj/common/response/InventoryResponse.java
@@ -0,0 +1,117 @@
+package com.zbkj.common.response;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
+
+import java.math.BigDecimal;
+
+/**
+ * 物资盘点表响应对象
+ */
+@Data
+public class InventoryResponse {
+
+ /**
+ * 序号
+ */
+ @ApiModelProperty(value = "序号")
+ @ExcelProperty(value = "序号", index = 0)
+ @ColumnWidth(10)
+ private Integer index;
+
+ /**
+ * 商品名称
+ */
+ @ApiModelProperty(value = "商品名称")
+ @ExcelIgnore
+ private String cargoName;
+
+ /**
+ * 规格型号
+ */
+ @ApiModelProperty(value = "规格型号")
+ @ExcelIgnore
+ private String cargoSpec;
+
+ /**
+ * 品名及规格
+ */
+ @ApiModelProperty(value = "品名及规格")
+ @ExcelProperty(value = "品名及规格", index = 1)
+ @ColumnWidth(30)
+ private String cargoNameWithSpec;
+
+ /**
+ * 上期结存数量
+ */
+ @ApiModelProperty(value = "上期结存数量")
+ @ExcelProperty(value = {"上期结存", "数量"}, index = 2)
+ @ColumnWidth(15)
+ private BigDecimal lastCargoNum;
+
+ /**
+ * 上期结存金额
+ */
+ @ApiModelProperty(value = "上期结存金额")
+ @ExcelProperty(value = {"上期结存", "金额"}, index = 3)
+ @ColumnWidth(15)
+ private BigDecimal lastCargoValue;
+
+ /**
+ * 本期入库数量
+ */
+ @ApiModelProperty(value = "本期入库数量")
+ @ExcelProperty(value = {"本期入库", "数量"}, index = 4)
+ @ColumnWidth(15)
+ private BigDecimal inCargoNum;
+
+ /**
+ * 本期入库金额
+ */
+ @ApiModelProperty(value = "本期入库金额")
+ @ExcelProperty(value = {"本期入库", "金额"}, index = 5)
+ @ColumnWidth(15)
+ private BigDecimal inCargoValue;
+
+ /**
+ * 本期出库数量
+ */
+ @ApiModelProperty(value = "本期出库数量")
+ @ExcelProperty(value = {"本期出库", "数量"}, index = 6)
+ @ColumnWidth(15)
+ private BigDecimal outCargoNum;
+
+ /**
+ * 本期出库金额
+ */
+ @ApiModelProperty(value = "本期出库金额")
+ @ExcelProperty(value = {"本期出库", "金额"}, index = 7)
+ @ColumnWidth(15)
+ private BigDecimal outCargoValue;
+
+ /**
+ * 累计结存数量
+ */
+ @ApiModelProperty(value = "累计结存数量")
+ @ExcelProperty(value = {"累计结存", "数量"}, index = 8)
+ @ColumnWidth(15)
+ private BigDecimal cargoNum;
+
+ /**
+ * 累计结存金额
+ */
+ @ApiModelProperty(value = "累计结存金额")
+ @ExcelProperty(value = {"累计结存", "金额"}, index = 9)
+ @ColumnWidth(15)
+ private BigDecimal cargoValue;
+
+ /**
+ * 单位
+ */
+ @ApiModelProperty(value = "单位")
+ @ExcelIgnore
+ private String unit;
+}
\ No newline at end of file
diff --git a/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/controller/CkBillCargoController.java b/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/controller/CkBillCargoController.java
index 02db833..e6096b7 100644
--- a/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/controller/CkBillCargoController.java
+++ b/crmeb/crmeb-admin/src/main/java/com/zbkj/modules/autogencode/controller/CkBillCargoController.java
@@ -8,24 +8,28 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URLEncoder;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import javax.servlet.http.HttpServletResponse;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.zbkj.common.model.system.SysDept;
import com.zbkj.common.model.system.SystemAdmin;
import com.zbkj.modules.autogencode.entity.*;
-import com.zbkj.modules.autogencode.service.CkStockChangeService;
+import com.zbkj.modules.autogencode.service.*;
import com.zbkj.service.service.SysDeptService;
import com.zbkj.service.service.SystemAdminService;
+import com.zbkj.modules.autogencode.service.CmCustService;
import org.apache.commons.lang3.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zbkj.common.request.PageParamRequest;
import com.zbkj.common.response.CommonResult;
import com.zbkj.common.page.CommonPage;
-import com.zbkj.modules.autogencode.service.CkBillService;
-import com.zbkj.modules.autogencode.service.CkBillCargoService;
-import com.zbkj.modules.autogencode.service.CkBillStockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@@ -58,6 +62,18 @@ public class CkBillCargoController {
@Autowired
private SysDeptService systemDeptService;
+
+ @Autowired
+ private CmCustProductService cmCustProductService;
+
+ @Autowired
+ private PmProductClassService pmProductClassService;
+
+ @Autowired
+ private SysDictDataService sysDictDataService;
+
+ @Autowired
+ private CmCustService cmCustService;
/**
* 条件设置
* 根据实体类字段自动生成查询条件
@@ -201,7 +217,36 @@ public class CkBillCargoController {
// 货主名称
if (StrUtil.isNotBlank(request.getCustName())) {
- queryWrapper.eq(CkBillCargo::getCustName, request.getCustName());
+ queryWrapper.like(CkBillCargo::getCustName, request.getCustName());
+ }
+
+ // 商品分类ID(通过关联CmCustProduct表查询)
+ if (request.getClassId() != null) {
+ queryWrapper.inSql(CkBillCargo::getCargoId,
+ "select id from cm_cust_product where class_id = " + request.getClassId());
+ }
+
+ // 商品分类ID列表(支持多选,逗号分隔字符串或数组格式)
+ if (StrUtil.isNotBlank(request.getClassIds())) {
+ String classIdsStr = request.getClassIds();
+ // 处理数组格式 [1,2,3] 或 ["1","2","3"]
+ if (classIdsStr.startsWith("[")) {
+ classIdsStr = classIdsStr.replace("[", "").replace("]", "").replace("\"", "");
+ }
+ // 处理数组参数格式 classIds[]=1&classIds[]=2 转换后的字符串
+ if (classIdsStr.contains("classIds[]=")) {
+ String[] parts = classIdsStr.split("&");
+ StringBuilder sb = new StringBuilder();
+ for (String part : parts) {
+ if (part.startsWith("classIds[]=")) {
+ if (sb.length() > 0) sb.append(",");
+ sb.append(part.replace("classIds[]=", ""));
+ }
+ }
+ classIdsStr = sb.toString();
+ }
+ queryWrapper.inSql(CkBillCargo::getCargoId,
+ "select id from cm_cust_product where class_id in (" + classIdsStr + ")");
}
// 业务性质
@@ -433,6 +478,51 @@ public class CkBillCargoController {
}
}
}
+
+ // 根据cargoId查询CmCustProduct获取分类信息
+ if (cargo.getCargoId() != null) {
+ CmCustProduct product = cmCustProductService.getById(cargo.getCargoId());
+ if (product != null) {
+ cargo.setClassId(product.getClassId());
+ // 根据classId查询物资类别代码
+ if (product.getClassId() != null) {
+ PmProductClass productClass = pmProductClassService.getById(product.getClassId());
+ if (productClass != null) {
+ cargo.setClassCode(productClass.getClassCode());
+ cargo.setClassName(productClass.getClassName());
+ }
+ }
+ }
+ }
+
+ // 添加单位名称(翻译过的单位)
+ if (StrUtil.isNotBlank(cargo.getUnit())) {
+ // 尝试不同的字典类型
+ String[] dictTypes = {"bm_measuring_unit"};
+ String unitName = cargo.getUnit();
+
+ for (String dictType : dictTypes) {
+ SysDictData dictData = sysDictDataService.getOne(new LambdaQueryWrapper()
+ .eq(SysDictData::getDictType, dictType)
+ .and(wrapper -> wrapper.eq(SysDictData::getDictValue, cargo.getUnit())
+ .or().eq(SysDictData::getDictLabel, cargo.getUnit())));
+
+ if (dictData != null) {
+ unitName = dictData.getDictLabel();
+ break;
+ }
+ }
+
+ // 如果仍然是0/斤格式,提取斤部分
+ if (unitName != null && unitName.contains("/")) {
+ String[] parts = unitName.split("/");
+ if (parts.length > 1) {
+ unitName = parts[1];
+ }
+ }
+
+ cargo.setUnitName(unitName);
+ }
}
return CommonResult.success(page);
@@ -468,9 +558,17 @@ public class CkBillCargoController {
if (request.getBeginDateTwo() != null) {
queryWrapper.between(CkBillCargo::getExpiryDate, request.getBeginDateTwo(), adjustEndDate(request.getEndDateTwo()));
}
+
+ // 出库时间范围查询(通过billDate字段处理)
+ if (request.getBillDate() != null && request.getBeginDate() == null) {
+ // 使用billDate作为起始日期查询
+ queryWrapper.ge(CkBillCargo::getBillDate, request.getBillDate());
+ }
// 排序
queryWrapper.orderByDesc(CkBillCargo::getBillDate);
+ queryWrapper.orderByDesc(CkBillCargo::getBillNumber);
+
}
/**
@@ -604,6 +702,35 @@ public class CkBillCargoController {
return CommonResult.success(totalWeight);
}
+ /**
+ * 查询出库合计(数量和金额)
+ */
+ @ApiOperation("查询出库合计")
+ @GetMapping("/selectTotal")
+ public CommonResult