Compare commits

..

137 Commits

Author SHA1 Message Date
mkm
bb93f8f238 Merge pull request 'dev' (#31) from dev into main
Reviewed-on: #31
2025-04-28 11:56:35 +08:00
f3b547b835 修改仓库商品查询的错误 2025-04-28 11:55:17 +08:00
mkm
bcbcd626c3 1 2025-04-24 18:36:25 +08:00
mkm
7e11bf3bb2 1 2025-04-24 18:36:14 +08:00
mkm
03af4a589a Merge pull request 'feat(admin): 为商品列表添加图片字段' (#30) from dev into main
Reviewed-on: #30
2025-04-24 15:58:33 +08:00
mkm
13a575ca0c feat(admin): 为商品列表添加图片字段
- 在 StoreProductLists 类中添加了 'image' => '图片' 字段
- 此修改使得商品列表能够显示商品图片,提高列表的可读性和直观性
2025-04-24 15:57:54 +08:00
mkm
fb3b626970 Merge pull request '添加导入商品采购价' (#29) from dev into main
Reviewed-on: #29
2025-04-23 15:22:57 +08:00
959978f746 添加导入商品采购价 2025-04-23 15:22:27 +08:00
mkm
fbba725ce7 Merge pull request '同步商品价格比例' (#28) from dev into main
Reviewed-on: #28
2025-04-18 18:00:39 +08:00
11687aa3d4 同步商品价格比例 2025-04-18 18:00:11 +08:00
mkm
a08d11f69c Merge pull request '同步商品价格比例' (#27) from dev into main
Reviewed-on: #27
2025-04-18 17:50:28 +08:00
49d534a48d 同步商品价格比例 2025-04-18 17:49:43 +08:00
mkm
0a046509dd Merge pull request '添加商品价格更新时间' (#26) from dev into main
Reviewed-on: #26
2025-04-18 17:30:15 +08:00
970a7f07c5 添加商品价格更新时间 2025-04-18 17:22:06 +08:00
mkm
848dbf2c80 Merge pull request 'dev' (#25) from dev into main
Reviewed-on: #25
2025-04-18 16:33:03 +08:00
463da3cef1 Merge branch 'dev' of https://gitea.lihaink.cn/mkm/multi-store into dev 2025-04-18 16:32:27 +08:00
5e35acdc39 修改商品零售价格的错误 2025-04-18 16:31:14 +08:00
mkm
58b70c53f8 Merge pull request 'refactor(xlsx): 调整订单供货出库表格的列标题和数据填充逻辑' (#24) from dev into main
Reviewed-on: #24
2025-04-18 15:20:36 +08:00
mkm
b9e34a94d9 refactor(xlsx): 调整订单供货出库表格的列标题和数据填充逻辑
- 将"出库单价"、"出库总价"、"供货价"、"供货总价"等列
2025-04-18 15:19:00 +08:00
mkm
6d67d00c63 Merge pull request 'feat(admin): 仓库产品列表增加分类搜索功能' (#23) from dev into main
Reviewed-on: #23
2025-04-18 13:48:42 +08:00
mkm
3976af97f1 feat(admin): 仓库产品列表增加分类搜索功能
- 添加了根据分类 ID 进行搜索的功能
- 如果请求中包含 'class_all' 参数,则在查询中加入相应的条件
- 通过 StoreProduct 模型获取符合条件的产品 ID 列表
- 如果没有符合条件的产品,则返回空数组
2025-04-18 13:47:42 +08:00
mkm
a89f7fbe28 Merge pull request '调整了查询条件,增加了对class_all参数的处理。' (#22) from dev into main
Reviewed-on: #22
2025-04-18 12:07:45 +08:00
bb039fcf5e 调整了查询条件,增加了对class_all参数的处理。 2025-04-18 12:06:16 +08:00
mkm
b461c79b53 Merge pull request '修改商品列表搜索' (#21) from dev into main
Reviewed-on: #21
2025-04-17 09:57:21 +08:00
197a31668e 修改商品列表搜索 2025-04-17 09:57:07 +08:00
mkm
b3dee9c166 Merge pull request '修改商品列表搜索' (#20) from dev into main
Reviewed-on: #20
2025-04-17 09:44:42 +08:00
6dcd228e3c 修改商品列表搜索 2025-04-17 09:44:17 +08:00
mkm
fb4d528070 Merge pull request '更新 app/admin/logic/store_product/StoreProductLogic.php' (#19) from mkm-patch-2 into main
Reviewed-on: #19
2025-04-16 18:20:31 +08:00
mkm
90927b1c8e 更新 app/admin/logic/store_product/StoreProductLogic.php 2025-04-16 18:20:21 +08:00
mkm
363c7d604a Merge pull request 'dev' (#18) from dev into main
Reviewed-on: #18
2025-04-16 17:18:47 +08:00
eb24c561ad 修改商品列表搜索 2025-04-16 17:17:55 +08:00
4fc5b2d8dd 修改商品列表搜索 2025-04-16 17:14:58 +08:00
mkm
42750fcab9 Merge pull request '修改商品列表搜索' (#17) from dev into main
Reviewed-on: #17
2025-04-16 17:00:51 +08:00
022a25c6a6 修改商品列表搜索 2025-04-16 17:00:29 +08:00
mkm
4f7c8ffa85 Merge pull request '修改商品列表搜索' (#16) from dev into main
Reviewed-on: #16
2025-04-16 16:44:58 +08:00
881164ebbd 修改商品列表搜索 2025-04-16 16:43:41 +08:00
mkm
0d6c8f8057 Merge pull request '调试导入赠品' (#15) from dev into main
Reviewed-on: #15
2025-04-16 10:29:23 +08:00
fae49b796f 调试导入赠品 2025-04-16 10:24:40 +08:00
mkm
7e8a5d5420 Merge pull request 'dev' (#14) from dev into main
Reviewed-on: #14
2025-04-14 17:31:58 +08:00
3d47bb1b5d 修改预订单商品退库 2025-04-14 17:30:52 +08:00
c19efa176a 商品图片管理1 2025-04-14 16:02:44 +08:00
c19ef6080a 商品图片管理 2025-04-14 15:33:52 +08:00
mkm
e220e660f8 Merge pull request 'dev' (#13) from dev into main
Reviewed-on: #13
2025-04-14 14:45:22 +08:00
daf4b858ce 修改采购价格录入限制 2025-04-14 14:44:25 +08:00
e6e0eaadab 调试图片上传和识别 2025-04-14 09:40:54 +08:00
mkm
a4eb84500a Merge pull request 'fix(product): 修复商品价格保存逻辑' (#12) from dev into main
Reviewed-on: #12
2025-04-12 15:57:00 +08:00
mkm
f9d969c85c fix(product): 修复商品价格保存逻辑
- 在 StoreProductPriceLogic 类中,将价格保存逻辑中的 'price' 字段错误地设置为 'vip_price' 的值
- 已将相关代码修正,确保 'price' 字段正确保存为 'price' 的值
2025-04-12 15:56:30 +08:00
mkm
0ae06f9bfb Merge pull request '商品列表添加改价' (#11) from dev into main
Reviewed-on: #11
2025-04-12 11:43:30 +08:00
41264fd9a0 商品列表添加改价 2025-04-12 11:24:54 +08:00
mkm
40ede21710 Merge pull request '修改往期补单入库' (#10) from dev into main
Reviewed-on: #10
2025-04-11 10:24:37 +08:00
ed4d7bb3ae 修改往期补单入库 2025-04-11 10:02:50 +08:00
mkm
f7379b663a Merge pull request 'dev' (#9) from dev into main
Reviewed-on: #9
2025-04-10 14:36:21 +08:00
d13c5c16b0 修改小程序端订单详情 2025-04-10 14:24:27 +08:00
776ee0bfbc Merge branch 'dev' of https://gitea.lihaink.cn/mkm/multi-store into HEAD 2025-04-09 12:28:14 +08:00
1182ee6279 调拨单详情备注 2025-04-09 12:21:35 +08:00
mkm
dcaca31635 add tencent sdk 2025-04-08 15:33:59 +08:00
8d085e688e 调拨订单导出和插入修改1 2025-04-08 14:44:26 +08:00
5e378a3372 调拨订单导出和插入修改1 2025-04-08 14:40:56 +08:00
83fe8c4539 调拨订单导出和插入修改 2025-04-08 12:40:18 +08:00
95514a0da6 调拨订单导出和插入修改 2025-04-08 12:32:33 +08:00
d05a8c842d 调拨订单导出和插入修改 2025-04-08 12:23:52 +08:00
dd681470d8 调拨订单导出和插入arr 2025-04-08 11:39:42 +08:00
be9781f170 调拨订单导出和插入 2025-04-08 11:23:09 +08:00
6e291277d0 调拨订单导出和插入 2025-04-08 11:18:54 +08:00
c26790ebbe excel导入铺货。修改接口 2025-04-07 14:01:01 +08:00
08fa715e73 excel导入铺货。修改接口 2025-04-07 13:37:23 +08:00
4875159679 excel导入铺货。修改接口 2025-04-07 12:10:28 +08:00
e3dc0985bd excel导入铺货 2025-04-07 10:46:37 +08:00
3a1f256fe9 Merge pull request '修改商品出库的错误' (#8) from dev into main
Reviewed-on: #8
2025-04-06 10:57:12 +08:00
d1a4e5acdf 修改商品出库的错误 2025-04-06 10:56:09 +08:00
d71b3ddefa Merge pull request '修改采购价格录入的错误' (#7) from dev into main
Reviewed-on: #7
2025-04-06 10:35:44 +08:00
850773a2fd 修改采购价格录入的错误 2025-04-06 10:33:06 +08:00
5b37749696 Merge pull request '修改预订单高级会员导出' (#6) from dev into main
Reviewed-on: #6
2025-04-03 16:52:01 +08:00
8aa2740b50 修改预订单高级会员导出 2025-04-03 16:51:06 +08:00
8deb9a32bb Merge pull request '修改预订单高级会员导出' (#5) from dev into main
Reviewed-on: #5
2025-04-03 14:59:05 +08:00
2439429e4c 修改预订单高级会员导出 2025-04-03 14:58:12 +08:00
mkm
d3c4bf923f Merge pull request '修改预订单高级会员导出' (#4) from dev into main
Reviewed-on: #4
2025-04-03 11:40:30 +08:00
b55503650c 修改预订单高级会员导出 2025-04-03 11:40:07 +08:00
mkm
ef846fe23d Merge pull request 'dev' (#3) from dev into main
Reviewed-on: #3
2025-04-03 11:32:03 +08:00
mkm
94676eb4ea Merge branch 'main' into dev 2025-04-03 11:30:22 +08:00
7ea7dde782 Merge branch 'dev' of https://gitea.lihaink.cn/mkm/multi-store into dev 2025-04-03 11:29:02 +08:00
407553baaf 修改预订单高级会员导出 2025-04-03 11:28:58 +08:00
mkm
98181dfbf9 Merge pull request '更新 app/api/lists/order/CartList.php' (#2) from dev into main
Reviewed-on: #2
2025-04-02 16:12:18 +08:00
mkm
ba6d76de7e 更新 app/api/lists/order/CartList.php 2025-04-02 16:12:02 +08:00
mkm
bb5f16e971 Merge pull request 'dev' (#1) from dev into main
Reviewed-on: #1
2025-04-02 16:06:56 +08:00
mkm
cf55572a9b 更新 app/api/lists/product/ProductLists.php 2025-04-02 16:06:09 +08:00
5f543566cb 调整商品调拨单 2025-03-26 17:44:29 +08:00
5d74bf2f41 修改报损出库 2025-03-26 14:00:16 +08:00
mkm
38d5451d9f Merge pull request '数据变更列表添加操作时间' (#560) from dev into main
Reviewed-on: #560
2025-03-26 10:49:54 +08:00
9e51c0963b 数据变更列表添加操作时间 2025-03-26 10:39:07 +08:00
mkm
5a00d7a858 Merge pull request '修改预订单出库' (#559) from dev into main
Reviewed-on: #559
2025-03-26 10:19:06 +08:00
4585c57609 修改预订单出库 2025-03-25 14:46:58 +08:00
mkm
53faf6751c Merge pull request '采购资金添加详情' (#558) from dev into main
Reviewed-on: #558
2025-03-24 14:30:16 +08:00
6e8b34f301 采购资金添加详情 2025-03-24 14:16:23 +08:00
mkm
d06d71b167 Merge pull request '添加复制到仓库' (#557) from dev into main
Reviewed-on: #557
2025-03-23 09:24:41 +08:00
0fc761e915 添加复制到仓库 2025-03-22 11:45:20 +08:00
mkm
5bc0836fea Merge pull request 'dev' (#556) from dev into main
Reviewed-on: #556
2025-03-21 17:45:03 +08:00
fcef927257 调试财务溯源 2025-03-21 17:36:00 +08:00
b4e8f188ab 调试财务溯源 2025-03-21 17:15:38 +08:00
mkm
0863b55846 Merge pull request 'dev' (#555) from dev into main
Reviewed-on: #555
2025-03-21 09:17:28 +08:00
0ddfd9c483 调试财务溯源 2025-03-20 15:58:38 +08:00
e2b47ab17b 调试财务溯源 2025-03-20 15:29:55 +08:00
7f843c5698 调试财务溯源 2025-03-20 15:20:44 +08:00
09a6c25259 调试财务溯源 2025-03-20 15:04:32 +08:00
ccfd1f3556 调试财务溯源 2025-03-20 14:16:00 +08:00
mkm
a20a7eb8b4 Merge pull request 'dev' (#554) from dev into main
Reviewed-on: #554
2025-03-18 16:15:08 +08:00
0eb1586076 修改预订单列表查询 2025-03-18 16:07:45 +08:00
98815747f5 修改商品改价列表 2025-03-18 15:20:56 +08:00
mkm
4d22eecf2d Merge pull request '修改商品溯源导出' (#553) from dev into main
Reviewed-on: #553
2025-03-18 09:40:19 +08:00
4be97abe72 Merge branch 'main' into dev 2025-03-18 09:38:35 +08:00
6751be1f23 修改商品溯源导出 2025-03-18 09:37:05 +08:00
mkm
0d30d497cc Merge pull request '修改商品溯源导出' (#552) from dev into main
Reviewed-on: #552
2025-03-17 18:48:10 +08:00
7fc4d87249 修改商品溯源导出 2025-03-17 18:47:43 +08:00
mkm
2c5c541fe8 Merge pull request '添加商品溯源导出' (#551) from dev into main
Reviewed-on: #551
2025-03-17 18:36:36 +08:00
43b34ea55b 添加商品溯源导出 2025-03-17 18:35:48 +08:00
mkm
2d615a43e6 Merge pull request '修改出入库补单' (#550) from dev into main
Reviewed-on: #550
2025-03-17 17:34:41 +08:00
712409b41b 修改出入库补单 2025-03-17 17:31:15 +08:00
mkm
67a019608a Merge pull request '添加出入库补单' (#549) from dev into main
Reviewed-on: #549
2025-03-17 17:21:52 +08:00
4d89794a05 添加出入库补单 2025-03-17 16:40:34 +08:00
mkm
2accc5e41d Merge pull request 'dev' (#548) from dev into main
Reviewed-on: #548
2025-03-17 15:34:14 +08:00
6475df1d71 修改图片字段的错误 2025-03-17 15:33:03 +08:00
a9ae0ede08 修改出库单商品详情 2025-03-17 15:04:40 +08:00
mkm
cfcb1c181c Merge pull request 'dev' (#547) from dev into main
Reviewed-on: #547
2025-03-17 14:42:28 +08:00
60ae388d9f Merge branch 'update_warehouse_product' into dev 2025-03-17 14:36:13 +08:00
c3acd04bf8 商品溯源详情添加跳转 2025-03-17 14:36:02 +08:00
mkm
6375194854 Merge pull request 'update_warehouse_product' (#546) from update_warehouse_product into main
Reviewed-on: #546
2025-03-15 11:26:09 +08:00
a49919882a 调整商品溯源 2025-03-14 18:16:27 +08:00
c9684b2f8b 调整商品溯源 2025-03-14 17:37:36 +08:00
4a8d90d1a6 调整商品溯源 2025-03-14 17:18:17 +08:00
mkm
b2e51cbf5f refactor(app): 调整商品价格显示逻辑
- 注释掉原代码中处理活动价的部分
- 新增高级会员价处理逻辑
- 修改价格显示为成本价
- 更新商品名称后缀为"高级会员价"
2025-03-14 16:56:05 +08:00
mkm
092e5e1785 fix(admin): 修复预订单购物车信息逻辑
- 在预订单购物车信息中添加 purchase 字段,用于记录商品价格
- 修复了未定义 prices 导致的潜在问题,使用空值合并运算符 ?? 0 提供默认值
- 确保 cart_num、accept_num 和 price 字段正确赋值
2025-03-14 14:46:18 +08:00
mkm
02c96c75d7 feat: 价格趋势数据按时间顺序排序
- 在处理价格趋势数据时,增加了对列表进行按时间顺序排序的步骤
- 使用 asort() 函数对 $list 数组进行排序,确保价格趋势数据按时间轴正确展示
2025-03-14 11:59:23 +08:00
mkm
d367e0e49f refactor(admin): 优化商品价格查询和订单处理逻辑
- 修改商品价格查询排序方式,从升序改为降序
2025-03-14 11:50:36 +08:00
0ad56182cf 修改商品出入库溯源 2025-03-13 17:49:03 +08:00
ad25d6c599 调整商品溯源 2025-03-12 17:54:08 +08:00
mkm
8c4128ccd4 calc(product-source-link): 计算商品溯源列表中的总数和仓库数
- 移除了字段 'total_nums', 'nums', 'warehouse_total_nums', 'warehouse_nums' 的直接查询
- 使用 each 函数遍历查询结果,计算每个商品的总数量和仓库数量
- 通过 ProductSourceLinkInfo 模型
2025-03-12 14:34:21 +08:00
mkm
47de656777 refactor(api): 更新 IndexController 中的数据处理逻辑
- 移除了未使用的注释代码
- 添加了对 'ceshi_copy_copy' 表的数据处理逻辑
- 使用 Db 类进行数据库操作,提高了代码的可读性和维护性
- 优化了数据处理流程,提高了代码执行效率
2025-03-12 11:21:45 +08:00
35935 changed files with 3656064 additions and 383 deletions

View File

@ -3,14 +3,27 @@
namespace app\admin\controller;
use app\admin\logic\beforehand_order_cart_info\BeforehandOrderCartInfoLogic;
use app\admin\logic\product_source_link_info\ProductSourceLinkInfoLogic;
use app\admin\logic\inventory_transfer_order\InventoryTransferOrderLogic;
use app\admin\logic\store_product\StoreProductLogic;
use app\admin\logic\store_product_price\StoreProductPriceLogic;
use app\admin\service\ProductPriceService;
use app\common\model\beforehand_order\BeforehandOrder;
use app\common\model\beforehand_order_cart_info\BeforehandOrderCartInfo;
use app\common\model\CeshiCopy;
use app\common\model\product_source_link\ProductSourceLink;
use app\common\model\product_source_link_info\ProductSourceLinkInfo;
use app\common\model\purchase_product_offer\PurchaseProductOffer;
use app\common\model\store_category\StoreCategory;
use app\common\model\store_product\StoreProduct;
use app\common\model\store_product_group_price\StoreProductGroupPrice;
use app\common\model\store_product_price\StoreProductPrice;
use app\common\model\StoreProductPriceList;
use app\common\model\warehouse_order\WarehouseOrder;
use app\common\model\warehouse_product\WarehouseProduct;
use app\common\model\store_branch_product\StoreBranchProduct;
use app\common\model\system_store\SystemStore;
use app\common\model\warehouse_product_storege\WarehouseProductStorege;
use PhpOffice\PhpSpreadsheet\IOFactory;
use support\exception\BusinessException;
use support\Redis;
@ -19,7 +32,186 @@ use think\facade\Db;
class LocalController extends BaseAdminController
{
public $notNeedLogin = ['activityPrice', 'searchProduct', 'setPrice', 'index', 'updateProductPriceList', 'importOrder'];
public $notNeedLogin = ['importPrice', 'searchProduct', 'setPrice', 'index', 'updateProductPriceList', 'importOrder', 'warehousing', 'outbound', 'syncPrice', 'importProduct'];
public $ids = [1829, 1828, 1827, 1826, 1825, 1824, 1823, 1821, 1820, 1814, 1813, 1811, 1810, 1809, 1808, 1807, 1806, 1800, 1799, 1798, 1796, 1795, 1794, 1793, 1792, 1791, 1790, 1789, 1788, 1787, 1786, 1785, 1784, 1783, 1782, 1781, 1780, 1779, 1778, 1777, 1776, 1775, 1774, 1773, 1772, 1771, 1770, 1768, 1765, 1764, 1763, 1762, 1761, 1760, 1759, 1758, 1757, 1756, 1755, 1754, 1753, 1752, 1751, 1750, 1749, 1748, 1747, 1746, 1745, 1744, 1743, 1742, 1741, 1740, 1739, 1738, 1737, 1736, 1735, 1733, 1732, 1731, 1730, 1729, 1728, 1727, 1726, 1725, 1724, 1723, 1722, 1720, 1719, 1718, 1717, 1716, 1715, 1714, 1713, 1712, 1711, 1710, 1709, 1708, 1707, 1706, 1705, 1704, 1703, 1701, 1700, 1699, 1698, 1697, 1696, 1695, 1694, 1693, 1692, 1691, 1690, 1689, 1688, 1687, 1686, 1685, 1684, 1683, 1682, 1681, 1680, 1679, 1678, 1677, 1676, 1675, 1674, 1673, 1672, 1671, 1670, 1668, 1667, 1666, 1665, 1664, 1663, 1660, 1659, 1658, 1657, 1656, 1655, 1654, 1652, 1651, 1650, 1649, 1648, 1647, 1646, 1645, 1644, 1643, 1642, 1641, 1640, 1639, 1638, 1637, 1636, 1635, 1634, 1633, 1632, 1631, 1630, 1629, 1628, 1627, 1626, 1623, 1622];
public function importPrice()
{
$file = $this->request->file('file');
$reader = IOFactory::createReader('Xlsx');
$spreadsheet = $reader->load($file->getRealPath());
$data = $spreadsheet->getActiveSheet()->toArray();
foreach ($data as $k => $v) {
if ($k < 1) {
continue;
}
$productId = $v[0];
$purchasePrice = $v[12];
$product = StoreProduct::where('id', $productId)->find();
if (empty($product)) {
continue;
}
$params = [
'product_id' => $productId,
'purchase_price' => $purchasePrice,
'status' => 1,
];
$productService = new ProductPriceService();
$productPriceRate = $productService->getProductPriceRate($productId);
if (!empty($productPriceRate)) {
$priceArray = $productService->setProductPrice($params['purchase_price'], $productPriceRate);
$params = array_merge($params, $priceArray);
}
StoreProductPriceLogic::add($params);
}
}
public function importProduct()
{
$file = $this->request->file('file');
$reader = IOFactory::createReader('Xlsx');
$spreadsheet = $reader->load($file->getRealPath());
$data = $spreadsheet->getActiveSheet()->toArray();
$createTime = time();
$updateTime = time();
foreach ($data as $k => $v) {
if ($k < 1) {
continue;
}
$productName = $v[0];
$num = $v[1];
$package = $v[2];
$product = StoreProduct::where('store_name', $productName)->find();
if (empty($product)) {
$product = StoreProductLogic::add([
'store_name' => $productName,
'image' => '',
'cate_id' => 15627,
'cate_arr' => [15324, 15627],
'package' => $package,
'unit' => 0,
'price' => 0,
'vip_price' => 0,
'cost' => 0,
'purchase' => 0,
'is_return' => 0,
'is_store_all' => 1,
'product_type' => 3,
]);
}
$warehouseProduct = WarehouseProductStorege::where('product_id', $product->id)->find();
if (empty($warehouseProduct)) {
WarehouseProductStorege::create([
'product_id' => $product->id,
'nums' => $num,
'warehouse_id' => 1,
'create_time' => $createTime,
'update_time' => $updateTime,
]);
} else {
$warehouseProduct->save(['nums' => $num]);
}
}
}
public function syncPrice(ProductPriceService $productPriceService)
{
$data = Db::connect('local')->query('SELECT id, product_id,purchase_price FROM (SELECT id,product_id,purchase_price,ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY id DESC) as rn FROM la_store_product_price) subquery WHERE rn = 1');
$products = StoreProduct::whereIn('id', array_column($data, 'product_id'))->field('id,store_name,top_cate_id,cate_id')->select()->toArray();
$products = reset_index($products, 'id');
$update = [];
$update2 = [];
foreach ($data as $item) {
$product = $products[$item['product_id']] ?? [];
if (empty($product)) {
continue;
}
$priceRateList = $productPriceService->getProductPriceRate($product['id'], true);
$rate = $priceRateList['supply_rate'];
$costRate = $priceRateList['merchant_rate'];
$vipPriceRate = $priceRateList['vip_rate'];
$priceRate = $priceRateList['price_rate'];
$purchase = bcmul($item['purchase_price'], $rate, 2);
$cost = bcmul($purchase, $costRate, 2);
$price = bcmul($purchase, $priceRate, 2);
$vipPrice = bcmul($purchase, $vipPriceRate, 2);
$update[] = [
'id' => $item['id'],
'purchase_lv' => $rate,
'purchase' => $purchase,
'cost_lv' => $costRate,
'cost' => $cost,
'price_lv' => $priceRate,
'price' => $price,
'vip_lv' => $vipPriceRate,
'vip_price' => $vipPrice,
];
$update2[] = [
'id' => $item['product_id'],
'purchase' => $purchase,
'cost' => $cost,
'price' => $price,
'vip_price' => $vipPrice,
];
}
(new StoreProductPrice())->saveAll($update);
(new StoreProduct())->saveAll($update2);
}
public function warehousing()
{
$warehousingIds = BeforehandOrder::whereIn('id', $this->ids)->where('warehousing_id', '>', 0)->column('warehousing_id');
$warehouseOrders = WarehouseOrder::field('id,warehouse_id')->whereIn('id', $warehousingIds)->where('financial_pm', 1)->select()->toArray();
$productSourceLinkInfo = [];
foreach ($warehouseOrders as $order) {
$products = WarehouseProduct::field('id,product_id,nums,purchase,create_time')->where('oid', $order['id'])->select()->toArray();
foreach ($products as $product) {
$productSourceLink = ProductSourceLink::where('product_id', $product['product_id'])->where('purchase_uid', 20)->where('warehouse_id', $order['warehouse_id'])->find();
if (empty($productSourceLink)) {
$productSourceLink = new ProductSourceLink();
$productSourceLink->product_id = $product['product_id'];
$productSourceLink->purchase_uid = 20;
$productSourceLink->warehouse_id = $order['warehouse_id'];
$productSourceLink->save();
}
$productSourceLinkInfo[] = [
'oid' => $productSourceLink['id'],
'product_id' => $product['product_id'],
'warehouse_id' => $order['warehouse_id'],
'nums' => $product['nums'],
'current_nums' => $product['nums'],
'types' => ProductSourceLinkInfo::TypeIn,
'link_id' => $product['id'],
'price' => $product['purchase'],
'total_price' => bcmul($product['purchase'], $product['nums'], 2),
'create_time' => strtotime($product['create_time']),
];
}
}
(new ProductSourceLinkInfo())->insertAll($productSourceLinkInfo);
}
public function outbound()
{
$outboundIds = BeforehandOrder::whereIn('id', $this->ids)->where('outbound_id', '>', 0)->column('outbound_id');
$outboundOrders = WarehouseOrder::field('id,warehouse_id,store_id')->whereIn('id', $outboundIds)->where('financial_pm', 0)->select()->toArray();
foreach ($outboundOrders as $order) {
$products = WarehouseProduct::field('id,product_id,nums,purchase,create_time')->where('oid', $order['id'])->select()->toArray();
foreach ($products as $product) {
$productSourceLinkInfoLogic = new ProductSourceLinkInfoLogic();
$productSourceLinkInfoLogic->warehouseProduct = $product;
$productSourceLinkInfoLogic->setInfo([
'warehouse_id' => $order['warehouse_id'],
'store_id' => $order['store_id'],
'link_id' => $product['id'],
'create_time' => strtotime($product['create_time']),
]);
$productSourceLinkInfoLogic->outbound();
}
}
}
public function activityPrice()
{
@ -453,4 +645,53 @@ class LocalController extends BaseAdminController
}
}
}
public function importStorege()
{
$file = $this->request->file('file');
$reader = IOFactory::createReader('Xlsx');
$spreadsheet = $reader->load($file->getRealPath());
$sheets = $spreadsheet->getActiveSheet()->toArray();
$new_params = [];
$params = [];
$system_store_id = 0;
$params['product_arr'] = [];
foreach ($sheets as $key => $row) {
if ($key == 0) {
continue;
}
if (!$system_store_id) {
$system_store_id = SystemStore::where('name', $row[1])->value('id');
}
$product = StoreBranchProduct::where('product_id', $row[0])->where('store_id', $system_store_id)->field('id,product_id,stock')->findOrEmpty();
if ($row[10] == $product->stock && intval($product->stock) > 0) {
$arr = [
'nums' => $row[10],
'product_id' => $product->product_id,
'purchase' => 0,
'total_price' => $product->total_price,
];
$params['product_arr'][] = $arr;
} else {
$arr = [];
$arr['product_id'] = $row[0];
$arr['product_name'] = $row[2] ?? '';
$arr['store_id'] = $system_store_id;
$arr['nums'] = $row[10] ?? 0;
$arr['stock'] = $product->stock ?? 0;
$new_params[] = $arr;
}
}
// 生成铺货单
$params['mark'] = "门店铺货-excel导入";
$params['one_id'] = $system_store_id; //门店id
$params['one_type'] = 1; //1门店2仓库
$params['two_id'] = 1; //1海吉星仓库
$params['two_type'] = 2; //1门店2仓库
$params['types'] = 0; //0减库存 1不减库存
InventoryTransferOrderLogic::add($params, $this->adminId);
$new_params = json_encode($new_params, true);
file_put_contents(public_path() . '/output.text', $new_params);
return $this->success('导入成功');
}
}

View File

@ -0,0 +1,115 @@
<?php
namespace app\admin\controller;
use app\admin\controller\BaseAdminController;
use app\admin\lists\PurchaseFundsLists;
use app\admin\logic\PurchaseFundsLogic;
use app\admin\validate\PurchaseFundsValidate;
/**
* PurchaseFunds控制器
* Class PurchaseFundsController
* @package app\admin\controller
*/
class PurchaseFundsController extends BaseAdminController
{
/**
* @notes 获取列表
* @author admin
* @date 2025/03/19 14:59
*/
public function lists()
{
return $this->dataLists(new PurchaseFundsLists());
}
/**
* @notes 添加
* @author admin
* @date 2025/03/19 14:59
*/
public function add()
{
$params = (new PurchaseFundsValidate())->post()->goCheck('add');
$result = PurchaseFundsLogic::add($params);
if (true === $result) {
return $this->success('添加成功', [], 1, 1);
}
return $this->fail(PurchaseFundsLogic::getError());
}
/**
* @notes 编辑
* @author admin
* @date 2025/03/19 14:59
*/
public function edit()
{
$params = (new PurchaseFundsValidate())->post()->goCheck('edit');
$result = PurchaseFundsLogic::edit($params);
if (true === $result) {
return $this->success('编辑成功', [], 1, 1);
}
return $this->fail(PurchaseFundsLogic::getError());
}
/**
* @notes 删除
* @author admin
* @date 2025/03/19 14:59
*/
public function delete()
{
$params = (new PurchaseFundsValidate())->post()->goCheck('delete');
PurchaseFundsLogic::delete($params);
return $this->success('删除成功', [], 1, 1);
}
/**
* @notes 获取详情
* @author admin
* @date 2025/03/19 14:59
*/
public function detail()
{
$params = (new PurchaseFundsValidate())->goCheck('detail');
$result = PurchaseFundsLogic::detail($params);
return $this->data($result);
}
/**
* @notes 审核
* @author admin
* @date 2025/03/19 14:59
*/
public function audit()
{
$params = (new PurchaseFundsValidate())->post()->goCheck('delete');
$params['approve_uid'] = $this->adminId;
PurchaseFundsLogic::audit($params);
return $this->success('操作成功', [], 1, 1);
}
/**
* @notes 补充
* @author admin
* @date 2025/03/19 14:59
*/
public function replenish()
{
$params = (new PurchaseFundsValidate())->post()->goCheck('delete');
$params['approve_uid'] = $this->adminId;
PurchaseFundsLogic::replenish($params);
return $this->success('操作成功', [], 1, 1);
}
}

View File

@ -84,7 +84,7 @@ class BeforehandOrderController extends BaseAdminController
'regional_manager' => $params['regional_manager'] ?? '',
];
$params['other_data'] = $other_data;
if ($params['order_type'] == 7) {
if (in_array($params['order_type'], [7, 9])) {
PurchaseProductOfferLogic::batchCreate($params);
} else {
BeforehandOrderLogic::add($params);

View File

@ -7,7 +7,8 @@ use app\admin\controller\BaseAdminController;
use app\admin\lists\inventory_transfer\InventoryTransferLists;
use app\admin\logic\inventory_transfer\InventoryTransferLogic;
use app\admin\validate\inventory_transfer\InventoryTransferValidate;
use app\admin\logic\inventory_transfer_order\InventoryTransferOrderLogic;
use app\common\service\xlsx\InventoryTransferXlsx;
/**
* 商品调拨控制器
@ -38,8 +39,8 @@ class InventoryTransferController extends BaseAdminController
*/
public function add()
{
$params = (new InventoryTransferValidate())->post()->goCheck('add');
$result = InventoryTransferLogic::add($params,$this->adminId);
$params = $this->request->post();
$result = InventoryTransferLogic::add($params, $this->adminId);
if (true === $result) {
return $this->success('添加成功', [], 1, 1);
}
@ -91,6 +92,4 @@ class InventoryTransferController extends BaseAdminController
$result = InventoryTransferLogic::detail($params);
return $this->data($result);
}
}
}

View File

@ -7,7 +7,8 @@ use app\admin\controller\BaseAdminController;
use app\admin\lists\inventory_transfer_order\InventoryTransferOrderLists;
use app\admin\logic\inventory_transfer_order\InventoryTransferOrderLogic;
use app\admin\validate\inventory_transfer_order\InventoryTransferOrderValidate;
use app\common\service\xlsx\InventoryTransferXlsx;
use app\common\model\inventory_transfer\InventoryTransfer;
/**
* 商品调拨订单控制器
@ -39,7 +40,7 @@ class InventoryTransferOrderController extends BaseAdminController
public function add()
{
$params = $this->request->post();
$result = InventoryTransferOrderLogic::add($params,$this->adminId);
$result = InventoryTransferOrderLogic::add($params, $this->adminId);
if (true === $result) {
return $this->success('添加成功', [], 1, 1);
}
@ -91,5 +92,28 @@ class InventoryTransferOrderController extends BaseAdminController
return $this->data($result);
}
/**
* @notes 审核商品调拨订单
* @author admin
* @date 2025/01/24 09:59
*/
public function audit()
{
$params = (new InventoryTransferOrderValidate())->post()->goCheck('delete');
$order = InventoryTransferOrderLogic::detail($params);
InventoryTransferOrderLogic::audit($order);
return $this->success('删除成功', [], 1, 1);
}
}
/**
* 导出调拨表格
*/
public function export()
{
$params = $this->request->post();
$xlsx = new InventoryTransferXlsx();
$order = InventoryTransferOrderLogic::detail($params);
$file_path = $xlsx->export($order['product_list'], $order);
return $this->success('导出成功', ['url' => $file_path]);
}
}

View File

@ -0,0 +1,95 @@
<?php
namespace app\admin\controller\product_image;
use app\admin\controller\BaseAdminController;
use app\admin\lists\product_image\ProductImageLists;
use app\admin\logic\product_image\ProductImageLogic;
use app\admin\validate\product_image\ProductImageValidate;
/**
* 商品图库管理控制器
* Class ProductImageController
* @package app\admin\controller\product_image
*/
class ProductImageController extends BaseAdminController
{
/**
* @notes 获取商品图库管理列表
* @return \think\response\Json
* @author admin
* @date 2025/04/14 11:02
*/
public function lists()
{
return $this->dataLists(new ProductImageLists());
}
/**
* @notes 添加商品图库管理
* @return \think\response\Json
* @author admin
* @date 2025/04/14 11:02
*/
public function add()
{
$params = (new ProductImageValidate())->post()->goCheck('add');
$result = ProductImageLogic::add($params);
if (true === $result) {
return $this->success('添加成功', [], 1, 1);
}
return $this->fail(ProductImageLogic::getError());
}
/**
* @notes 编辑商品图库管理
* @return \think\response\Json
* @author admin
* @date 2025/04/14 11:02
*/
public function edit()
{
$params = (new ProductImageValidate())->post()->goCheck('edit');
$result = ProductImageLogic::edit($params);
if (true === $result) {
return $this->success('编辑成功', [], 1, 1);
}
return $this->fail(ProductImageLogic::getError());
}
/**
* @notes 删除商品图库管理
* @return \think\response\Json
* @author admin
* @date 2025/04/14 11:02
*/
public function delete()
{
$params = (new ProductImageValidate())->post()->goCheck('delete');
ProductImageLogic::delete($params);
return $this->success('删除成功', [], 1, 1);
}
/**
* @notes 获取商品图库管理详情
* @return \think\response\Json
* @author admin
* @date 2025/04/14 11:02
*/
public function detail()
{
$params = (new ProductImageValidate())->goCheck('detail');
$result = ProductImageLogic::detail($params);
return $this->data($result);
}
}

View File

@ -0,0 +1,145 @@
<?php
namespace app\admin\controller\product_source_link;
use app\admin\controller\BaseAdminController;
use app\admin\lists\product_source_link\ProductSourceLinkLists;
use app\admin\logic\product_source_link\ProductSourceLinkLogic;
use app\admin\validate\product_source_link\ProductSourceLinkValidate;
use app\common\model\product_source_link\ProductSourceLink;
use app\common\model\product_source_link_info\ProductSourceLinkInfo;
use app\common\model\store_product\StoreProduct;
use app\common\model\warehouse_product\WarehouseProduct;
use app\common\service\xlsx\ProductSourceLinkXsl;
/**
* 商品溯源管理控制器
* Class ProductSourceLinkController
* @package app\admin\controller\product_source_link
*/
class ProductSourceLinkController extends BaseAdminController
{
/**
* @notes 获取商品溯源管理列表
* @author admin
* @date 2025/03/12 10:03
*/
public function lists()
{
return $this->dataLists(new ProductSourceLinkLists());
}
/**
* @notes 添加商品溯源管理
* @author admin
* @date 2025/03/12 10:03
*/
public function add()
{
$params = (new ProductSourceLinkValidate())->post()->goCheck('add');
$result = ProductSourceLinkLogic::add($params);
if (true === $result) {
return $this->success('添加成功', [], 1, 1);
}
return $this->fail(ProductSourceLinkLogic::getError());
}
/**
* @notes 编辑商品溯源管理
* @author admin
* @date 2025/03/12 10:03
*/
public function edit()
{
$params = (new ProductSourceLinkValidate())->post()->goCheck('edit');
$result = ProductSourceLinkLogic::edit($params);
if (true === $result) {
return $this->success('编辑成功', [], 1, 1);
}
return $this->fail(ProductSourceLinkLogic::getError());
}
/**
* @notes 删除商品溯源管理
* @author admin
* @date 2025/03/12 10:03
*/
public function delete()
{
$params = (new ProductSourceLinkValidate())->post()->goCheck('delete');
ProductSourceLinkLogic::delete($params);
return $this->success('删除成功', [], 1, 1);
}
/**
* @notes 获取商品溯源管理详情
* @author admin
* @date 2025/03/12 10:03
*/
public function detail()
{
$params = (new ProductSourceLinkValidate())->goCheck('detail');
$result = ProductSourceLinkLogic::detail($params);
return $this->data($result);
}
public function export()
{
$params = $this->request->get();
$query = ProductSourceLink::field('id,purchase_uid,product_id,warehouse_id');
if (!empty($params['product_name'])) {
$productIds = StoreProduct::where('store_name', 'like', "%{$params['product_name']}%")->column('id');
$query->whereIn('product_id', $productIds);
}
if (!empty($params['purchase_uid'])) {
$query->where('purchase_uid', $params['purchase_uid']);
}
if (!empty($params['warehouse_id'])) {
$query->where('warehouse_id', $params['warehouse_id']);
}
$list = $query->with(['product', 'purchase'])
->field(['id', 'purchase_uid', 'product_id'])
->order(['id' => 'desc'])
->group('purchase_uid,product_id')
->select()
->toArray();
$linkInfos = ProductSourceLinkInfo::whereIn('oid', array_column($list, 'id'))->select()->toArray();
$orderSnList = WarehouseProduct::field('id,code')->whereIn('id', array_unique(array_column($linkInfos, 'link_id')))->select()->toArray();
$orderSnList = reset_index($orderSnList, 'id');
foreach ($list as &$item) {
$item['in_order_no'] = [];
$item['out_order_no'] = [];
$item['in_num'] = 0;
$item['out_num'] = 0;
foreach ($linkInfos as $linkInfo) {
if ($linkInfo['oid'] == $item['id']) {
$orderSnItem = $orderSnList[$linkInfo['link_id']] ?? [];
if ($linkInfo['types'] == ProductSourceLinkInfo::TypeIn) {
if (!empty($orderSnItem)) {
$item['in_order_no'][] = $orderSnItem['code'];
}
$item['in_num'] = bcadd($item['in_num'], $linkInfo['nums'], 2);
} else {
if (!empty($orderSnItem)) {
$item['out_order_no'][] = $orderSnItem['code'];
}
$item['out_num'] = bcadd($item['out_num'], $linkInfo['nums'], 2);
}
}
}
$item['in_order_no'] = !empty($item['in_order_no']) ? implode('', $item['in_order_no']) : '';
$item['out_order_no'] =!empty($item['out_order_no']) ? implode('', $item['out_order_no']) : '';
}
$file_path = (new ProductSourceLinkXsl())->export($list);
return $this->success('导出成功', ['url' => $file_path]);
}
}

View File

@ -0,0 +1,90 @@
<?php
namespace app\admin\controller\product_source_link_info;
use app\admin\controller\BaseAdminController;
use app\admin\lists\product_source_link_info\ProductSourceLinkInfoLists;
use app\admin\logic\product_source_link_info\ProductSourceLinkInfoLogic;
use app\admin\validate\product_source_link_info\ProductSourceLinkInfoValidate;
/**
* 商品溯源详细控制器
* Class ProductSourceLinkInfoController
* @package app\admin\controller\product_source_link_info
*/
class ProductSourceLinkInfoController extends BaseAdminController
{
/**
* @notes 获取商品溯源详细列表
* @author admin
* @date 2025/03/12 10:08
*/
public function lists()
{
return $this->dataLists(new ProductSourceLinkInfoLists());
}
/**
* @notes 添加商品溯源详细
* @author admin
* @date 2025/03/12 10:08
*/
public function add()
{
$params = (new ProductSourceLinkInfoValidate())->post()->goCheck('add');
$result = ProductSourceLinkInfoLogic::add($params);
if ($result) {
return $this->success('添加成功', [], 1, 1);
}
return $this->fail(ProductSourceLinkInfoLogic::getError());
}
/**
* @notes 编辑商品溯源详细
* @author admin
* @date 2025/03/12 10:08
*/
public function edit()
{
$params = (new ProductSourceLinkInfoValidate())->post()->goCheck('edit');
$result = ProductSourceLinkInfoLogic::edit($params);
if (true === $result) {
return $this->success('编辑成功', [], 1, 1);
}
return $this->fail(ProductSourceLinkInfoLogic::getError());
}
/**
* @notes 删除商品溯源详细
* @author admin
* @date 2025/03/12 10:08
*/
public function delete()
{
$params = (new ProductSourceLinkInfoValidate())->post()->goCheck('delete');
ProductSourceLinkInfoLogic::delete($params);
return $this->success('删除成功', [], 1, 1);
}
/**
* @notes 获取商品溯源详细详情
* @author admin
* @date 2025/03/12 10:08
*/
public function detail()
{
$params = (new ProductSourceLinkInfoValidate())->goCheck('detail');
$result = ProductSourceLinkInfoLogic::detail($params);
return $this->data($result);
}
}

View File

@ -91,5 +91,10 @@ class StoreCategoryController extends BaseAdminController
return $this->data($result);
}
public function tree()
{
$result = StoreCategoryLogic::tree();
return $this->data($result);
}
}

View File

@ -11,8 +11,19 @@ use app\admin\validate\store_product\StoreProductValidate;
use app\common\model\store_branch_product\StoreBranchProduct;
use app\common\model\store_product\StoreProduct;
use app\common\model\warehouse_product_storege\WarehouseProductStorege;
use TencentCloud\Common\Credential;
use TencentCloud\Common\Profile\ClientProfile;
use TencentCloud\Common\Profile\HttpProfile;
use TencentCloud\Tiia\V20190529\Models\CreateImageRequest;
use TencentCloud\Tiia\V20190529\Models\SearchImageRequest;
use TencentCloud\Tiia\V20190529\TiiaClient;
use Webman\RedisQueue\Redis;
use app\common\model\product_image\ProductImage;
use app\admin\logic\product_image\ProductImageLogic;
/**
* 商品列表控制器
* Class StoreProductController
@ -21,6 +32,7 @@ use Webman\RedisQueue\Redis;
class StoreProductController extends BaseAdminController
{
public $notNeedLogin = ['upload', 'recognition'];
/**
* @notes 获取商品列表列表
@ -124,6 +136,18 @@ class StoreProductController extends BaseAdminController
return $this->success('复制成功', [], 1, 1);
}
/**
* @notes 复制商品到仓库
* @author likeadmin
* @date 2024/05/31 10:53
*/
public function copyWarehouse()
{
$params = $this->request->post();
StoreProductLogic::copyWarehouse($params);
return $this->success('复制成功', [], 1, 1);
}
/**
* 商品导入到门店
*/
@ -139,4 +163,78 @@ class StoreProductController extends BaseAdminController
return $this->success('删除成功', [], 1, 1);
}
public function upload()
{
$params = $this->request->get();
// $params = [
// 'ProductId' => '1024',
// 'GroupId' => 'default',
// ];
$storeName = StoreProduct::where('id', $params['ProductId'])->value('store_name');
$product_num = ProductImage::where('product_id', $params['ProductId'])->count('id');
$cred = new Credential(getenv('TENCENT_SECRET_ID'), getenv('TENCENT_SECRET_KEY'));
$httpProfile = new HttpProfile();
$httpProfile->setEndpoint("tiia.tencentcloudapi.com");
$clientProfile = new ClientProfile();
$clientProfile->setHttpProfile($httpProfile);
$client = new TiiaClient($cred, "ap-guangzhou", $clientProfile);
$req = new CreateImageRequest();
$file = $this->request->file('file');
$filePath = $file->getRealPath();
$fileName = $file->getuploadName();
$file = file_get_contents($filePath);
// $fileName ="矿泉水7";
// $file = file_get_contents(public_path() . '/' . $fileName. '.jpg');
$ImageParams = [
'GroupId' => $params['GroupId'],
'EntityId' => $params['ProductId'].'_'.$storeName.'_'.intval($product_num+1),
'PicName' => $params['ProductId'].'_'.$fileName,
'ImageBase64' => base64_encode($file)
];
$req->fromJsonString(json_encode($ImageParams));
$resp = $client->CreateImage($req);
$CreateParams = [
'product_id' => $params['ProductId'],
'group_id' => $ImageParams['GroupId'],
'entity_id' => $ImageParams['EntityId'],
'pic_name' => $ImageParams['PicName'],
];
ProductImageLogic::add($CreateParams);
$result = json_decode($resp->toJsonString(), true);
return $this->data($result);
}
public function recognition()
{
$params = $this->request->get();
// $params = [
// 'GroupId' => 'default',
// ];
$cred = new Credential(getenv('TENCENT_SECRET_ID'), getenv('TENCENT_SECRET_KEY'));
$httpProfile = new HttpProfile();
$httpProfile->setEndpoint("tiia.tencentcloudapi.com");
$clientProfile = new ClientProfile();
$clientProfile->setHttpProfile($httpProfile);
$client = new TiiaClient($cred, "ap-guangzhou", $clientProfile);
$req = new SearchImageRequest();
$file = $this->request->file('file');
$filePath = $file->getRealPath();
$file = file_get_contents($filePath);
// $fileName ="鱿鱼";
// $file = file_get_contents(public_path() . '/' . $fileName. '.jpg');
$ImageParams = [
'GroupId' => $params['GroupId'],
'ImageBase64' => base64_encode($file)
];
$req->fromJsonString(json_encode($ImageParams));
$resp = $client->SearchImage($req);
if(!empty($resp->ImageInfos)){
$ids = array_column($resp->ImageInfos,'EntityId');
$data = ProductImage::whereIn('entity_id', $ids)->field('product_id,group_id,entity_id,pic_name')->group(['product_id', 'entity_id'])->select();
$resp->ImageInfos = $data->toArray();
$resp->Count = $data->count('product_id');
}
$result = json_decode($resp->toJsonString(), true);
return $this->data($result);
}
}

View File

@ -5,8 +5,8 @@ namespace app\admin\controller\store_product_price;
use app\admin\controller\BaseAdminController;
use app\admin\lists\store_product_price\StoreProductPriceLists;
use app\admin\logic\store_finance_flow\StoreFinanceFlowLogic;
use app\admin\logic\store_product_price\StoreProductPriceLogic;
use app\admin\service\ProductPriceService;
use app\admin\validate\store_product_price\StoreProductPriceValidate;
@ -115,4 +115,21 @@ class StoreProductPriceController extends BaseAdminController
return $this->data($data);
}
public function getRate(ProductPriceService $productPriceService)
{
$params = $this->request->get();
$productPriceRate = $productPriceService->getProductPriceRate($params['product_id'], true);
return $this->data($productPriceRate);
}
public function create()
{
$params = request()->post();
$result = StoreProductPriceLogic::add($params);
if (true === $result) {
return $this->success('添加成功', [], 1, 1);
}
return $this->fail(StoreProductPriceLogic::getError());
}
}

View File

@ -106,6 +106,7 @@ class WarehouseOrderController extends BaseAdminController
'admin_id' => $this->adminId,
'type' => $type,
'order_type' => 0,
'code' => $code,
];
$storeProduct = StoreProduct::where('id', $arr['id'])->find();
$data['total_price'] = bcmul($arr['stock'], $storeProduct['purchase'], 2);

View File

@ -45,7 +45,7 @@ class ChangeLogLists extends BaseAdminDataLists implements ListsSearchInterface
public function lists(): array
{
return ChangeLog::where($this->searchWhere)
->field(['id', 'admin_id', 'model', 'link_id', 'nums', 'pm', 'url', 'mark'])
->field(['id', 'admin_id', 'model', 'link_id', 'nums', 'pm', 'url', 'mark', 'create_time'])
->limit($this->limitOffset, $this->limitLength)
->order(['id' => 'desc'])
->select()->each(

View File

@ -0,0 +1,89 @@
<?php
namespace app\admin\lists;
use app\common\model\auth\Admin;
use app\common\model\product_source_link_info\ProductSourceLinkInfo;
use app\common\model\PurchaseFunds;
use app\common\lists\ListsSearchInterface;
use app\common\model\user\User;
/**
* PurchaseFunds列表
* Class PurchaseFundsLists
* @package app\admin\lists
*/
class PurchaseFundsLists extends BaseAdminDataLists implements ListsSearchInterface
{
/**
* @notes 设置搜索条件
* @return \string[][]
* @author admin
* @date 2025/03/19 14:59
*/
public function setSearch(): array
{
return [
'=' => ['from_uid', 'approve_uid', 'status'],
];
}
/**
* @notes 获取列表
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author admin
* @date 2025/03/19 14:59
*/
public function lists(): array
{
$query = PurchaseFunds::where($this->searchWhere);
if (!empty($this->params['approve_uid'])) {
$userIds = Admin::where('name', 'like', '%' . $this->params['approve_uid'] . '%')->column('id');
$query->whereIn('approve_uid', $userIds);
}
if (!empty($this->params['order'])) {
$query->order(['id' => 'asc']);
} else {
$query->order(['id' => 'desc']);
}
return $query
->field(['id', 'from_uid', 'approve_uid', 'amount', 'current_amount', 'supply_price', 'status', 'create_time', 'audit_time'])
->limit($this->limitOffset, $this->limitLength)
->select()
->each(function ($item) {
$item['from_name'] = User::where('id', $item['from_uid'])->value('nickname');
$item['approve_name'] = empty($item['approve_uid']) ? '' : Admin::where('id', $item['approve_uid'])->value('name');
$item['status_name'] = $item->getStatusName();
if ($item['current_amount'] < 0) {
$item['status'] = -1;
$item['status_name'] = '已超额';
}
$item['audit_time'] = empty($item['audit_time']) ? '' : date('Y-m-d H:i:s', $item['audit_time']);
$item['supply_price'] = ProductSourceLinkInfo::where('purchase_funds_id', $item['id'])->where('types', ProductSourceLinkInfo::TypeOut)->sum('total_price');
$item['current_profit'] = ProductSourceLinkInfo::where('purchase_funds_id', $item['id'])->where('types', ProductSourceLinkInfo::TypeOrder)->sum('total_price');
})
->toArray();
}
/**
* @notes 获取数量
* @return int
* @author admin
* @date 2025/03/19 14:59
*/
public function count(): int
{
return PurchaseFunds::where($this->searchWhere)->count();
}
}

View File

@ -34,7 +34,7 @@ class BeforehandOrderLists extends BaseAdminDataLists implements ListsSearchInte
public function setSearch(): array
{
return [
'=' => ['store_id', 'paid', 'status', 'order_type', 'admin_id'],
'=' => ['id', 'store_id', 'paid', 'status', 'order_type', 'admin_id'],
'%like' => ['order_id','order_sn'],
'%like%' => ['mark'],
'between_time' => 'create_time'
@ -96,6 +96,7 @@ class BeforehandOrderLists extends BaseAdminDataLists implements ListsSearchInte
->order(['id' => 'desc'])
->select()->each(function ($item)use($export) {
$item['outbound'] = '';
$item['outbound_time'] = '';
$item['order_type_name'] = '';
if ($item->admin_id) {
$item->admin_name = Admin::where(['id' => $item->admin_id])->value('name');
@ -132,6 +133,8 @@ class BeforehandOrderLists extends BaseAdminDataLists implements ListsSearchInte
}
if ($item['outbound_id'] > 0) {
$item->outbound = '已出库|' . $item['outbound_id'];
$outboundTime = WarehouseOrder::where('id', $item['outbound_id'])->value('create_time');
$item->outbound_time = date('Y-m-d H:i:s', $outboundTime);
}
if ($item['store_id'] > 0) {
$item->system_store = SystemStore::where(['id' => $item['store_id']])->value('name');

View File

@ -76,6 +76,10 @@ class BeforehandOrderCartInfoLists extends BaseAdminDataLists implements ListsSe
$this->searchWhere[] = ['product_id', 'in', $ids];
}
}
if (!empty($this->params['store_id'])) {
$orderIds = BeforehandOrder::where('store_id', $this->params['store_id'])->column('id');
$this->searchWhere[] = ['bhoid', 'in', $orderIds];
}
$list = BeforehandOrderCartInfo::where($this->searchWhere)
->field(['id', 'bhoid', 'package', 'store_info', 'marques', 'gross_weight', 'net_weight', 'accept_num', 'after_sales', 'loss', 'uid', 'pay_price', 'is_buyer', 'buyer_uid', 'product_id', 'attr_value_id', 'purchase', 'price', 'total_price', 'cart_num', 'mark','create_time', 'procurement_order_id', 'store_sale'])
->limit($this->limitOffset, $this->limitLength)
@ -137,6 +141,10 @@ class BeforehandOrderCartInfoLists extends BaseAdminDataLists implements ListsSe
*/
public function count(): int
{
if (!empty($this->params['store_id'])) {
$orderIds = BeforehandOrder::where('store_id', $this->params['store_id'])->column('id');
$this->searchWhere[] = ['bhoid', 'in', $orderIds];
}
return BeforehandOrderCartInfo::where($this->searchWhere)->count();
}

View File

@ -33,7 +33,7 @@ class InventoryTransferLists extends BaseAdminDataLists implements ListsSearchIn
public function setSearch(): array
{
return [
'=' => ['type'],
'=' => ['type', 'product_id'],
'between_time' => 'create_time'
];
}
@ -70,7 +70,11 @@ class InventoryTransferLists extends BaseAdminDataLists implements ListsSearchIn
return [];
}
}
return InventoryTransfer::where($this->searchWhere)
$query = InventoryTransfer::where($this->searchWhere);
if (!empty($this->params['warehouse_id'])) {
$query->whereRaw("(one_type=2 and one_id={$this->params['warehouse_id']}) or (two_type=2 and two_id={$this->params['warehouse_id']})");
}
return $query
->field(['id','oid', 'product_id', 'nums', 'one_before_nums', 'one_after_nums','two_before_nums','two_after_nums', 'one_type','two_type', 'one_id', 'two_id', 'create_time'])
->limit($this->limitOffset, $this->limitLength)
->order(['id' => 'desc'])
@ -117,7 +121,11 @@ class InventoryTransferLists extends BaseAdminDataLists implements ListsSearchIn
return 0;
}
} else {
return InventoryTransfer::where($this->searchWhere)->count();
$query = InventoryTransfer::where($this->searchWhere);
if (!empty($this->params['warehouse_id'])) {
$query->whereRaw("(one_type=2 and one_id={$this->params['warehouse_id']}) or (two_type=2 and two_id={$this->params['warehouse_id']})");
}
return $query->count();
}
}

View File

@ -28,7 +28,7 @@ class InventoryTransferOrderLists extends BaseAdminDataLists implements ListsSea
public function setSearch(): array
{
return [
'=' => ['order_id', 'one_type', 'two_type', 'types'],
'=' => ['id', 'order_id', 'one_type', 'two_type', 'types'],
];
}
@ -45,7 +45,7 @@ class InventoryTransferOrderLists extends BaseAdminDataLists implements ListsSea
public function lists(): array
{
return InventoryTransferOrder::where($this->searchWhere)
->field(['id', 'order_id', 'one_id', 'one_type', 'two_id', 'two_type', 'types', 'total_nums', 'total_price','mark'])
->field(['id', 'order_id', 'one_id', 'one_type', 'two_id', 'two_type', 'types', 'total_nums', 'total_price','mark', 'status'])
->limit($this->limitOffset, $this->limitLength)
->order(['id' => 'desc'])
->select()->each(function ($item) {

View File

@ -0,0 +1,65 @@
<?php
namespace app\admin\lists\product_image;
use app\admin\lists\BaseAdminDataLists;
use app\common\model\product_image\ProductImage;
use app\common\lists\ListsSearchInterface;
/**
* 商品图库管理列表
* Class ProductImageLists
* @package app\admin\listsproduct_image
*/
class ProductImageLists extends BaseAdminDataLists implements ListsSearchInterface
{
/**
* @notes 设置搜索条件
* @return \string[][]
* @author admin
* @date 2025/04/14 11:02
*/
public function setSearch(): array
{
return [
'=' => ['product_id', 'entity_id', 'group_id', 'pic_name'],
];
}
/**
* @notes 获取商品图库管理列表
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author admin
* @date 2025/04/14 11:02
*/
public function lists(): array
{
return ProductImage::where($this->searchWhere)
->field(['id', 'product_id', 'entity_id', 'group_id', 'pic_name'])
->limit($this->limitOffset, $this->limitLength)
->order(['id' => 'desc'])
->select()
->toArray();
}
/**
* @notes 获取商品图库管理数量
* @return int
* @author admin
* @date 2025/04/14 11:02
*/
public function count(): int
{
return ProductImage::where($this->searchWhere)->count();
}
}

View File

@ -0,0 +1,81 @@
<?php
namespace app\admin\lists\product_source_link;
use app\admin\lists\BaseAdminDataLists;
use app\common\model\product_source_link\ProductSourceLink;
use app\common\lists\ListsSearchInterface;
use app\common\model\product_source_link_info\ProductSourceLinkInfo;
use app\common\model\store_product\StoreProduct;
use app\common\model\warehouse_product\WarehouseProduct;
/**
* 商品溯源管理列表
* Class ProductSourceLinkLists
* @package app\admin\listsproduct_source_link
*/
class ProductSourceLinkLists extends BaseAdminDataLists implements ListsSearchInterface
{
/**
* @notes 设置搜索条件
* @return \string[][]
* @author admin
* @date 2025/03/12 10:03
*/
public function setSearch(): array
{
return [
'=' => ['purchase_uid', 'product_id', 'warehouse_id'],
];
}
/**
* @notes 获取商品溯源管理列表
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author admin
* @date 2025/03/12 10:03
*/
public function lists(): array
{
$query = ProductSourceLink::where($this->searchWhere);
if (!empty($this->params['product_name'])) {
$productIds = StoreProduct::where('store_name', 'like', "%{$this->params['product_name']}%")->column('id');
$query->whereIn('product_id', $productIds);
}
return $query->with(['product','warehouse','purchase'])
->field(['id', 'purchase_uid', 'product_id','warehouse_id',])
->limit($this->limitOffset, $this->limitLength)
->order(['id' => 'desc'])
->select()
->each(function ($item) {
$item->total_nums = ProductSourceLinkInfo::where('product_id', $item->product_id)->where('oid',$item->id)->where('types',1)->sum('nums');
$item->warehouse_outbound_nums = ProductSourceLinkInfo::where('product_id', $item->product_id)->where('oid',$item->id)->where('types',2)->sum('nums');
})
->toArray();
}
/**
* @notes 获取商品溯源管理数量
* @return int
* @author admin
* @date 2025/03/12 10:03
*/
public function count(): int
{
$query = ProductSourceLink::where($this->searchWhere);
if (!empty($this->params['product_name'])) {
$productIds = StoreProduct::where('store_name', 'like', "%{$this->params['product_name']}%")->column('id');
$query->whereIn('product_id', $productIds);
}
return $query->count();
}
}

View File

@ -0,0 +1,98 @@
<?php
namespace app\admin\lists\product_source_link_info;
use app\admin\lists\BaseAdminDataLists;
use app\common\model\inventory_transfer\InventoryTransfer;
use app\common\model\product_source_link_info\ProductSourceLinkInfo;
use app\common\lists\ListsSearchInterface;
use app\common\model\store_order_cart_info\StoreOrderCartInfo;
use app\common\model\warehouse_product\WarehouseProduct;
/**
* 商品溯源详细列表
* Class ProductSourceLinkInfoLists
* @package app\admin\listsproduct_source_link_info
*/
class ProductSourceLinkInfoLists extends BaseAdminDataLists implements ListsSearchInterface
{
/**
* @notes 设置搜索条件
* @return \string[][]
* @author admin
* @date 2025/03/12 10:08
*/
public function setSearch(): array
{
return [
'=' => ['oid', 'types', 'purchase_funds_id', ]
];
}
/**
* @notes 获取商品溯源详细列表
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author admin
* @date 2025/03/12 10:08
*/
public function lists(): array
{
return ProductSourceLinkInfo::where($this->searchWhere)
->with(['product'])
->limit($this->limitOffset, $this->limitLength)
->order(['id' => 'desc'])
->select()
->each(function ($item) {
$item['route'] = $this->getRoute($item);
$item['type_name'] = $item->getTypeName();
})
->toArray();
}
/**
* @notes 获取商品溯源详细数量
* @return int
* @author admin
* @date 2025/03/12 10:08
*/
public function count(): int
{
return ProductSourceLinkInfo::where($this->searchWhere)->count();
}
public function getRoute($item)
{
if ($item['types'] == ProductSourceLinkInfo::TypeIn) {
$path = '/procure/warehouse_product';
$query = ['id' => $item['link_id']];
} elseif (in_array($item['types'], [ProductSourceLinkInfo::TypeOut, ProductSourceLinkInfo::TypeStoreIn, ProductSourceLinkInfo::TypeStoreOut])) {
$path = '/sales_inventory/outbound_list';
$query = ['id' => $item['link_id']];
} elseif ($item['types'] == ProductSourceLinkInfo::TypeOrder) {
$path = '/order/store_order';
$linkId = StoreOrderCartInfo::where('id', $item['link_id'])->value('oid');
$query = ['id' => $linkId];
} elseif ($item['types'] == ProductSourceLinkInfo::TypeOrderRefund) {
$path = '/order/store_order';
$query = ['id' => $item['link_id']];
} elseif (in_array($item['types'], [ProductSourceLinkInfo::TypeS2W, ProductSourceLinkInfo::TypeS2S, ProductSourceLinkInfo::TypeW2W])) {
$path = '/warehouse/inventory_transfer_order';
$linkId = InventoryTransfer::where('id', $item['link_id'])->value('oid');
$query = ['id' => $linkId];
}
return [
'path' => $path ?? '',
'query' => $query ?? []
];
}
}

View File

@ -32,7 +32,7 @@ class StoreOrderLists extends BaseAdminDataLists implements ListsSearchInterface
public function setSearch(): array
{
return [
'=' => ['store_id', 'pay_type', 'staff_id', 'shipping_type', 'delivery_id', 'paid', 'status', 'is_writeoff', 'is_merge', 'uid'],
'=' => ['id', 'store_id', 'pay_type', 'staff_id', 'shipping_type', 'delivery_id', 'paid', 'status', 'is_writeoff', 'is_merge', 'uid'],
'between_time' => 'create_time',
'%like%' => ['order_id'],
];

View File

@ -54,17 +54,6 @@ class StoreProductLists extends BaseAdminDataLists implements ListsSearchInterfa
*/
public function lists(): array
{
$class_all = $this->request->get('class_all');
if ($class_all) {
//查3级别的
$arr = Cate::where('pid', $class_all)->column('id');
if ($arr) {
$arr2 = Cate::where('pid', 'in', $arr)->column('id');
$this->searchWhere[] = ['cate_id', 'in', array_merge($arr, $arr2)];
} else {
$this->searchWhere[] = ['cate_id', '=', $class_all];
}
}
$is_warehouse = $this->request->get('is_warehouse', 0);
$order_type = $this->request->get('order_type', 0);
$userShip = 0;
@ -82,6 +71,18 @@ class StoreProductLists extends BaseAdminDataLists implements ListsSearchInterfa
$query->where('is_show', 1);
}
}
$class_all = $this->request->get('class_all');
if ($class_all) {
if (count($class_all) == 1) {
$query->where('top_cate_id', $class_all[0]);
} elseif (count($class_all) == 2) {
$query->where(function ($query) use ($class_all) {
$query->where('two_cate_id', $class_all[1])->whereOr('cate_id', $class_all[1]);
});
} else {
$query->where('cate_id', $class_all[2]);
}
}
if (!empty($this->params['activity_zone_form_id'])) {
$exceptIds = ActivityZone::where('form_id', $this->params['activity_zone_form_id'])->column('product_id');
$query->where('is_show', 1)->where('product_type', '<>', 5)->whereNotIn('id', $exceptIds);
@ -97,6 +98,7 @@ class StoreProductLists extends BaseAdminDataLists implements ListsSearchInterfa
$list = $query->limit($this->limitOffset, $this->limitLength)
->order(['id' => 'desc'])
->select()->each(function ($item) use ($is_warehouse, $userShip, $order_type, $is_true) {
$item['price_update_time'] = !empty($item['price_update_time']) ? date('Y-m-d H:i:s', $item['price_update_time']) : '';
$item['product_id'] = $item['id'];
$item['bar_code_two'] = '';
if (in_array($item['unit'], [2, 21])) {
@ -152,11 +154,13 @@ class StoreProductLists extends BaseAdminDataLists implements ListsSearchInterfa
$item['status_msg'] = '下架|不常用|是否有替换';
}
if ($order_type == 2) {
$price = StoreProductGroupPrice::where('group_id', 42)->where('product_id', $item['product_id'])->value('price');
if ($price > 0) {
$item['price'] = $price;
$item['store_name'] = $item['store_name'] . '|活动价';
}
// $price = StoreProductGroupPrice::where('group_id', 42)->where('product_id', $item['product_id'])->value('price');
// if ($price > 0) {
// $item['price'] = $price;
// $item['store_name'] = $item['store_name'] . '|活动价';
// }
$item['price'] = $item['cost'];
$item['store_name'] = $item['store_name'] . '|高级会员价';
}elseif($is_true == true && $userShip>0){
$item['price'] = $item['vip_price'];
$item['store_name'] = $item['store_name'] . '|会员价';
@ -178,21 +182,19 @@ class StoreProductLists extends BaseAdminDataLists implements ListsSearchInterfa
*/
public function count(): int
{
$export = $this->request->get('export');
if ($export == 1) {
$class_all = $this->request->get('class_all');
if ($class_all) {
//查3级别的
$arr = Cate::where('pid', $class_all)->column('id');
if ($arr) {
$arr2 = Cate::where('pid', 'in', $arr)->column('id');
$this->searchWhere[] = ['cate_id', 'in', array_merge($arr, $arr2)];
} else {
$this->searchWhere[] = ['cate_id', '=', $class_all];
}
$query = StoreProduct::where($this->searchWhere);
$class_all = $this->request->get('class_all');
if ($class_all) {
if (count($class_all) == 1) {
$query->where('top_cate_id', $class_all[0]);
} elseif (count($class_all) == 2) {
$query->where(function ($query) use ($class_all) {
$query->where('two_cate_id', $class_all[1])->whereOr('cate_id', $class_all[1]);
});
} else {
$query->where('cate_id', $class_all[2]);
}
}
$query = StoreProduct::where($this->searchWhere);
if (isset($this->params['type_filter'])) {
if ($this->params['type_filter'] == 0) {
$query->where(function ($query) {
@ -230,6 +232,7 @@ class StoreProductLists extends BaseAdminDataLists implements ListsSearchInterfa
{
$data = [
'id' => '商品id',
'image' => '图片',
'store_name' => '商品名称',
'product_type_name' => '商品类型',
'cate_name' => '分类',

View File

@ -4,9 +4,11 @@ namespace app\admin\lists\store_product_price;
use app\admin\lists\BaseAdminDataLists;
use app\admin\service\ProductPriceService;
use app\common\model\store_product_price\StoreProductPrice;
use app\common\lists\ListsSearchInterface;
use app\common\model\store_product\StoreProduct;
use app\common\model\StoreProductPriceList;
use app\common\model\warehouse\Warehouse;
/**
@ -54,7 +56,7 @@ class StoreProductPriceLists extends BaseAdminDataLists implements ListsSearchIn
if (!empty($this->params['end_time'])) {
$this->searchWhere[] = ['create_time', '<=', strtotime($this->params['end_time'])];
}
return StoreProductPrice::where($this->searchWhere)
$list = StoreProductPrice::where($this->searchWhere)
->field(['id','bhoid','offer_id', 'product_id', 'purchase_price', 'purchase_lv', 'purchase', 'cost_lv', 'cost', 'price_lv', 'price', 'vip_lv', 'vip_price', 'price_config', 'status','create_time','mark', 'warehouse_id'])
->limit($this->limitOffset, $this->limitLength)
->order(['id' => 'desc'])
@ -71,6 +73,19 @@ class StoreProductPriceLists extends BaseAdminDataLists implements ListsSearchIn
$item['status_name']=$item['status']==0?"未设置":"已设置";
})
->toArray();
$productIds = array_unique(array_column($list, 'product_id'));
$priceList = StoreProductPriceList::whereIn('product_id', $productIds)->select()->toArray();
$priceList = reset_index($priceList, 'product_id');
$productService = new ProductPriceService();
foreach ($list as &$item) {
$productPrice = $priceList[$item['product_id']] ?? [];
if (empty($productPrice) || $item['status'] == 1) {
continue;
}
$priceArray = $productService->setProductPrice($item['purchase_price'], $productPrice);
$item = array_merge($item, $priceArray);
}
return $list;
}

View File

@ -37,7 +37,7 @@ class WarehouseProductLists extends BaseAdminDataLists implements ListsSearchInt
public function setSearch(): array
{
return [
'=' => ['warehouse_id', 'financial_pm', 'product_id','store_id','oid','supplier_id','is_pay','code'],
'=' => ['id', 'warehouse_id', 'financial_pm', 'product_id','store_id','oid','supplier_id','is_pay','code'],
'between_time' => 'create_time'
];
}
@ -76,9 +76,12 @@ class WarehouseProductLists extends BaseAdminDataLists implements ListsSearchInt
}
$query = WarehouseProduct::where($this->searchWhere);
if (isset($this->params['is_group']) && $this->params['is_group'] == 1) {
$query->group('product_id')->field(['id', 'code','pay_type','oid','admin_id','supplier_id', 'store_id', 'warehouse_id', 'product_id', 'financial_pm', 'batch', 'sum(nums) nums', 'price', 'purchase', 'cost', 'sum(total_price) total_price', 'manufacture', 'expiration_date', 'status', 'mark', 'create_time','is_pay', 'order_type','vip_price']);
$query->group('product_id')->field(['id', 'code','pay_type','oid','admin_id','supplier_id', 'store_id', 'warehouse_id', 'product_id', 'financial_pm', 'batch', 'sum(nums) nums', 'price', 'purchase', 'cost', 'sum(total_price) total_price', 'manufacture', 'expiration_date', 'status', 'mark', 'create_time','is_pay', 'order_type','vip_price', 'delete_time']);
} else {
$query->field(['id', 'code','pay_type','oid','admin_id','supplier_id', 'store_id', 'warehouse_id', 'product_id', 'financial_pm', 'batch', 'nums', 'price', 'purchase', 'cost', 'total_price', 'manufacture', 'expiration_date', 'status', 'mark', 'create_time','is_pay', 'order_type','vip_price']);
$query->field(['id', 'code','pay_type','oid','admin_id','supplier_id', 'store_id', 'warehouse_id', 'product_id', 'financial_pm', 'batch', 'nums', 'price', 'purchase', 'cost', 'total_price', 'manufacture', 'expiration_date', 'status', 'mark', 'create_time','is_pay', 'order_type','vip_price', 'delete_time']);
}
if (!empty($this->params['product_status'])) {
$query->onlyTrashed();
}
return $query
->limit($this->limitOffset, $this->limitLength)
@ -168,10 +171,14 @@ class WarehouseProductLists extends BaseAdminDataLists implements ListsSearchInt
*/
public function count(): int
{
$query = WarehouseProduct::where($this->searchWhere);
if (!empty($this->params['product_status'])) {
$query->onlyTrashed();
}
if ($this->ids) {
return WarehouseProduct::whereIn('id', $this->ids)->where($this->searchWhere)->count();
return $query->whereIn('id', $this->ids)->count();
} else {
return WarehouseProduct::where($this->searchWhere)->count();
return $query->count();
}
}
/**

View File

@ -64,9 +64,14 @@ class WarehouseProductStoregeLists extends BaseAdminDataLists implements ListsSe
*/
public function lists(): array
{
$where = [];
if ($this->request->get('store_name')) {
$this->store_name = $this->request->get('store_name');
$ids = StoreProduct::where('store_name', 'like', '%' . $this->request->get('store_name') . '%')->column('id');
$where[] = ['store_name', 'like', '%' . $this->request->get('store_name') . '%'];
if($this->request->get('class_all')){
$where[] = ['top_cate_id', 'in', $this->request->get('class_all')];
}
$ids = StoreProduct::where($where)->column('id');
if ($ids) {
$this->searchWhere[] = ['product_id', 'in', $ids];
$this->ids = $ids;
@ -84,6 +89,16 @@ class WarehouseProductStoregeLists extends BaseAdminDataLists implements ListsSe
return [];
}
}
if($this->request->get('class_all')){
$where[] = ['top_cate_id', 'in', $this->request->get('class_all')];
}
$ids = StoreProduct::where($where)->column('id');
if ($ids) {
$this->searchWhere[] = ['product_id', 'in', $ids];
$this->ids = $ids;
} else {
return [];
}
return WarehouseProductStorege::where($this->searchWhere)
->field(['id','is_verify','warehouse_id', 'product_id', 'nums', 'price', 'total_price', 'status'])
->limit($this->limitOffset, $this->limitLength)

View File

@ -0,0 +1,163 @@
<?php
namespace app\admin\logic;
use app\admin\logic\delivery_service\DeliveryServiceLogic;
use app\common\model\PurchaseFunds;
use app\common\logic\BaseLogic;
use support\exception\BusinessException;
use think\facade\Db;
/**
* PurchaseFunds逻辑
* Class PurchaseFundsLogic
* @package app\admin\logic
*/
class PurchaseFundsLogic extends BaseLogic
{
/**
* @notes 添加
* @param array $params
* @return bool
* @author admin
* @date 2025/03/19 14:59
*/
public static function add(array $params): bool
{
Db::startTrans();
try {
PurchaseFunds::create([
'from_uid' => $params['from_uid'],
'amount' => $params['amount'],
]);
Db::commit();
return true;
} catch (\Throwable $e) {
Db::rollback();
throw new BusinessException($e->getMessage());
}
}
/**
* @notes 编辑
* @param array $params
* @return bool
* @author admin
* @date 2025/03/19 14:59
*/
public static function edit(array $params): bool
{
Db::startTrans();
try {
PurchaseFunds::where('id', $params['id'])->update([
'from_uid' => $params['from_uid'],
'approve_uid' => $params['approve_uid'],
'amount' => $params['amount'],
'status' => $params['status'],
]);
Db::commit();
return true;
} catch (\Throwable $e) {
Db::rollback();
throw new BusinessException($e->getMessage());
}
}
/**
* @notes 删除
* @param array $params
* @return bool
* @author admin
* @date 2025/03/19 14:59
*/
public static function delete(array $params): bool
{
return PurchaseFunds::destroy($params['id']);
}
/**
* @notes 获取详情
* @param $params
* @return array
* @author admin
* @date 2025/03/19 14:59
*/
public static function detail($params): array
{
return PurchaseFunds::findOrEmpty($params['id'])->toArray();
}
/**
* @notes 审核
* @param array $params
* @return bool
* @author admin
* @date 2025/03/19 14:59
*/
public static function audit(array $params): bool
{
$purchaseFunds = PurchaseFunds::findOrEmpty($params['id']);
if ($purchaseFunds->isEmpty()) {
throw new BusinessException('数据不存在');
}
Db::startTrans();
try {
$attrs = [
'approve_uid' => $params['approve_uid'],
'status' => $params['status'],
'audit_time' => time(),
];
if ($params['status'] == 1) {
$attrs['current_amount'] = $purchaseFunds['amount'];
}
PurchaseFunds::where('id', $params['id'])->update($attrs);
if ($params['status'] == 1) {
DeliveryServiceLogic::addPurchaseFunds($purchaseFunds['from_uid'], $purchaseFunds['amount']);
}
Db::commit();
return true;
} catch (\Throwable $e) {
Db::rollback();
throw new BusinessException($e->getMessage());
}
}
/**
* @notes 补充
* @param array $params
* @return bool
* @author admin
* @date 2025/03/19 14:59
*/
public static function replenish(array $params): bool
{
$purchaseFunds = PurchaseFunds::findOrEmpty($params['id']);
if ($purchaseFunds->isEmpty()) {
throw new BusinessException('数据不存在');
}
Db::startTrans();
try {
PurchaseFunds::where('id', $params['id'])->update([
'amount' => Db::raw('amount+' . $params['replenish_amount']),
'current_amount' => Db::raw('current_amount+' . $params['replenish_amount']),
]);
DeliveryServiceLogic::addPurchaseFunds($purchaseFunds['from_uid'], $params['replenish_amount']);
Db::commit();
return true;
} catch (\Throwable $e) {
Db::rollback();
throw new BusinessException($e->getMessage());
}
}
}

View File

@ -350,8 +350,15 @@ class BeforehandOrderLogic extends BaseLogic
];
if(!empty($params['order_type']) && $params['order_type']>0){
$data['order_type'] = $params['order_type'];
if(!empty($find['warehousing_id'])){
WarehouseOrder::where(['id' => $find['warehousing_id']])->update(['order_type' => $params['order_type']]);
}
if(!empty($find['outbound_id'])){
WarehouseOrder::where(['id' => $find['outbound_id']])->update(['order_type' => $params['order_type']]);
}
}
$find->save($data);
Db::commit();
return true;
} catch (\Throwable $e) {
@ -370,7 +377,6 @@ class BeforehandOrderLogic extends BaseLogic
public static function createOutboundOrder(array $params): bool
{
$warehouse_id = $params['warehouse_id'];
$store_id = $params['store_id'];
$admin_id = $params['admin_id'];
$delivery_time = $params['delivery_time'];
$mark = $params['remark'] ?? '';
@ -384,6 +390,7 @@ class BeforehandOrderLogic extends BaseLogic
if ($order['outbound_id'] > 0) {
throw new BusinessException('该订单已创建出库单');
}
$store_id = $order['store_id'];
$info = BeforehandOrderCartInfo::where('bhoid', $params['bhoid'])->select()->toArray();
$product_column = array_column($info, 'product_id');
$storege_arr=WarehouseProductStorege::where('warehouse_id', $params['warehouse_id'])->where('product_id','in',$product_column)->select();
@ -961,25 +968,14 @@ class BeforehandOrderLogic extends BaseLogic
$v['store_name'] = $find['store_name'];
$v['mark'] = $find['after_sales'];
if (isset($params['type']) && $params['type'] == 2) {
$price = $v['cost'];
$v['pay_price'] = bcmul($price, $v['nums'], 2);
$v['price'] = $v['vip_price']; //出库单价
$v['purchase'] = $v['cost']; //高级会员单,供货价=商户价
} else {
if ($v['vip_price'] > 0) {
$v['pay_price'] = bcmul($v['vip_price'], $v['nums'], 2);
$price = $v['vip_price'];
} else {
$price = StoreProductGroupPrice::where('product_id', $v['product_id'])->where('group_id', $user_ship)->value('price');
if ($price > 0) {
$v['pay_price'] = bcmul($price, $v['nums'], 2);
} else {
$price = $find['cost'];
$v['pay_price'] = bcmul($price, $v['nums'], 2);
}
WarehouseProduct::where('id', $v['id'])->update(['vip_price' => $price]);
}
$v['purchase'] = $v['vip_price'] > 0 ? $v['vip_price'] : $v['price']; //会员单,供货价=会员价
}
$v['purchase'] = $price;
$v['total_price'] = bcmul($v['price'], $v['nums'], 2); //出库总价
$v['pay_price'] = bcmul($v['purchase'], $v['nums'], 2); //供货总价
$v['profit'] = bcsub($v['total_price'], $v['pay_price'], 2);
$total_profit = bcadd($total_profit, $v['profit'], 2);
$pay_price = bcadd($pay_price, $v['pay_price'], 2);

View File

@ -2,11 +2,14 @@
namespace app\admin\logic\beforehand_order_cart_info;
use app\admin\logic\product_source_link\ProductSourceLinkLogic;
use app\admin\logic\purchase_product_offer\PurchaseProductOfferLogic;
use app\admin\logic\warehouse_product\WarehouseProductLogic;
use app\common\model\beforehand_order_cart_info\BeforehandOrderCartInfo;
use app\common\logic\BaseLogic;
use app\common\model\beforehand_order\BeforehandOrder;
use app\common\model\product_source_link\ProductSourceLink;
use app\common\model\product_source_link_info\ProductSourceLinkInfo;
use app\common\model\purchase_product_offer\PurchaseProductOffer;
use app\common\model\store_product\StoreProduct;
use app\common\model\warehouse_order\WarehouseOrder;
@ -79,6 +82,7 @@ class BeforehandOrderCartInfoLogic extends BaseLogic
$datas[$k]['bhoid'] = $bhoid;
$datas[$k]['cart_num'] = $v['nums'];
$datas[$k]['accept_num'] = $v['nums'];
$datas[$k]['purchase'] = $v['prices']??0;
$datas[$k]['price'] = $v['purchase'];
$datas[$k]['total_price'] = $v['total_price'];
$datas[$k]['pay_price'] = $v['total_price'];
@ -290,6 +294,12 @@ class BeforehandOrderCartInfoLogic extends BaseLogic
if (!$result) {
throw new BusinessException('出库失败,预订单更新出错');
}
ProductSourceLink::add([
'purchase_product_offer' => $offer_list,
'types' => ProductSourceLinkInfo::TypeIn,
'buyer_id' => $res['buyer_id'],
'warehouse_id' => $params['warehouse_id'],
]);
Db::commit();
return true;
} catch (\Throwable $e) {
@ -383,13 +393,13 @@ class BeforehandOrderCartInfoLogic extends BaseLogic
throw new BusinessException('请选择入库仓库');
}
$purchaseProductOffer = PurchaseProductOffer::where('id', $params['id'])->find();
if (empty($purchaseProductOffer) || $params['warehouse_num'] == 0) {
if (empty($purchaseProductOffer) || $params['warehouse_num'] == 0 || empty($purchaseProductOffer['total_price'])) {
throw new BusinessException('请先设置采购信息再入库');
}
if ($purchaseProductOffer['is_storage'] == 1) {
throw new BusinessException('商品已入库');
}
$beforehandOrder = BeforehandOrder::where('id', $params['bhoid'])->field('id,order_type,warehousing_id,is_warehousing')->find();
$beforehandOrder = BeforehandOrder::where('id', $params['bhoid'])->field('id,buyer_id,order_type,warehousing_id,is_warehousing')->find();
$completed_amount = PurchaseProductOffer::where(['order_id' => $params['bhoid'], 'pay_type' => 1, 'is_storage' => 1])->sum('total_price');
$outstanding_amount = PurchaseProductOffer::where(['order_id' => $params['bhoid'], 'pay_type' => 2, 'is_storage' => 1])->sum('total_price');
@ -435,10 +445,14 @@ class BeforehandOrderCartInfoLogic extends BaseLogic
$data['purchase'] = $purchaseProductOffer['price'];
$data['total_price'] = $purchaseProductOffer['total_price'];
$data['financial_pm'] = 1;
$data['buyer_id'] = $beforehandOrder['buyer_id'];
$data['buyer_nums'] = $data['nums'];
$data['price'] = $data['purchase'];
$data['manufacture'] = $purchaseProductOffer['manufacture'] > 0 ? date('Y-m-d H:i:s', $purchaseProductOffer['manufacture']) : '';
$data['expiration_date'] = $purchaseProductOffer['expiration_date'] > 0 ? date('Y-m-d H:i:s', $purchaseProductOffer['expiration_date']) : '';
$data['purchase_funds_id'] = $params['purchase_funds_id'];
if ($data['nums'] > 0) {
WarehouseProductLogic::add($data, 1, $params['admin_id']);
$warehouseProduct = WarehouseProductLogic::add($data, 1, $params['admin_id']);
}
$offerUpdate = ['price' => $purchaseProductOffer['price'], 'status' => 1, 'is_storage' => 1, 'warehouse_num' => $params['warehouse_num']];
$offerResult = PurchaseProductOffer::where('id', $purchaseProductOffer['id'])->where('is_storage', 0)->update($offerUpdate);
@ -459,9 +473,8 @@ class BeforehandOrderCartInfoLogic extends BaseLogic
$product = StoreProduct::where('id', $purchaseProductOffer['product_id'])->withTrashed()->field('id,store_name,top_cate_id,two_cate_id,cate_id')->find();
if (!in_array($beforehandOrder['order_type'], [6, 9])) {
PurchaseProductOfferLogic::setProductPrice($purchaseProductOffer, $product, $params['warehouse_id']);
PurchaseProductOfferLogic::setProductPrice($purchaseProductOffer, $product, $params['warehouse_id'], $warehouseProduct->id ?? 0);
}
Db::commit();
return true;
} catch (\Throwable $e) {

View File

@ -96,4 +96,30 @@ class DeliveryServiceLogic extends BaseLogic
{
return DeliveryService::findOrEmpty($params['id'])->toArray();
}
public static function addPurchaseFunds($uid, $amount)
{
$model = DeliveryService::where('uid', $uid)->findOrEmpty();
if (!$model->isEmpty()) {
$model->purchase_funds_total = bcadd($model->purchase_funds_total, $amount, 2);
$model->current_purchase_funds = bcadd($model->current_purchase_funds, $amount, 2);
$model->save();
}
}
/**
* 扣减采购人员资金
* @param $uid
* @param $amount
* @return void
*/
public static function subPurchaseFunds($uid, $amount)
{
$model = DeliveryService::where('uid', $uid)->findOrEmpty();
if (!$model->isEmpty()) {
$model->current_purchase_funds = bcsub($model->current_purchase_funds, $amount, 2);
$model->save();
}
}
}

View File

@ -4,10 +4,12 @@ namespace app\admin\logic\inventory_transfer;
use app\admin\logic\warehouse_product\WarehouseProductLogic;
use app\common\model\inventory_transfer\InventoryTransfer;
use app\admin\logic\inventory_transfer_order\InventoryTransferOrderLogic;
use app\common\logic\BaseLogic;
use app\common\model\store_branch_product\StoreBranchProduct;
use app\common\model\store_product\StoreProduct;
use app\common\model\warehouse_product_storege\WarehouseProductStorege;
use app\common\model\inventory_transfer_order\InventoryTransferOrder;
use support\exception\BusinessException;
use think\facade\Db;
@ -28,9 +30,62 @@ class InventoryTransferLogic extends BaseLogic
* @author admin
* @date 2024/08/13 16:18
*/
public static function add(array $params,$admin_id=0): bool
public static function add(array $params, $admin_id = 0)
{
return true;
$find = InventoryTransferOrder::where('id', $params['oid'])->find()->toArray();
if (empty($params['product_arr'])) {
throw new BusinessException('请选择商品');
}
$productIds = array_column($params['product_arr'], 'id');
if ($find['one_type'] == 1) {
$outProducts = StoreBranchProduct::whereIn('product_id', $productIds)->where('store_id', $find['one_id'])->field('id,product_id,stock')->select()->toArray();
} else {
$outProducts = WarehouseProductStorege::whereIn('product_id', $productIds)->where('warehouse_id', $find['one_id'])->field('id,product_id,nums stock')->select()->toArray();
}
$outProducts = reset_index($outProducts, 'product_id');
if ($find['two_type'] == 1) {
$inProducts = StoreBranchProduct::whereIn('product_id', $productIds)->where('store_id', $find['two_id'])->field('id,product_id,stock')->select()->toArray();
} else {
$inProducts = WarehouseProductStorege::whereIn('product_id', $productIds)->where('warehouse_id', $find['two_id'])->field('id,product_id,nums stock')->select()->toArray();
}
$inProducts = reset_index($inProducts, 'product_id');
$insert = [];
Db::startTrans();
try {
$insert = [];
foreach ($params['product_arr'] as $v) {
$outProduct = !empty($outProducts[$v['id']]) ? $outProducts[$v['id']] : ['stock' => 0, 'id' => 0, 'product_id' => $v['id']];
$inProduct = !empty($inProducts[$v['id']]) ? $inProducts[$v['id']] : ['stock' => 0, 'id' => 0, 'product_id' => $v['id']];
if ($outProduct['stock'] < $v['nums']) {
throw new BusinessException("出库商品库存不足 {$outProduct['product_id']} 调拨数量不能大于当前仓库库存");
continue;
}
$insert[] = [
'oid' => $find['id'],
'product_id' => $v['id'],
'nums' => $v['nums'],
'remark' => $v['remark'],
'one_before_nums' => $outProduct['stock'],
'one_after_nums' => bcsub($outProduct['stock'], $v['nums']),
'two_before_nums' => $inProduct['stock'],
'two_after_nums' => bcadd($inProduct['stock'], $v['nums']),
'one_type' => $find['one_type'],
'two_type' => $find['two_type'],
'one_id' => $find['one_id'],
'two_id' => $find['two_id'],
'create_time' => time(),
];
}
InventoryTransfer::insertAll($insert);
if ($find['two_type'] == 1 && $find['status'] == 1) {
InventoryTransferOrderLogic::audit($find, $insert, $admin_id);
}
Db::commit();
return true;
} catch (\Throwable $e) {
Db::rollback();
throw new BusinessException($e->getMessage());
}
}
/**

View File

@ -3,6 +3,7 @@
namespace app\admin\logic\inventory_transfer_order;
use app\admin\logic\product_source_link_info\ProductSourceLinkInfoLogic;
use app\common\model\inventory_transfer_order\InventoryTransferOrder;
use app\common\logic\BaseLogic;
use app\common\model\inventory_transfer\InventoryTransfer;
@ -31,9 +32,9 @@ class InventoryTransferOrderLogic extends BaseLogic
* @author admin
* @date 2025/01/24 09:59
*/
public static function add(array $params,$admin_id): bool
public static function add(array $params, $admin_id): bool
{
$types=$params['types']??0;
$types = $params['types'] ?? 0;
if (empty($params['product_arr'])) {
throw new BusinessException('请选择商品');
}
@ -64,6 +65,7 @@ class InventoryTransferOrderLogic extends BaseLogic
$insert[] = [
'product_id' => $v['product_id'],
'nums' => $v['nums'],
'remark' => $v['remark'],
'one_before_nums' => $outProduct['stock'],
'one_after_nums' => bcsub($outProduct['stock'], $v['nums']),
'two_before_nums' => $inProduct['stock'],
@ -75,61 +77,24 @@ class InventoryTransferOrderLogic extends BaseLogic
'create_time' => time(),
];
}
$order=InventoryTransferOrder::create([
$order = InventoryTransferOrder::create([
'order_id' => getNewOrderId('DB'),
'one_type' => $params['one_type'],
'two_type' => $params['two_type'],
'one_id' => $params['one_id'],
'two_id' => $params['two_id'],
'types' => $types,
'mark' => $params['mark']??'',
'mark' => $params['mark'] ?? '',
'status' => ($params['two_type'] == 2 && $types == 0) ? 0 : 1,
]);
foreach ($insert as $k => $v) {
$insert[$k]['oid'] = $order['id'];
}
InventoryTransfer::insertAll($insert);
if($types==1){
Db::commit();
return true;
}
foreach ($insert as $v) {
if($params['one_type']==1){
$find=StoreBranchProduct::where('product_id', $v['product_id'])->where('store_id', $params['one_id'])->find();
$find->save(['stock' =>bcsub( $find['stock'],$v['nums'],2)]);
SqlChannelLog('StoreBranchProduct', $find['id'], $v['nums'], -1, Request()->url(),$admin_id);
} elseif ($params['one_type'] == 2) {
$find=WarehouseProductStorege::where('product_id', $v['product_id'])->where('warehouse_id', $params['one_id'])->find();
$find->save(['nums' =>bcsub( $find['nums'],$v['nums'],2)]);
SqlChannelLog('WarehouseProductStorege', $find['id'], $v['nums'], -1, Request()->url(),$admin_id);
}
if($params['two_type']==1){
$find=StoreBranchProduct::where('product_id', $v['product_id'])->where('store_id', $params['two_id'])->find();
if (empty($find)) {
$storeProduct = StoreProduct::field('top_cate_id,two_cate_id,cate_id,store_name,image,price,vip_price,cost,purchase,keyword,bar_code,store_info,rose,product_type,unit,batch,store_batch,label_id,is_lack,manufacturer_information')->where('id', $v['product_id'])->find()->toArray();
$find = new StoreBranchProduct();
$find->product_id = $v['product_id'];
$find->store_id = $params['two_id'];
$find->stock = $v['nums'];
$find->setAttrs($storeProduct);
$find->save();
} else {
$find->save(['stock' =>bcadd( $find['stock'],$v['nums'],2)]);
}
SqlChannelLog('StoreBranchProduct', $find['id'], $v['nums'], 1, Request()->url(),$admin_id);
} elseif ($params['two_type'] == 2) {
$find=WarehouseProductStorege::where('product_id', $v['product_id'])->where('warehouse_id', $params['two_id'])->find();
if (empty($find)) {
$find = new WarehouseProductStorege();
$find->warehouse_id = $params['two_id'];
$find->product_id = $v['product_id'];
$find->nums = $v['nums'];
$find->save();
} else {
$find->save(['nums' =>bcadd( $find['nums'],$v['nums'],2)]);
}
SqlChannelLog('WarehouseProductStorege', $find['id'], $v['nums'], 1, Request()->url(),$admin_id);
}
if ($types == 0 && $params['two_type'] == 1) {
self::audit($params, $insert, $admin_id);
}
Db::commit();
return true;
} catch (\Throwable $e) {
@ -138,6 +103,59 @@ class InventoryTransferOrderLogic extends BaseLogic
}
}
public static function audit($order = null, $products = null, $admin_id = 0)
{
if (empty($products)) {
$products = InventoryTransfer::where('oid', $order['id'])->select()->toArray();
}
foreach ($products as $v) {
if ($order['one_type'] == 1) {
$find = StoreBranchProduct::where('product_id', $v['product_id'])->where('store_id', $order['one_id'])->find();
$find->save(['stock' => bcsub($find['stock'], $v['nums'], 2)]);
SqlChannelLog('StoreBranchProduct', $find['id'], $v['nums'], -1, Request()->url(), $admin_id);
} elseif ($order['one_type'] == 2) {
$find = WarehouseProductStorege::where('product_id', $v['product_id'])->where('warehouse_id', $order['one_id'])->find();
$find->save(['nums' => bcsub($find['nums'], $v['nums'], 2)]);
SqlChannelLog('WarehouseProductStorege', $find['id'], $v['nums'], -1, Request()->url(), $admin_id);
}
if ($order['two_type'] == 1) {
$find = StoreBranchProduct::where('product_id', $v['product_id'])->where('store_id', $order['two_id'])->find();
if (empty($find)) {
$storeProduct = StoreProduct::field('top_cate_id,two_cate_id,cate_id,store_name,image,price,vip_price,cost,purchase,keyword,bar_code,store_info,rose,product_type,unit,batch,store_batch,label_id,is_lack,manufacturer_information')->where('id', $v['product_id'])->find()->toArray();
$find = new StoreBranchProduct();
$find->product_id = $v['product_id'];
$find->store_id = $order['two_id'];
$find->stock = $v['nums'];
$find->setAttrs($storeProduct);
$find->save();
} else {
$find->save(['stock' => bcadd($find['stock'], $v['nums'], 2)]);
}
SqlChannelLog('StoreBranchProduct', $find['id'], $v['nums'], 1, Request()->url(), $admin_id);
} elseif ($order['two_type'] == 2) {
$find = WarehouseProductStorege::where('product_id', $v['product_id'])->where('warehouse_id', $order['two_id'])->find();
if (empty($find)) {
$find = new WarehouseProductStorege();
$find->warehouse_id = $order['two_id'];
$find->product_id = $v['product_id'];
$find->nums = $v['nums'];
$find->save();
} else {
$find->save(['nums' => bcadd($find['nums'], $v['nums'], 2)]);
}
SqlChannelLog('WarehouseProductStorege', $find['id'], $v['nums'], 1, Request()->url(), $admin_id);
}
InventoryTransferOrder::where('id', $order['id'])->update(['status' => 1]);
$productSourceLinkInfoLogic = new ProductSourceLinkInfoLogic();
$productSourceLinkInfoLogic->setInfo([
'oid' => $v['oid'],
'product_id' => $v['product_id'],
]);
$productSourceLinkInfoLogic->transfer();
}
}
/**
* @notes 编辑商品调拨订单
@ -192,28 +210,28 @@ class InventoryTransferOrderLogic extends BaseLogic
*/
public static function detail($params): array
{
$data= InventoryTransferOrder::findOrEmpty($params['id']);
$type_name='';
if($data->one_type==1){
$data->one_name=SystemStore::where('id',$data->one_id)->value('name');
$type_name='门店转';
}else{
$data->one_name=Warehouse::where('id',$data->one_id)->value('name');
$type_name='仓库转';
$data = InventoryTransferOrder::findOrEmpty($params['id']);
$type_name = '';
if ($data->one_type == 1) {
$data->one_name = SystemStore::where('id', $data->one_id)->value('name');
$type_name = '门店转';
} else {
$data->one_name = Warehouse::where('id', $data->one_id)->value('name');
$type_name = '仓库转';
}
if($data->two_type==1){
$type_name.='门店';
$data->two_name=SystemStore::where('id',$data->two_id)->value('name');
}else{
$type_name.='仓库';
$data->two_name=Warehouse::where('id',$data->two_id)->value('name');
if ($data->two_type == 1) {
$type_name .= '门店';
$data->two_name = SystemStore::where('id', $data->two_id)->value('name');
} else {
$type_name .= '仓库';
$data->two_name = Warehouse::where('id', $data->two_id)->value('name');
}
$data->type_name=$type_name;
$data['product_list']=InventoryTransfer::where('oid',$params['id'])->select()->each(function ($item) {
$find= StoreProduct::where('id',$item->product_id)->withTrashed()->field('store_name')->find();
$item->store_name=$find['store_name'];
$data->type_name = $type_name;
$data['product_list'] = InventoryTransfer::where('oid', $params['id'])->select()->each(function ($item) {
$find = StoreProduct::where('id', $item->product_id)->withTrashed()->field('store_name')->find();
$item->store_name = $find['store_name'] ?? '';
})
->toArray();
->toArray();
return $data->toArray();
}
}
}

View File

@ -0,0 +1,102 @@
<?php
namespace app\admin\logic\product_image;
use app\common\model\product_image\ProductImage;
use app\common\logic\BaseLogic;
use support\exception\BusinessException;
use think\facade\Db;
/**
* 商品图库管理逻辑
* Class ProductImageLogic
* @package app\admin\logic\product_image
*/
class ProductImageLogic extends BaseLogic
{
/**
* @notes 添加商品图库管理
* @param array $params
* @return bool
* @author admin
* @date 2025/04/14 11:02
*/
public static function add(array $params): bool
{
Db::startTrans();
try {
ProductImage::create([
'product_id' => $params['product_id'],
'entity_id' => $params['entity_id'],
'group_id' => $params['group_id'],
'pic_name' => $params['pic_name'],
'create_time' => time(),
'update_time' => time(),
]);
Db::commit();
return true;
} catch (\Throwable $e) {
Db::rollback();
throw new BusinessException($e->getMessage());
}
}
/**
* @notes 编辑商品图库管理
* @param array $params
* @return bool
* @author admin
* @date 2025/04/14 11:02
*/
public static function edit(array $params): bool
{
Db::startTrans();
try {
ProductImage::where('id', $params['id'])->update([
'product_id' => $params['product_id'],
'entity_id' => $params['entity_id'],
'group_id' => $params['group_id'],
'pic_name' => $params['pic_name'],
]);
Db::commit();
return true;
} catch (\Throwable $e) {
Db::rollback();
throw new BusinessException($e->getMessage());
}
}
/**
* @notes 删除商品图库管理
* @param array $params
* @return bool
* @author admin
* @date 2025/04/14 11:02
*/
public static function delete(array $params): bool
{
return ProductImage::destroy($params['id']);
}
/**
* @notes 获取商品图库管理详情
* @param $params
* @return array
* @author admin
* @date 2025/04/14 11:02
*/
public static function detail($params): array
{
return ProductImage::findOrEmpty($params['id'])->toArray();
}
}

View File

@ -0,0 +1,118 @@
<?php
namespace app\admin\logic\product_source_link;
use app\admin\logic\product_source_link_info\ProductSourceLinkInfoLogic;
use app\admin\service\ProductPriceService;
use app\common\model\product_source_link\ProductSourceLink;
use app\common\logic\BaseLogic;
use app\common\model\product_source_link_info\ProductSourceLinkInfo;
use support\exception\BusinessException;
use think\facade\Db;
/**
* 商品溯源管理逻辑
* Class ProductSourceLinkLogic
* @package app\admin\logic\product_source_link
*/
class ProductSourceLinkLogic extends BaseLogic
{
/**
* @notes 添加商品溯源管理
* @param array $info
* @return bool
* @author admin
* @date 2025/03/12 10:03
*/
public static function add(array $info): bool
{
foreach ($info['purchase_product_offer'] as $offer) {
$model = ProductSourceLink::where('product_id', $offer['product_id'])->where('purchase_uid', $info['buyer_id'])->where('warehouse_id', $info['warehouse_id'])->find();
if (empty($model)) {
$model = new ProductSourceLink();
$model->product_id = $offer['product_id'];
$model->purchase_uid = $info['buyer_id'];
$model->warehouse_id = $info['warehouse_id'];
$model->save();
}
$attrs = [
'oid' => $model['id'],
'product_id' => $offer['product_id'],
'warehouse_id' => $info['warehouse_id'],
'nums' => $offer['buyer_nums'],
'current_nums' => $offer['buyer_nums'],
'types' => $info['types'],
'link_id' => $info['link_id'],
'price' => $offer['price'],
'total_price' => $offer['total_price'],
'purchase_funds_id' => $offer['purchase_funds_id'] ?? 0,
];
if ($attrs['types'] == ProductSourceLinkInfo::TypeIn) {
// 商品入库,记录采购总价和供货总价
$priceRate = (new ProductPriceService())->getProductPriceRate($offer['product_id']);
$attrs['purchase_price'] = $offer['total_price'];
$rate = bcdiv($priceRate['supply_rate'], 100, 2);
$attrs['supply_price'] = bcmul(bcmul($offer['price'], $rate, 2), $offer['nums'], 2);
}
ProductSourceLinkInfoLogic::add($attrs);
}
return true;
}
/**
* @notes 编辑商品溯源管理
* @param array $params
* @return bool
* @author admin
* @date 2025/03/12 10:03
*/
public static function edit(array $params): bool
{
Db::startTrans();
try {
ProductSourceLink::where('id', $params['id'])->update([
'purchase_uid' => $params['purchase_uid'],
'product_id' => $params['product_id'],
'warehouse_id' => $params['warehouse_id'],
]);
Db::commit();
return true;
} catch (\Throwable $e) {
Db::rollback();
throw new BusinessException($e->getMessage());
}
}
/**
* @notes 删除商品溯源管理
* @param array $params
* @return bool
* @author admin
* @date 2025/03/12 10:03
*/
public static function delete(array $params): bool
{
return ProductSourceLink::destroy($params['id']);
}
/**
* @notes 获取商品溯源管理详情
* @param $params
* @return array
* @author admin
* @date 2025/03/12 10:03
*/
public static function detail($params): array
{
return ProductSourceLink::findOrEmpty($params['id'])->toArray();
}
}

View File

@ -0,0 +1,544 @@
<?php
namespace app\admin\logic\product_source_link_info;
use app\admin\service\ProductPriceService;
use app\common\model\inventory_transfer\InventoryTransfer;
use app\common\model\product_source_link\ProductSourceLink;
use app\common\model\product_source_link_info\ProductSourceLinkInfo;
use app\common\logic\BaseLogic;
use support\exception\BusinessException;
use support\Log;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
/**
* 商品溯源详细逻辑
* Class ProductSourceLinkInfoLogic
* @package app\admin\logic\product_source_link_info
*/
class ProductSourceLinkInfoLogic extends BaseLogic
{
public $purchaseProductOffer = []; // 采购商品数据
public $orderProduct = []; // 订单商品数据
public $warehouseProduct = []; // 出入库商品数据
public $storeProductPrice = []; // 商品改价数据
public $info = [
'warehouse_id' => 0,
'buyer_id' => 0,
'types' => 0,
'link_id' => 0,
'is_store_order' => 0,
'store_id' => 0,
'create_time' => 0,
'product_id' => 0,
'nums' => 0,
'add_nums' => 0,
'oid' => 0,
];
public function setInfo($info)
{
$this->info = array_merge($this->info, $info);
}
/**
* @notes 添加商品溯源详细
* @param array $params
* @return ProductSourceLinkInfo
* @author admin
* @date 2025/03/12 10:08
*/
public static function add(array $params)
{
$model = new ProductSourceLinkInfo();
$model->setAttrs($params);
$model->save();
return $model;
}
/**
* @notes 编辑商品溯源详细
* @param array $params
* @return bool
* @author admin
* @date 2025/03/12 10:08
*/
public static function edit(array $params): bool
{
Db::startTrans();
try {
ProductSourceLinkInfo::where('id', $params['id'])->update([
'oid' => $params['oid'],
'product_id' => $params['product_id'],
'nums' => $params['nums'],
'types' => $params['types'],
'link_id' => $params['link_id'],
'total_price' => $params['total_price']
]);
Db::commit();
return true;
} catch (\Throwable $e) {
Db::rollback();
throw new BusinessException($e->getMessage());
}
}
/**
* @notes 删除商品溯源详细
* @param array $params
* @return bool
* @author admin
* @date 2025/03/12 10:08
*/
public static function delete(array $params): bool
{
return ProductSourceLinkInfo::destroy($params['id']);
}
/**
* @notes 获取商品溯源详细详情
* @param $params
* @return array
* @author admin
* @date 2025/03/12 10:08
*/
public static function detail($params): array
{
return ProductSourceLinkInfo::findOrEmpty($params['id'])->toArray();
}
/**
* @notes 仓库入库
* @return bool
*/
public function putInStorage(): bool
{
if (empty($this->purchaseProductOffer)) {
return false;
}
try {
$model = ProductSourceLink::where('product_id', $this->purchaseProductOffer['product_id'])->where('purchase_uid', $this->info['buyer_id'])->where('warehouse_id', $this->info['warehouse_id'])->find();
if (empty($model)) {
$model = new ProductSourceLink();
$model->product_id = $this->purchaseProductOffer['product_id'];
$model->purchase_uid = $this->info['buyer_id'];
$model->warehouse_id = $this->info['warehouse_id'];
$model->save();
}
$attrs = [
'oid' => $model['id'],
'product_id' => $this->purchaseProductOffer['product_id'],
'warehouse_id' => $this->info['warehouse_id'],
'nums' => $this->purchaseProductOffer['buyer_nums'],
'current_nums' => $this->purchaseProductOffer['buyer_nums'],
'types' => $this->info['types'],
'link_id' => $this->info['link_id'],
'price' => $this->purchaseProductOffer['price'],
'total_price' => $this->purchaseProductOffer['total_price'],
'purchase_funds_id' => $this->purchaseProductOffer['purchase_funds_id'] ?? 0,
];
if ($attrs['types'] == ProductSourceLinkInfo::TypeIn) {
// 商品入库,记录采购总价和供货总价
$priceRate = (new ProductPriceService())->getProductPriceRate($this->purchaseProductOffer['product_id']);
$attrs['purchase_price'] = $this->purchaseProductOffer['total_price'];
$rate = bcdiv($priceRate['supply_rate'], 100, 2);
$attrs['supply_price'] = bcmul(bcmul($this->purchaseProductOffer['price'], $rate, 2), $this->purchaseProductOffer['nums'], 2);
}
ProductSourceLinkInfoLogic::add($attrs);
return true;
} catch (BusinessException $e) {
Log::error('商品入库溯源信息保存失败' . $e->getMessage());
}
return false;
}
/**
* 仓库出库
* @return true
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function outbound()
{
$query = ProductSourceLinkInfo::where('product_id', $this->warehouseProduct['product_id'])->where('current_nums', '>', 0);
$query->whereIn('types', [ProductSourceLinkInfo::TypeIn, ProductSourceLinkInfo::TypeS2W, ProductSourceLinkInfo::TypeW2W]);
$productSourceLinkInfo = $query->select()->toArray();
$needNum = $this->warehouseProduct['nums'];
return $this->putOutStorage($productSourceLinkInfo, $needNum);
}
/**
* 订单销售出库
* @return true
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function sale()
{
$query = ProductSourceLinkInfo::where('product_id', $this->orderProduct['product_id'])->where('current_nums', '>', 0);
$query->where('store_id', $this->info['store_id'])->whereIn('types', [ProductSourceLinkInfo::TypeStoreIn, ProductSourceLinkInfo::TypeS2S]);
$productSourceLinkInfo = $query->select()->toArray();
$needNum = $this->orderProduct['nums'];
return $this->putOutStorage($productSourceLinkInfo, $needNum);
}
/**
* 更新入库单的数量和价格
* @return void
* @throws DbException
*/
public function updateInStorageNum()
{
$data = ProductSourceLinkInfo::where('link_id', $this->info['link_id'])->where('types', ProductSourceLinkInfo::TypeIn)->findOrEmpty()->toArray();
$attrs['nums'] = bcadd($data['nums'], $this->info['add_nums'], 2);
$attrs['current_nums'] = bcadd($data['current_nums'], $this->info['add_nums'], 2);
$attrs['total_price'] = bcmul($this->info['nums'], $data['price'], 2);
$attrs['supply_price'] = bcmul($this->info['nums'], bcdiv($data['supply_price'], $data['nums'], 2), 2);
ProductSourceLinkInfo::where('id', $data['id'])->update($attrs);
}
/**
* 更新出库单的数量和价格
* @return void
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function updateOutboundNum()
{
if ($this->info['add_nums'] < 0) {
$list = ProductSourceLinkInfo::where('link_id', $this->info['link_id'])->where('types', ProductSourceLinkInfo::TypeOut)->order('id desc')->select()->toArray();
if (empty($list)) {
return;
}
$rollbackNum = abs($this->info['add_nums']);
$update = [];
foreach ($list as $item) {
if ($item['nums'] > $rollbackNum) {
$update = $this->setUpdate($item, $rollbackNum, $update);
break;
} else {
$update = $this->setUpdate($item, $item['nums'], $update);
}
$rollbackNum = bcsub($rollbackNum, $item['nums'], 2);
}
(new ProductSourceLinkInfo())->saveAll($update);
} else {
$data = ProductSourceLinkInfo::where('link_id', $this->info['link_id'])->where('types', ProductSourceLinkInfo::TypeOut)->findOrEmpty()->toArray();
if (empty($data)) {
return;
}
$update = $this->setUpdate($data, -$this->info['add_nums'], []);
(new ProductSourceLinkInfo())->saveAll($update);
}
}
/**
* 根据linkId删除
* @param $linkId
* @param $types
* @return void
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function deleteByLinkId($linkId, $types)
{
$list = ProductSourceLinkInfo::where('link_id', $linkId)->where('types', $types)->select()->toArray();
$update = [];
foreach ($list as $item) {
if ($types == ProductSourceLinkInfo::TypeOut && $item['from_id'] > 0) {
$update[] = [
'id' => $item['from_id'],
'current_nums' => Db::raw("current_nums+{$item['nums']}"),
];
}
$update[] = [
'id' => $item['id'],
'delete_time' => time(),
];
}
(new ProductSourceLinkInfo())->saveAll($update);
}
private function getInsertAndUpdate($update, $insert, $currentNum, $item, $needNum)
{
$time = time();
$update[] = [
'id' => $item['id'],
'current_nums' => $currentNum,
'update_time' => $time,
];
$exist = ProductSourceLinkInfo::field('id,from_id,nums,current_nums')->where('link_id', $this->info['link_id'])->where('types', ProductSourceLinkInfo::TypeOut)->findOrEmpty()->toArray();
if (!empty($exist) && $exist['from_id'] == $item['id']) {
$itemNums = bcadd($exist['nums'], $needNum, 2);
$itemCurrentNums = bcadd($exist['current_nums'], $needNum, 2);
$update[] = [
'id' => $exist['id'],
'nums' => $itemNums,
'current_nums' => $itemCurrentNums,
'total_price' => bcmul($item['price'], $itemNums, 2),
'update_time' => $time,
];
} else {
$insertItem = [
'product_id' => $item['product_id'],
'warehouse_id' => $this->info['warehouse_id'],
'store_id' => $this->info['store_id'],
'oid' => $item['oid'],
'types' => empty($this->info['types']) ? ProductSourceLinkInfo::TypeOut : $this->info['types'],
'link_id' => $this->info['link_id'],
'from_id' => $item['id'],
'nums' => $needNum,
'current_nums' => $needNum,
'price' => $item['price'],
'total_price' => bcmul($item['price'], $needNum, 2),
'purchase_funds_id' => $item['purchase_funds_id'],
'create_time' => !empty($this->info['create_time']) ? $this->info['create_time'] : $time,
'update_time' => $time,
'trace_info' => empty($item['trace_info']) ? $item['id'] : $item['trace_info'] . ',' . $item['id'],
];
if ($insertItem['types'] == ProductSourceLinkInfo::TypeOut) {
// 商品出库,价格为供货价,总价为供货总价
$insertItem['price'] = bcdiv($item['supply_price'], $item['nums'], 2);
$insertItem['total_price'] = bcmul($insertItem['price'], $insertItem['nums'], 2);
} elseif ($insertItem['types'] == ProductSourceLinkInfo::TypeOrder) {
// 商品订单出库,价格为销售价,总价为销售总价
$insertItem['price'] = $this->orderProduct['price'];
$insertItem['total_price'] = bcmul($insertItem['price'], $insertItem['nums'], 2);
$insertItem['supply_price'] = bcmul($this->orderProduct['supply_price'], $insertItem['nums'], 2);
}
$insert[] = $insertItem;
}
return [$update, $insert];
}
/**
* 更新商品溯源供货价
* @return void
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function updateSupplyPrice()
{
$productSourceLinkInfo = ProductSourceLinkInfo::where('product_id', $this->storeProductPrice['product_id'])
->where('link_id', $this->storeProductPrice['warehouse_product_id'])
->where('types', ProductSourceLinkInfo::TypeIn)
->find();
if (!empty($productSourceLinkInfo)) {
ProductSourceLinkInfo::where('id', $productSourceLinkInfo['id'])->update(['supply_price' => bcmul($this->storeProductPrice['purchase'], $productSourceLinkInfo['nums'], 2)]);
$list = ProductSourceLinkInfo::field('id,nums,types')
->whereFindInSet('trace_info', $productSourceLinkInfo['id'])
->select()->toArray();
$update = [];
foreach ($list as $item) {
if (in_array($item['types'], [ProductSourceLinkInfo::TypeOrder, ProductSourceLinkInfo::TypeOrderRefund])) {
$update[] = [
'id' => $item['id'],
'supply_price' => bcmul($this->storeProductPrice['purchase'], $item['nums'], 2),
];
} else {
$update[] = [
'id' => $item['id'],
'price' => $this->storeProductPrice['purchase'],
'total_price' => bcmul($this->storeProductPrice['purchase'], $item['nums'], 2),
];
}
}
(new ProductSourceLinkInfo())->saveAll($update);
}
}
/**
* 门店退库
* @return void
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function storeRollback()
{
$list = ProductSourceLinkInfo::where('link_id', $this->info['link_id'])
->where('product_id', $this->info['product_id'])
->where('types', ProductSourceLinkInfo::TypeStoreIn)
->order('id desc')->select()->toArray();
if (empty($list)) {
return;
}
$rollbackNum = abs($this->info['nums']);
$update = [];
foreach ($list as $item) {
if ($item['nums'] > $rollbackNum) {
$update = $this->setUpdate2($item, $rollbackNum, $update);
break;
} else {
$update = $this->setUpdate2($item, $item['nums'], $update);
}
$rollbackNum = bcsub($rollbackNum, $item['nums'], 2);
}
(new ProductSourceLinkInfo())->saveAll($update);
}
private function setUpdate(array $data, float|int|string $rollbackNum, array $update): array
{
$dataNums = bcsub($data['nums'], $rollbackNum, 2);
$currentNums = max(bcsub($data['current_nums'], $rollbackNum, 2), 0);
$rollbackPrice = bcmul($data['price'], $rollbackNum, 2);
$update[] = [
'id' => $data['id'],
'nums' => $dataNums,
'current_nums' => $currentNums,
'total_price' => bcmul($data['price'], $dataNums, 2),
'delete_time' => $dataNums > 0 ? null : time(),
];
if ($data['from_id'] > 0) {
if ($data['types'] == ProductSourceLinkInfo::TypeStoreIn) {
// 门店入库数量发起退库,更新出库单的数量和价格,更新入库单的可分配数量
$outboundLinkInfoId = ProductSourceLinkInfo::where('id', $data['from_id'])->value('from_id');
$update[] = [
'id' => $data['from_id'],
'nums' => Db::raw("nums-{$rollbackNum}"),
'current_nums' => Db::raw("current_nums-{$rollbackNum}"),
'total_price' => Db::raw("total_price-{$rollbackPrice}"),
];
$update[] = [
'id' => $outboundLinkInfoId,
'current_nums' => Db::raw("current_nums+{$rollbackNum}"),
];
} else {
// 更新来源单的可分配数量
$update[] = [
'id' => $data['from_id'],
'current_nums' => Db::raw("current_nums+{$rollbackNum}"),
];
}
}
return $update;
}
/**
* 商品调拨
* @return void
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function transfer()
{
$inventoryTransfer = InventoryTransfer::field('id,nums,one_type,one_id,two_type,two_id')
->where('oid', $this->info['oid'])
->where('product_id', $this->info['product_id'])
->findOrEmpty()->toArray();
if (empty($inventoryTransfer)) {
return;
}
$this->info['link_id'] = $inventoryTransfer['id'];
$query = ProductSourceLinkInfo::where('product_id', $this->info['product_id']);
if ($inventoryTransfer['one_type'] == 1) {
$query->where('store_id', $inventoryTransfer['one_id'])->whereIn('types', [ProductSourceLinkInfo::TypeStoreIn, ProductSourceLinkInfo::TypeS2S]);
$this->info['types'] = $inventoryTransfer['two_type'] == 1 ? ProductSourceLinkInfo::TypeS2S : ProductSourceLinkInfo::TypeS2W;
} else {
$this->info['types'] = ProductSourceLinkInfo::TypeW2W;
$query->where('warehouse_id', $inventoryTransfer['one_id'])->whereIn('types', [ProductSourceLinkInfo::TypeIn, ProductSourceLinkInfo::TypeS2W, ProductSourceLinkInfo::TypeW2W]);
}
if ($inventoryTransfer['two_type'] == 1) {
$this->info['store_id'] = $inventoryTransfer['two_id'];
} else {
$this->info['store_id'] = $inventoryTransfer['one_id'];
$this->info['warehouse_id'] = $inventoryTransfer['two_id'];
}
$list = $query->where('current_nums', '>', 0)
->field('id,oid,product_id,warehouse_id,store_id,purchase_funds_id,nums,current_nums,link_id,from_id,price,trace_info')
->select()->toArray();
if (empty($list)) {
return;
}
$update = [];
$insert = [];
$needNum = $inventoryTransfer['nums'];
foreach ($list as $item) {
$currentNum = max(bcsub($item['current_nums'], $needNum, 2), 0);
if ($item['current_nums'] > $needNum) {
[$update, $insert] = $this->getInsertAndUpdate($update, $insert, $currentNum, $item, $needNum);
break;
} else {
[$update, $insert] = $this->getInsertAndUpdate($update, $insert, 0, $item, $item['current_nums']);
}
$needNum = $needNum - $item['current_nums'];
}
(new ProductSourceLinkInfo())->saveAll($update);
(new ProductSourceLinkInfo())->insertAll($insert);
}
/**
* 门店入库
* @return void
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function storeInStorage()
{
$list = ProductSourceLinkInfo::where('link_id', $this->info['link_id'])
->where('product_id', $this->info['product_id'])
->where('types', ProductSourceLinkInfo::TypeOut)
->select()->toArray();
if (empty($list)) {
return;
}
$insert = [];
foreach ($list as $item) {
$insert[] = [
'oid' => $item['oid'],
'product_id' => $item['product_id'],
'warehouse_id' => $this->info['warehouse_id'],
'store_id' => $this->info['store_id'],
'nums' => $item['nums'],
'current_nums' => $item['nums'],
'types' => $this->info['types'],
'link_id' => $this->info['link_id'],
'from_id' => $item['id'],
'price' => $item['price'],
'total_price' => $item['total_price'],
'purchase_funds_id' => $item['purchase_funds_id'],
'trace_info' => empty($item['trace_info']) ? $item['id'] : $item['trace_info'] . ',' . $item['id'],
];
}
ProductSourceLinkInfo::insertAll($insert);
}
public function putOutStorage(array $productSourceLinkInfo, mixed $needNum): bool
{
$update = [];
$insert = [];
foreach ($productSourceLinkInfo as $item) {
$this->info['warehouse_id'] = empty($this->info['warehouse_id']) ? $item['warehouse_id'] : $this->info['warehouse_id'];
$this->info['store_id'] = empty($this->info['store_id']) ? $item['store_id'] : $this->info['store_id'];
$currentNum = max(bcsub($item['current_nums'], $needNum, 2), 0);
if ($item['current_nums'] > $needNum) {
[$update, $insert] = $this->getInsertAndUpdate($update, $insert, $currentNum, $item, $needNum);
break;
} else {
[$update, $insert] = $this->getInsertAndUpdate($update, $insert, 0, $item, $item['current_nums']);
}
$needNum = $needNum - $item['current_nums'];
}
(new ProductSourceLinkInfo())->saveAll($update);
(new ProductSourceLinkInfo())->insertAll($insert);
return true;
}
}

View File

@ -3,6 +3,7 @@
namespace app\admin\logic\purchase_product_offer;
use app\admin\service\ProductPriceService;
use app\common\model\purchase_product_offer\PurchaseProductOffer;
use app\common\logic\BaseLogic;
use app\common\model\auth\Admin;
@ -214,6 +215,11 @@ class PurchaseProductOfferLogic extends BaseLogic
$params['manufacture'] = !empty($params['manufacture']) ? strtotime($params['manufacture']) : '';
$params['expiration_date'] = !empty($params['expiration_date']) ? strtotime($params['expiration_date']) : '';
$offer = PurchaseProductOffer::where(['id' => $params['id']])->find();
$lastPrice = PurchaseProductOffer::where(['product_id' => $offer['product_id']])->where('status', 1)->order('id desc')->value('price');
$currentPrice = bcdiv($params['total_price'], $params['buyer_nums'], 2);
if ($lastPrice > 0 && ($currentPrice > $lastPrice * 3 || $currentPrice < $lastPrice / 3)) {
// throw new BusinessException('价格异常,请重新输入');
}
// $uid=Admin::where('id',$params['admin_id'])->value('uid');
// if($params['admin_id']!=1){
// if($offer['buyer_id']!=$uid){
@ -383,12 +389,14 @@ class PurchaseProductOfferLogic extends BaseLogic
* 设置商品价格
* @param $params
* @param $product
* @param $warehouseId
* @param $warehouseProductId
* @return void
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function setProductPrice($params, $product, $warehouseId = 0)
public static function setProductPrice($params, $product, $warehouseId = 0, $warehouseProductId = 0)
{
$priceConfig = [];
$data = [
@ -400,22 +408,13 @@ class PurchaseProductOfferLogic extends BaseLogic
'update_time' => time(),
'status' => 0,
'warehouse_id' => $warehouseId,
'warehouse_product_id' => $warehouseProductId,
];
$productPriceRate = self::getProductPriceRate($product);
$productService = new ProductPriceService();
$productPriceRate = $productService->getProductPriceRate($product['id']);
if (!empty($productPriceRate)) {
$data['purchase_lv'] = bcdiv($productPriceRate['supply_rate'], 100, 2);
$data['purchase'] = bcmul($params['purchase'], $data['purchase_lv'], 2);
$data['cost_lv'] = bcdiv($productPriceRate['merchant_rate'], 100, 2);
$data['cost'] = bcmul($data['purchase'], $data['cost_lv'], 2);
$data['vip_lv'] = bcdiv($productPriceRate['vip_rate'], 100, 2);
$data['vip_price'] = bcmul($data['purchase'], $data['vip_lv'], 2);
$data['price_lv'] = bcdiv($productPriceRate['price_rate'], 100, 2);
$data['price'] = bcmul($data['purchase'], $data['price_lv'], 2);
$lastNum = substr($data['price'], -1);
if ($lastNum > 0) {
$data['price'] = ceil($data['price'] * 10);
$data['price'] = bcdiv($data['price'], 10, 2);
}
$priceArray = $productService->setProductPrice($params['purchase'], $productPriceRate);
$data = array_merge($data, $priceArray);
}
$data['price_config'] = $priceConfig;
$find = StoreProductPrice::where(['offer_id' => $params['id']])->find();
@ -426,14 +425,19 @@ class PurchaseProductOfferLogic extends BaseLogic
}
}
/**
* @deprecated 已废弃,使用(new ProductPriceService())->getProductPriceRate($product['id'])
* @param $product
* @return array|int[]
*/
public static function getProductPriceRate($product)
{
$list = StoreProductPriceList::where('product_id', $product['id'])->findOrEmpty()->toArray();
if (empty($list)) {
$list = [
'supply_rate' => 110,
'merchant_rate' => 106,
'vip_rate' => 110,
'merchant_rate' => 103,
'vip_rate' => 115,
'price_rate' => 120,
];
}
@ -491,7 +495,7 @@ class PurchaseProductOfferLogic extends BaseLogic
$procurementOrder->order_id = getNewOrderId('CG');
$procurementOrder->buyer_id = $params['buyer_id'];
$procurementOrder->admin_id = $params['admin_id'];
$procurementOrder->order_type = 7;
$procurementOrder->order_type = $params['order_type'];
$procurementOrder->total_price = 0;
$procurementOrder->pay_price = 0;
$procurementOrder->save();

View File

@ -2,7 +2,9 @@
namespace app\admin\logic\store_branch_product;
use app\admin\logic\product_source_link\ProductSourceLinkLogic;
use app\admin\logic\store_product\StoreProductLogic;
use app\common\model\product_source_link_info\ProductSourceLinkInfo;
use app\common\model\store_branch_product\StoreBranchProduct;
use app\common\logic\BaseLogic;
use app\common\model\store_product\StoreProduct;
@ -141,6 +143,13 @@ class StoreBranchProductLogic extends BaseLogic
], ['product_id' => $productId,'store_id'=>$storeId]);
SqlChannelLog('StoreBranchProduct',$branchProduct['id'], $num, -1, Request()->url());
}
ProductSourceLinkLogic::add([
'purchase_product_offer' => [$params],
'types' => ProductSourceLinkInfo::TypeIn,
'buyer_id' => $params['buyer_id'],
'warehouse_id' => $params['warehouse_id'],
'link_id' => $res['id'],
]);
}
}

View File

@ -108,4 +108,11 @@ class StoreCategoryLogic extends BaseLogic
{
return StoreCategory::findOrEmpty($params['id'])->toArray();
}
public static function tree()
{
$data = StoreCategory::field('id,pid,name')->order('id desc')->select()->toArray();
return list2tree($data);
}
}

View File

@ -3,22 +3,18 @@
namespace app\admin\logic\store_product;
use app\admin\logic\ActivityZoneLogic;
use app\admin\logic\warehouse_product\WarehouseProductLogic;
use app\common\model\store_product\StoreProduct;
use app\common\logic\BaseLogic;
use app\common\model\store_branch_product\StoreBranchProduct;
use app\common\model\store_branch_product_attr_value\StoreBranchProductAttrValue;
use app\common\model\store_branch_product_exchange\StoreBranchProductExchange;
use app\common\model\store_category\StoreCategory;
use app\common\model\store_product_attr_value\StoreProductAttrValue;
use app\common\model\store_product_cate\StoreProductCate;
use app\common\model\store_product_group_price\StoreProductGroupPrice;
use app\common\model\store_product_unit\StoreProductUnit;
use app\common\model\system_store\SystemStore;
use app\common\model\system_store_storage\SystemStoreStorage;
use app\common\model\user\User;
use app\common\model\warehouse_product_storege\WarehouseProductStorege;
use Illuminate\Support\Facades\Log;
use support\exception\BusinessException;
use think\facade\Db;
use Webman\RedisQueue\Redis;
@ -35,11 +31,10 @@ class StoreProductLogic extends BaseLogic
/**
* @notes 添加商品列表
* @param array $params
* @return bool
* @author likeadmin
* @date 2024/05/31 10:53
*/
public static function add(array $params): bool
public static function add(array $params)
{
$count = count($params['cate_arr']);
$top_cate_id = 0;
@ -67,6 +62,7 @@ class StoreProductLogic extends BaseLogic
'vip_price' => $params['vip_price'],
'cost' => $params['cost'],
'purchase' => $params['purchase'],
'package' => $params['package']??'',
'is_return' => $params['is_return'],
'manufacturer_information' => $params['manufacturer_information'] ?? '',
'swap' => $params['swap'] ?? 0,
@ -124,7 +120,7 @@ class StoreProductLogic extends BaseLogic
Redis::send('store-storage', ['product_arr' => ['id' => $res['id'], 'stock' => 0], 'store_id' => getenv('STORE_ID'), 'stock_type' => 1, 'admin_id' => Request()->adminId]);
}
return true;
return $res;
} catch (\Exception $e) {
Db::rollback();
throw new BusinessException('添加商品失败' . $e->getMessage());
@ -466,4 +462,32 @@ class StoreProductLogic extends BaseLogic
// }
// }
}
/**
* 复制商品到仓库
* @param $params
* @return void
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function copyWarehouse($params)
{
$exist = WarehouseProductStorege::where(['product_id' => $params['product_id'], 'warehouse_id' => $params['warehouse_id']])->find();
if ($exist) {
throw new BusinessException('该商品已存在该仓库');
}
$storeProduct = StoreProduct::where('id', $params['product_id'])->findOrEmpty();
if (!$storeProduct) {
throw new BusinessException('商品不存在');
}
$data = [
'warehouse_id' => $params['warehouse_id'],
'product_id' => $params['product_id'],
'nums' => 0,
'total_price' => 0
];
WarehouseProductStorege::create($data);
}
}

View File

@ -3,6 +3,8 @@
namespace app\admin\logic\store_product_price;
use app\admin\logic\product_source_link_info\ProductSourceLinkInfoLogic;
use app\admin\service\ProductPriceService;
use app\common\model\store_product_group_price\StoreProductGroupPrice;
use app\common\model\store_product_price\StoreProductPrice;
use app\common\logic\BaseLogic;
@ -35,7 +37,46 @@ class StoreProductPriceLogic extends BaseLogic
{
Db::startTrans();
try {
StoreProductPrice::create([]);
$model = StoreProductPrice::create($params);
$storeProductPriceList = StoreProductPriceList::where('product_id', $model['product_id'])->find();
$attrs = [
'supply_rate' => $params['purchase_lv'] * 100,
'merchant_rate' => $params['cost_lv'] * 100,
'vip_rate' => $params['vip_lv'] * 100,
'price_rate' => $params['price_lv'] * 100,
];
if (empty($storeProductPriceList)) {
$attrs['product_id'] = $model['product_id'];
StoreProductPriceList::create($attrs);
} else {
StoreProductPriceList::where('product_id', $model['product_id'])->update($attrs);
}
$productPrice = StoreProduct::where('id', $model['product_id'])->value('vip_price');
if ($productPrice != $model['vip_price']) {
SqlChannelPriceLog($model['product_id'], 43, $productPrice, $model['vip_price']);
}
StoreProduct::where('id', $model['product_id'])->update([
'purchase' => $model['purchase'],
'cost' => $model['cost'],
'vip_price' => $model['vip_price'],
'price' => $model['price'],
'ot_price' => $model['price'],
'price_update_time' => time(),
]);
StoreBranchProduct::where('product_id', $model['product_id'])->update([
'purchase' => $model['purchase'],
'cost' => $model['cost'],
'vip_price' => $model['vip_price'],
'price' => $model['price'],
'ot_price' => $model['price']
]);
$productSourceLinkInfoLogic = new ProductSourceLinkInfoLogic();
$productSourceLinkInfoLogic->storeProductPrice = $model;
$productSourceLinkInfoLogic->updateSupplyPrice();
Db::commit();
return true;
@ -59,30 +100,29 @@ class StoreProductPriceLogic extends BaseLogic
try {
$find = StoreProductPrice::where('id', $params['id'])->find();
if ($find) {
$changePurchase = false;
$productPriceListAttrs = [];
if ($find['purchase_lv'] != $params['purchase_lv']) {
$params = self::updateProductPriceList2($find['product_id'], 'supply_rate', $params['purchase_lv'], $params, 'purchase', $find['purchase_price']);
$changePurchase = true;
}
if ($changePurchase) {
$params['cost'] = bcmul($params['purchase'], $params['cost_lv'], 2);
$params['vip_price'] = bcmul($params['purchase'], $params['vip_lv'], 2);
$params['price'] = bcmul($params['purchase'], $params['price_lv'], 2);
$productPriceListAttrs['supply_rate'] = $params['purchase_lv'] * 100;
}
if ($find['cost_lv'] != $params['cost_lv']) {
$params = self::updateProductPriceList2($find['product_id'], 'merchant_rate', $params['cost_lv'], $params, 'cost', $params['purchase']);
$productPriceListAttrs['merchant_rate'] = $params['cost_lv'] * 100;
}
if ($find['vip_lv'] != $params['vip_lv']) {
$params = self::updateProductPriceList2($find['product_id'], 'vip_rate', $params['vip_lv'], $params, 'vip_price', $params['purchase']);
$productPriceListAttrs['vip_rate'] = $params['vip_lv'] * 100;
}
if ($find['price_lv'] != $params['price_lv']) {
$params = self::updateProductPriceList2($find['product_id'], 'price_rate', $params['price_lv'], $params, 'price', $params['purchase']);
$productPriceListAttrs['price_rate'] = $params['price_lv'] * 100;
}
$lastNum = substr($params['price'], -1);
if ($lastNum > 0) {
$params['price'] = ceil($params['price'] * 10);
$params['price'] = bcdiv($params['price'], 10, 2);
if (!empty($productPriceListAttrs)) {
$id = StoreProductPriceList::where('product_id', $find['product_id'])->value('id');
if (empty($id)) {
$productPriceListAttrs = array_merge($productPriceListAttrs, ['product_id' => $find['product_id']]);
StoreProductPriceList::create($productPriceListAttrs);
} else {
StoreProductPriceList::where('id', $id)->update($productPriceListAttrs);
}
}
$find->save([
'status' => 1,
'purchase' => $params['purchase'],
@ -95,20 +135,29 @@ class StoreProductPriceLogic extends BaseLogic
'price_lv' => $params['price_lv'],
'price_config' => $params['price_config'],
]);
$productPrice = StoreProduct::where('id', $find['product_id'])->value('vip_price');
if ($productPrice != $find['vip_price']) {
SqlChannelPriceLog($find['product_id'], 43, $productPrice, $find['vip_price']);
}
StoreProduct::where('id', $find['product_id'])->update([
'purchase' => $find['purchase'],
'cost' => $find['cost'],
'vip_price' => $find['vip_price'],
'price' => $find['vip_price'],
'ot_price' => $find['price']
'price' => $find['price'],
'ot_price' => $find['price'],
'price_update_time' => time(),
]);
StoreBranchProduct::where('product_id', $find['product_id'])->update([
'purchase' => $find['purchase'],
'cost' => $find['cost'],
'vip_price' => $find['vip_price'],
'price' => $find['vip_price'],
'price' => $find['price'],
'ot_price' => $find['price']
]);
$productSourceLinkInfoLogic = new ProductSourceLinkInfoLogic();
$productSourceLinkInfoLogic->storeProductPrice = $find;
$productSourceLinkInfoLogic->updateSupplyPrice();
}
Db::commit();
return true;
@ -118,7 +167,7 @@ class StoreProductPriceLogic extends BaseLogic
}
}
public static function updateProductPriceList2($productId, $field, $rate, $params, $index, $basePrice)
public static function updateProductPriceList2($productId, $field, $rate)
{
$id = StoreProductPriceList::where('product_id', $productId)->value('id');
if (empty($id)) {
@ -129,8 +178,6 @@ class StoreProductPriceLogic extends BaseLogic
} else {
StoreProductPriceList::where('id', $id)->update([$field => $rate * 100]);
}
$params[$index] = bcmul($basePrice, $rate, 2);
return $params;
}
public static function updateProductPriceList($productId, $priceType, $rate, $params, $field, $basePrice)
@ -162,25 +209,31 @@ class StoreProductPriceLogic extends BaseLogic
try {
$find = StoreProductPrice::where('id', $params['id'])->find();
if ($find) {
$productService = new ProductPriceService();
$productPriceRate = StoreProductPriceList::whereIn('product_id', $find['product_id'])->findOrEmpty()->toArray();
$update = ['status' => 1];
$lastNum = substr($find['price'], -1);
if ($lastNum > 0) {
$update['price'] = ceil($find['price'] * 10);
$update['price'] = bcdiv($update['price'], 10, 2);
if (!empty($productPriceRate)) {
$update = $productService->setProductPrice($find['purchase_price'], $productPriceRate);
$update['status'] = 1;
}
$find->save($update);
$productPrice = StoreProduct::where('id', $find['product_id'])->value('vip_price');
if ($productPrice != $find['vip_price']) {
SqlChannelPriceLog($find['product_id'], 43, $productPrice, $find['vip_price']);
}
StoreProduct::where('id', $find['product_id'])->update([
'purchase' => $find['purchase'] ?? 0,
'cost' => $find['cost'] ?? 0,
'vip_price' => $find['vip_price'] ?? 0,
'price' => $find['vip_price'] ?? 0,
'price' => $find['price'] ?? 0,
'ot_price' => $find['price'] ?? 0,
'price_update_time' => time(),
]);
StoreBranchProduct::where('product_id', $find['product_id'])->update([
'purchase' => $find['purchase'] ?? 0,
'cost' => $find['cost'] ?? 0,
'vip_price' => $find['vip_price'] ?? 0,
'price' => $find['vip_price'] ?? 0,
'price' => $find['price'] ?? 0,
'ot_price' => $find['price'] ?? 0,
]);
}
@ -273,7 +326,7 @@ class StoreProductPriceLogic extends BaseLogic
{
$list = StoreProductPrice::where('product_id', $params['product_id'])
->field('id,purchase_price,purchase,create_time')
->order('id asc')->limit(30)
->order('id desc')->limit(30)
->select()->toArray();
foreach ($list as &$item) {
$item['date'] = date('m-d', strtotime($item['create_time']));
@ -283,6 +336,7 @@ class StoreProductPriceLogic extends BaseLogic
$item['price'] = $item['purchase'];
}
}
asort($list);
$data = [
'name' => '价格趋势',
'series' => [['name' => '价格', 'value' => array_column($list, 'price')]],

View File

@ -2,9 +2,10 @@
namespace app\admin\logic\system_store_storage;
use app\admin\logic\product_source_link_info\ProductSourceLinkInfoLogic;
use app\admin\logic\store_product\StoreProductLogic;
use app\common\model\product_source_link_info\ProductSourceLinkInfo;
use app\common\model\store_branch_product\StoreBranchProduct;
use app\common\model\store_branch_product_attr_value\StoreBranchProductAttrValue;
use app\common\model\system_store_storage\SystemStoreStorage;
use app\common\logic\BaseLogic;
use app\common\model\store_product\StoreProduct;
@ -64,26 +65,30 @@ class SystemStoreStorageLogic extends BaseLogic
Db::startTrans();
try {
$find= WarehouseProduct::where(['id' => $params['id']])->find();
// $find=SystemStoreStorage::where(['id' => $params['id']])->find();
if($find){
// if($find['order_type']==1){
$find->save(['status'=>1,'staff_id'=>$params['staff_id']??0,'admin_id'=>$params['admin_id']??0,'mark'=>'入库时间:'.date('Y-m-d H:i:s',time())]);
$branch_product=StoreBranchProduct::where(['product_id'=>$find['product_id'],'store_id'=>$find['store_id']])->find();
if($branch_product){
$branch_product->stock=$branch_product['stock']+$find['nums'];
$branch_product->save();
SqlChannelLog('StoreBranchProduct', $branch_product['id'], $find['nums'], 1,Request()->url(),$admin_id);
}else{
$storeProduct = StoreProduct::where('id', $find['product_id'])->withTrashed()->findOrEmpty();
$storeBranchProduct = StoreProductLogic::ordinary(['id' => $find['product_id']], $find['store_id'], 0, $storeProduct);
$storeBranchProduct->stock = $find['nums'];
$storeBranchProduct->save();
SqlChannelLog('StoreBranchProduct', $storeBranchProduct['id'], $find['nums'], 1,Request()->url(),$admin_id);
}
// }else{
// $find->save(['status'=>1,'staff_id'=>$params['staff_id']??0,'admin_id'=>$params['admin_id']??0,'mark'=>'确认时间:'.date('Y-m-d H:i:s',time())]);
// }
$find->save(['status'=>1,'staff_id'=>$params['staff_id']??0,'admin_id'=>$params['admin_id']??0,'mark'=>'入库时间:'.date('Y-m-d H:i:s',time())]);
$branch_product=StoreBranchProduct::where(['product_id'=>$find['product_id'],'store_id'=>$find['store_id']])->find();
if($branch_product){
$branch_product->stock=$branch_product['stock']+$find['nums'];
$branch_product->save();
SqlChannelLog('StoreBranchProduct', $branch_product['id'], $find['nums'], 1,Request()->url(),$admin_id);
}else{
$storeProduct = StoreProduct::where('id', $find['product_id'])->withTrashed()->findOrEmpty();
$storeBranchProduct = StoreProductLogic::ordinary(['id' => $find['product_id']], $find['store_id'], 0, $storeProduct);
$storeBranchProduct->stock = $find['nums'];
$storeBranchProduct->save();
SqlChannelLog('StoreBranchProduct', $storeBranchProduct['id'], $find['nums'], 1,Request()->url(),$admin_id);
}
$productSourceLinkInfoLogic = new ProductSourceLinkInfoLogic();
$productSourceLinkInfoLogic->setInfo([
'link_id' => $find['id'],
'product_id' => $find['product_id'],
'warehouse_id' => $find['warehouse_id'],
'store_id' => $find['store_id'],
'types' => ProductSourceLinkInfo::TypeStoreIn,
]);
$productSourceLinkInfoLogic->storeInStorage();
}
Db::commit();
return true;
@ -195,7 +200,18 @@ class SystemStoreStorageLogic extends BaseLogic
$warehouseProduct->save();
$warehouseStorage->nums += $params['num'];
$warehouseStorage->save();
SqlChannelLog('StoreBranchProduct', $warehouseProduct['id'], $warehouseProduct['nums'], 1,Request()->url());
SqlChannelLog('WarehouseProductStorege', $warehouseStorage['id'], $params['num'], 1,Request()->url());
SqlChannelLog('StoreBranchProduct', $StoreProduct['id'], $params['num'], -1,Request()->url());
$productSourceLinkInfoLogic = new ProductSourceLinkInfoLogic();
$productSourceLinkInfoLogic->setInfo([
'link_id' => $warehouseProduct['id'],
'product_id' => $warehouseProduct['product_id'],
'nums' => $params['num'],
'types' => ProductSourceLinkInfo::TypeStoreOut,
]);
$productSourceLinkInfoLogic->storeRollback();
Db::commit();
return true;
} catch (\Exception $e) {

View File

@ -20,6 +20,7 @@ class WarehouseOrderLogic extends BaseLogic
/**
* @deprecated 已禁止直接创建入库单
* @notes 添加仓储商品单
* @param array $params
* @return bool
@ -92,9 +93,11 @@ class WarehouseOrderLogic extends BaseLogic
throw new BusinessException('订单不存在');
}
$order_type=BeforehandOrder::where('warehousing_id|outbound_id',$find['id'])->value('order_type')??0;
$buyerId = BeforehandOrder::where('warehousing_id|outbound_id',$find['id'])->value('buyer_id') ?? 0;
Db::startTrans();
try {
foreach ($params['product_arr'] as $k => $v) {
$data['buyer_id'] = $buyerId;
$data['order_type'] = $order_type;
$data['supplier_id'] = $v['supplier_id']??0;
$data['pay_type'] = $v['pay_type']??0;
@ -106,6 +109,8 @@ class WarehouseOrderLogic extends BaseLogic
$data['product_id'] = $v['id'];
$data['nums'] = $v['nums'];
$data['purchase'] = $v['purchase'];
$data['buyer_nums'] = $v['nums'];
$data['price'] = $v['purchase'];
$data['total_price'] = $v['total_price'];
$data['financial_pm'] = $find['financial_pm'];
if (!empty($v['manufacture'])) {
@ -118,7 +123,11 @@ class WarehouseOrderLogic extends BaseLogic
$data['purchase'] = $v['prices'];
$data['total_price'] = bcmul($v['prices'], $v['nums'], 2);
}
WarehouseProductLogic::add($data,1,$params['admin_id']);
if ($data['financial_pm'] == 1) {
WarehouseProductLogic::add($data,1,$params['admin_id']);
} else {
WarehouseProductLogic::setOutbound($data,1,$params['admin_id']);
}
}
$find = WarehouseProduct::where('oid', $params['id'])->field('sum(nums) as nums,sum(total_price) as total_price')->find();
if ($find) {
@ -168,6 +177,9 @@ class WarehouseOrderLogic extends BaseLogic
* @date 2024/08/20 10:50
*/
public static function update_edit($data){
if (!empty($data['create_time'])) {
$data['create_time'] = strtotime($data['create_time']);
}
$res=WarehouseOrder::update($data);
if($res){
return true;

View File

@ -2,17 +2,20 @@
namespace app\admin\logic\warehouse_product;
use app\admin\logic\store_branch_product\StoreBranchProductLogic;
use app\admin\logic\store_product\StoreProductLogic;
use app\admin\logic\delivery_service\DeliveryServiceLogic;
use app\admin\logic\product_source_link_info\ProductSourceLinkInfoLogic;
use app\common\model\product_source_link_info\ProductSourceLinkInfo;
use app\common\model\PurchaseFunds;
use app\common\model\warehouse_product\WarehouseProduct;
use app\common\logic\BaseLogic;
use app\common\model\purchase_product_offer\PurchaseProductOffer;
use app\common\model\store_branch_product\StoreBranchProduct;
use app\common\model\store_product\StoreProduct;
use app\common\model\system_store_storage\SystemStoreStorage;
use app\common\model\warehouse_order\WarehouseOrder;
use app\common\model\warehouse_product_storege\WarehouseProductStorege;
use support\Log;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
use support\exception\BusinessException;
@ -29,7 +32,6 @@ class WarehouseProductLogic extends BaseLogic
/**
* @notes 添加商品仓储信息
* @param array $params
* @return bool
* @author admin
* @date 2024/07/31 16:55
*/
@ -53,7 +55,7 @@ class WarehouseProductLogic extends BaseLogic
$total_price = bcmul($after_nums, $storeProduct['purchase'], 2);
}
WarehouseProductStorege::update(['nums' => $after_nums, 'total_price' => $total_price], ['id' => $storege['id']]);
SqlChannelLog('WarehouseProductStorege', $storege['id'], $after_nums, 1, Request()->url(),$admin_id);
SqlChannelLog('WarehouseProductStorege', $storege['id'], $params['nums'], 1, Request()->url(),$admin_id);
}
} else {
@ -112,6 +114,21 @@ class WarehouseProductLogic extends BaseLogic
$res = WarehouseProduct::create($data);
SqlChannelLog('WarehouseProduct', $res['id'], $params['nums'], $params['financial_pm'] == 1 ? 1 : -1, Request()->url(),$admin_id);
if (!empty($params['purchase_funds_id'])) {
PurchaseFunds::where('id', $params['purchase_funds_id'])->dec('current_amount', $params['total_price'])->save();
}
$productSourceLinkInfoLogic = new ProductSourceLinkInfoLogic();
$productSourceLinkInfoLogic->purchaseProductOffer = $params;
$productSourceLinkInfoLogic->setInfo([
'types' => ProductSourceLinkInfo::TypeIn,
'buyer_id' => $params['buyer_id'],
'warehouse_id' => $params['warehouse_id'],
'link_id' => $res['id'],
]);
$productSourceLinkInfoLogic->putInStorage();
DeliveryServiceLogic::subPurchaseFunds($params['buyer_id'], $params['total_price']);
return $res;
} catch (\Throwable $e) {
throw new BusinessException($e->getMessage());
@ -129,24 +146,10 @@ class WarehouseProductLogic extends BaseLogic
if ($params['order_type'] != 6) {
$storege = WarehouseProductStorege::where('warehouse_id', $params['warehouse_id'])->where('product_id', $params['product_id'])->find();
if ($storege) {
// if (($params['store_id'] == 3 && in_array($params['order_type'], [1, 2, 3, 4, 8])) || in_array($params['order_type'], [1, 4])) {
// SystemStoreStorage::create([
// 'store_id' => $params['store_id'],
// 'admin_id' => $params['admin_id'],
// 'order_type' => $params['order_type'],
// 'staff_id' => 0,
// 'type' => 1,
// 'product_id' => $params['product_id'],
// 'nums' => $params['nums'],
// 'outbound_id' => $params['oid'] ?? 0,
// 'warehouse_id' =>1,
// 'status' => 0
// ]);
// }
$after_nums = bcsub($storege['nums'], $params['nums']);
$total_price = bcmul($after_nums, $params['purchase'], 2);
WarehouseProductStorege::update(['nums' => bcsub($storege['nums'], $params['nums']), 'total_price' => $total_price], ['id' => $storege['id']]);
SqlChannelLog('WarehouseProductStorege', $storege['id'], bcsub($storege['nums'], $params['nums']), -1, Request()->url(),$admin_id);
SqlChannelLog('WarehouseProductStorege', $storege['id'], $params['nums'], -1, Request()->url(),$admin_id);
} else {
$data = [
'warehouse_id' => $params['warehouse_id'],
@ -155,7 +158,7 @@ class WarehouseProductLogic extends BaseLogic
'total_price' => 0
];
$storege = WarehouseProductStorege::create($data);
SqlChannelLog('WarehouseProductStorege', $storege->id, -$params['nums'], -1, Request()->url(),$admin_id);
SqlChannelLog('WarehouseProductStorege', $storege->id, $params['nums'], -1, Request()->url(),$admin_id);
}
} else {
$storege['nums'] = 0;
@ -188,6 +191,15 @@ class WarehouseProductLogic extends BaseLogic
$res = WarehouseProduct::create($data);
SqlChannelLog('WarehouseProduct', $res->id, $params['nums'], $params['financial_pm'] == 1 ? 1 : -1, Request()->url(),$admin_id);
$productSourceLinkInfoLogic = new ProductSourceLinkInfoLogic();
$productSourceLinkInfoLogic->warehouseProduct = $data;
$productSourceLinkInfoLogic->setInfo([
'warehouse_id' => $params['warehouse_id'],
'store_id' => $data['store_id'],
'link_id' => $res['id'],
]);
$productSourceLinkInfoLogic->outbound();
Db::commit();
return $res;
} catch (\Throwable $e) {
@ -210,24 +222,16 @@ class WarehouseProductLogic extends BaseLogic
$find = WarehouseOrder::where('id', $params['oid'])->find();
if ($find) {
$res = WarehouseProduct::where('id', $params['id'])->withTrashed()->find();
if($params['nums']>$res['nums']){
$nums=bcsub($params['nums'], $res['nums'],2);
if ($res['financial_pm'] == 0) {
self::decWarehouseProduct($res, $nums);
} else {
self::incWarehouseProduct($res, $nums);
}
}else{
if($params['nums']==0){
self::decWarehouseProduct($res, $res['nums']);
}else{
$nums = bcsub($res['nums'], $params['nums'], 2);
if ($res['financial_pm'] == 0) {
self::incWarehouseProduct($res, $nums);
} else {
self::decWarehouseProduct($res, $nums);
}
$updateNums = bcsub($params['nums'], $res['nums'],2);
if ($updateNums != 0) {
if ($res['status'] == 1 && $res['store_id'] > 0) {
throw new BusinessException('门店已确认入库,不能修改数量');
}
$storageNum = $res['financial_pm'] == 0 ? -$updateNums : $updateNums;
$productNum = $updateNums;
self::updateWarehouseProduct($res, $storageNum, $productNum);
self::updateProductSourceLink($res, $params, $updateNums);
}
$datas = [
'total_price' => $params['total_price'],
@ -246,12 +250,12 @@ class WarehouseProductLogic extends BaseLogic
$datas['expiration_date'] = strtotime($params['expiration_date']);
}
$res->save($datas);
self::updateWarehouseOrder($res['oid']);
}
Db::commit();
return $res;
} catch (\Exception $e) {
Db::rollback();
d($e);
throw new BusinessException($e->getMessage());
}
}
@ -269,12 +273,16 @@ class WarehouseProductLogic extends BaseLogic
if ($res) {
Db::startTrans();
try {
if ($res['financial_pm'] == 1) {
self::decProductIncStorege($res, $res['nums'], $admin_id);
} elseif ($res['financial_pm'] == 0) {
self::incProductDecStorege($res, $res['nums'], $admin_id);
}
$storageNum = $res['financial_pm'] == 1 ? -$res['nums'] : $res['nums'];
$productNum = -$res['nums'];
self::updateWarehouseProduct($res, $storageNum, $productNum);
$res->delete();
self::updateWarehouseOrder($res['oid']);
$types = $res['financial_pm'] == 1 ? ProductSourceLinkInfo::TypeIn : ProductSourceLinkInfo::TypeOut;
$productSourceLinkInfoLogic = new ProductSourceLinkInfoLogic();
$productSourceLinkInfoLogic->deleteByLinkId($res['id'], $types);
Db::commit();
return true;
} catch (\Throwable $th) {
@ -316,28 +324,30 @@ class WarehouseProductLogic extends BaseLogic
{
Db::startTrans();
try {
$res = WarehouseProduct::where('id', $params['id'])->find();
if ($res) {
if($params['nums']>$res['nums']){
$nums=bcsub($params['nums'], $res['nums'],2);
self::incProductDecStorege($res, $nums,$admin_id);
}else{
$nums=bcsub($res['nums'],$params['nums'],2);
self::decProductIncStorege($res, $nums,$admin_id);
$warehouseProduct = WarehouseProduct::where('id', $params['id'])->find();
if ($warehouseProduct) {
$updateNums = bcsub($params['nums'], $warehouseProduct['nums'],2);
if ($updateNums != 0) {
$storageNum = $warehouseProduct['financial_pm'] == 0 ? -$updateNums : $updateNums;
$productNum = $updateNums;
self::updateWarehouseProduct($warehouseProduct, $storageNum, $productNum);
self::updateProductSourceLink($warehouseProduct, $params, $updateNums);
}
if($res['financial_pm']==1){
if($warehouseProduct['financial_pm']==1){
$datas = [
'nums' => $params['nums'],
'total_price' => bcmul($params['nums'], $res['purchase'], 2),
'total_price' => bcmul($params['nums'], $warehouseProduct['purchase'], 2),
];
}else{
$datas = [
'nums' => $params['nums'],
'total_price' => bcmul($params['nums'], $res['price'], 2),
'total_price' => bcmul($params['nums'], $warehouseProduct['price'], 2),
];
}
$res->save($datas);
$warehouseProduct->save($datas);
self::updateWarehouseOrder($warehouseProduct['oid']);
}
Db::commit();
} catch (\Throwable $th) {
@ -445,71 +455,50 @@ class WarehouseProductLogic extends BaseLogic
}
/**
* 增加商品入库数量
* 增加商品数量
* @param $warehouseProduct
* @param $nums
* @param $storageNum
* @param $productNum
* @return void
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public static function incWarehouseProduct($warehouseProduct, $nums)
public static function updateWarehouseProduct($warehouseProduct, $storageNum, $productNum)
{
$warehouseProductStorage = WarehouseProductStorege::where('warehouse_id', $warehouseProduct['warehouse_id'])
->where('product_id', $warehouseProduct['product_id'])->find();
$warehouseProductStorage->nums = bcadd($warehouseProductStorage->nums, $nums, 2);
$warehouseProductStorage->nums = bcadd($warehouseProductStorage->nums, $storageNum, 2);
$warehouseProductStorage->save();
SqlChannelLog('WarehouseProductStorege', $warehouseProductStorage['id'], $nums, 1, Request()->url());
SqlChannelLog('WarehouseProductStorege', $warehouseProductStorage['id'], $storageNum, $storageNum > 0 ? 1 : -1, Request()->url());
$update = [
'nums' => bcadd($warehouseProduct['nums'], $nums, 2),
'total_price' => bcadd($warehouseProduct['total_price'], bcmul($nums, $warehouseProduct['price'], 2), 2),
'nums' => bcadd($warehouseProduct['nums'], $productNum, 2),
'total_price' => bcadd($warehouseProduct['total_price'], bcmul($productNum, $warehouseProduct['price'], 2), 2),
];
WarehouseProduct::where('id',$warehouseProduct['id'])->update($update);
SqlChannelLog('WarehouseProduct', $warehouseProduct['id'], $nums, 1, Request()->url());
SqlChannelLog('WarehouseProduct', $warehouseProduct['id'], $productNum, $productNum > 0 ? 1 : -1, Request()->url());
$find = WarehouseProduct::where('oid', $warehouseProduct['oid'])->field('sum(nums) as nums,sum(total_price) as total_price')->find();
if ($find) {
WarehouseOrder::where('id', $warehouseProduct['oid'])->update([
'nums' => $find['nums'],
'total_price' => $find['total_price']
]);
}
self::updateStoreStorage2($warehouseProduct, $nums);
self::updateStoreStorage2($warehouseProduct, $productNum);
}
/**
* 减少商品入库数量
* @param $warehouseProduct
* @param $nums
* 更新订单数量和总价
* @param $oid
* @return void
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public static function decWarehouseProduct($warehouseProduct, $nums)
public static function updateWarehouseOrder($oid)
{
$warehouseProductStorage = WarehouseProductStorege::where('warehouse_id', $warehouseProduct['warehouse_id'])
->where('product_id', $warehouseProduct['product_id'])->find();
$warehouseProductStorage->nums = bcsub($warehouseProductStorage->nums, $nums, 2);
$warehouseProductStorage->save();
SqlChannelLog('WarehouseProductStorege', $warehouseProductStorage['id'], $nums, -1, Request()->url());
$update = [
'nums' => bcsub($warehouseProduct['nums'], $nums, 2),
'total_price' => bcsub($warehouseProduct['total_price'], bcmul($nums, $warehouseProduct['price'], 2), 2),
];
WarehouseProduct::where('id',$warehouseProduct['id'])->update($update);
SqlChannelLog('WarehouseProduct', $warehouseProduct['id'], $nums, -1, Request()->url());
$find = WarehouseProduct::where('oid', $warehouseProduct['oid'])->field('sum(nums) as nums,sum(total_price) as total_price')->find();
$find = WarehouseProduct::where('oid', $oid)->field('sum(nums) as nums,sum(total_price) as total_price')->find();
if ($find) {
WarehouseOrder::where('id', $warehouseProduct['oid'])->update([
WarehouseOrder::where('id', $oid)->update([
'nums' => $find['nums'],
'total_price' => $find['total_price']
]);
}
self::updateStoreStorage2($warehouseProduct, $nums);
}
/**
@ -542,4 +531,23 @@ class WarehouseProductLogic extends BaseLogic
}
}
public static function updateProductSourceLink($warehouseProduct, $params, $updateNums)
{
$productSourceLinkInfoLogic = new ProductSourceLinkInfoLogic();
$productSourceLinkInfoLogic->setInfo([
'link_id' => $warehouseProduct['id'],
'product_id' => $warehouseProduct['product_id'],
'nums' => $params['nums'],
'add_nums' => $updateNums,
]);
if ($warehouseProduct['financial_pm'] == 1) {
$productSourceLinkInfoLogic->updateInStorageNum();
} else {
$productSourceLinkInfoLogic->setInfo([
'add_nums' => bcsub($params['nums'], $warehouseProduct['nums'],2),
]);
$productSourceLinkInfoLogic->updateOutboundNum();
}
}
}

View File

@ -3,6 +3,9 @@
namespace app\admin\logic\warehouse_product_return;
use app\admin\logic\product_source_link_info\ProductSourceLinkInfoLogic;
use app\admin\logic\warehouse_product\WarehouseProductLogic;
use app\common\model\product_source_link_info\ProductSourceLinkInfo;
use app\common\model\warehouse_product_return\WarehouseProductReturn;
use app\common\logic\BaseLogic;
use app\common\model\beforehand_order\BeforehandOrder;
@ -76,10 +79,6 @@ class WarehouseProductReturnLogic extends BaseLogic
throw new BusinessException('该商品库存:'.$params['nums'].'小于仓库库存'.$proudct['nums']);
}
}
// $offer = PurchaseProductOffer::where('order_id', $params['bhoid'])->where('product_id', $find['product_id'])->find();
// if (!$offer) {
// throw new BusinessException('该商品没有采购信息');
// }
$datas = [
'source_id' => $params['id'],
'bhoid' => $params['bhoid'] ?? 0,
@ -93,14 +92,19 @@ class WarehouseProductReturnLogic extends BaseLogic
'nums' => $params['nums'],
'return_type' => $params['return_type'],
'mark' => $params['mark'],
// 'price' => $offer['price'],
// 'total_price' => bcmul($params['nums'], $offer['price'], 2),
'price' => 0,
'total_price' => 0,
];
}
WarehouseProductReturn::create($datas);
$updateNums = bcsub($find['nums'], $params['nums'], 2);
if ($params['nums'] != 0) {
$numTemp = bcsub($find['nums'], $params['nums'], 2);
WarehouseProductLogic::updateProductSourceLink($find, array_merge($params, ['nums' => $numTemp]), $updateNums);
}
if ($params['financial_pm'] == 1 && $params['return_type'] == 1) {
$nums = bcsub($find['nums'], $params['nums'], 2);
$total_price = 0;
@ -109,13 +113,8 @@ class WarehouseProductReturnLogic extends BaseLogic
}
$find->save(['nums' => $nums, 'total_price' => $total_price]);
$total_price = WarehouseProduct::where('oid', $find['oid'])->sum('total_price');
if ($nums > 0) {
WarehouseOrder::where(['id' => $find['oid']])->update(['total_price' => $total_price]);
BeforehandOrder::update(['pay_price' => $total_price], ['id' => $params['bhoid']]);
} elseif ($nums == 0) {
WarehouseOrder::where(['id' => $find['oid']])->update(['total_price' => $total_price]);
BeforehandOrder::update(['pay_price' => $total_price], ['id' => $params['bhoid']]);
}
WarehouseOrder::where(['id' => $find['oid']])->update(['total_price' => $total_price]);
BeforehandOrder::update(['pay_price' => $total_price, 'total_price' => $total_price], ['id' => $params['bhoid']]);
$res=WarehouseProductStorege::where(['product_id' => $find['product_id'], 'warehouse_id' => $find['warehouse_id']])->find();
$res->save(['nums' =>bcadd( $res['nums'],$params['nums'],2)]);
SqlChannelLog('WarehouseProductStorege', $res['id'], $params['nums'], 1, Request()->url(),$params['admin_id']);

View File

@ -0,0 +1,79 @@
<?php
namespace app\admin\service;
use app\common\model\store_product\StoreProduct;
use app\common\model\StoreProductPriceList;
class ProductPriceService
{
/**
* 设置商品价格
* @param $purchasePrice float 采购价
* @param $productPriceRate array 价格比例
* @return array
*/
public function setProductPrice(float $purchasePrice, array $productPriceRate)
{
$result = [];
$result['purchase_lv'] = bcdiv($productPriceRate['supply_rate'], 100, 2);
$result['purchase'] = bcmul($purchasePrice, $result['purchase_lv'], 2);
$result['cost_lv'] = bcdiv($productPriceRate['merchant_rate'], 100, 2);
$result['cost'] = bcmul($result['purchase'], $result['cost_lv'], 2);
$result['vip_lv'] = bcdiv($productPriceRate['vip_rate'], 100, 2);
$result['vip_price'] = bcmul($result['purchase'], $result['vip_lv'], 2);
$result['price_lv'] = bcdiv($productPriceRate['price_rate'], 100, 2);
$result['price'] = bcmul($result['purchase'], $result['price_lv'], 2);
$lastNum = substr($result['price'], -1);
if ($lastNum > 0) {
$result['price'] = ceil($result['price'] * 10);
$result['price'] = bcdiv($result['price'], 10, 2);
}
$lastNum = substr($result['vip_price'], -1);
if ($lastNum > 0) {
$result['vip_price'] = ceil($result['vip_price'] * 10);
$result['vip_price'] = bcdiv($result['vip_price'], 10, 2);
}
return $result;
}
/**
* @param $productId int 商品id
* @param $percent bool 是否返回百分比
* @return array|int[]
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getProductPriceRate($productId, $percent = false)
{
$list = StoreProductPriceList::where('product_id', $productId)->findOrEmpty()->toArray();
$product = StoreProduct::where('id', $productId)->field('id,store_name,top_cate_id,cate_id')->find();
if (empty($list)) {
if ($product->isSpecial()) {
$list = [
'supply_rate' => 102,
'merchant_rate' => 102,
'vip_rate' => 104,
'price_rate' => 108,
];
} else {
$list = [
'supply_rate' => 105,
'merchant_rate' => 105,
'vip_rate' => 108,
'price_rate' => 112,
];
}
}
if ($percent) {
$list['supply_rate'] = $list['supply_rate'] / 100;
$list['merchant_rate'] = $list['merchant_rate'] / 100;
$list['vip_rate'] = $list['vip_rate'] / 100;
$list['price_rate'] = $list['price_rate'] / 100;
}
return $list;
}
}

View File

@ -0,0 +1,82 @@
<?php
namespace app\admin\validate;
use app\common\validate\BaseValidate;
/**
* PurchaseFunds验证器
* Class PurchaseFundsValidate
* @package app\admin\validate
*/
class PurchaseFundsValidate extends BaseValidate
{
/**
* 设置校验规则
* @var string[]
*/
protected $rule = [
'id' => 'require',
];
/**
* 参数描述
* @var string[]
*/
protected $field = [
'id' => 'id',
];
/**
* @notes 添加场景
* @return PurchaseFundsValidate
* @author admin
* @date 2025/03/19 14:59
*/
public function sceneAdd()
{
return $this->remove('id', true);
}
/**
* @notes 编辑场景
* @return PurchaseFundsValidate
* @author admin
* @date 2025/03/19 14:59
*/
public function sceneEdit()
{
return $this->only(['id']);
}
/**
* @notes 删除场景
* @return PurchaseFundsValidate
* @author admin
* @date 2025/03/19 14:59
*/
public function sceneDelete()
{
return $this->only(['id']);
}
/**
* @notes 详情场景
* @return PurchaseFundsValidate
* @author admin
* @date 2025/03/19 14:59
*/
public function sceneDetail()
{
return $this->only(['id']);
}
}

View File

@ -0,0 +1,82 @@
<?php
namespace app\admin\validate\product_image;
use app\common\validate\BaseValidate;
/**
* 商品图库管理验证器
* Class ProductImageValidate
* @package app\admin\validate\product_image
*/
class ProductImageValidate extends BaseValidate
{
/**
* 设置校验规则
* @var string[]
*/
protected $rule = [
'id' => 'require',
];
/**
* 参数描述
* @var string[]
*/
protected $field = [
'id' => 'id',
];
/**
* @notes 添加场景
* @return ProductImageValidate
* @author admin
* @date 2025/04/14 11:02
*/
public function sceneAdd()
{
return $this->remove('id', true);
}
/**
* @notes 编辑场景
* @return ProductImageValidate
* @author admin
* @date 2025/04/14 11:02
*/
public function sceneEdit()
{
return $this->only(['id']);
}
/**
* @notes 删除场景
* @return ProductImageValidate
* @author admin
* @date 2025/04/14 11:02
*/
public function sceneDelete()
{
return $this->only(['id']);
}
/**
* @notes 详情场景
* @return ProductImageValidate
* @author admin
* @date 2025/04/14 11:02
*/
public function sceneDetail()
{
return $this->only(['id']);
}
}

View File

@ -0,0 +1,82 @@
<?php
namespace app\admin\validate\product_source_link;
use app\common\validate\BaseValidate;
/**
* 商品溯源管理验证器
* Class ProductSourceLinkValidate
* @package app\admin\validate\product_source_link
*/
class ProductSourceLinkValidate extends BaseValidate
{
/**
* 设置校验规则
* @var string[]
*/
protected $rule = [
'id' => 'require',
];
/**
* 参数描述
* @var string[]
*/
protected $field = [
'id' => 'id',
];
/**
* @notes 添加场景
* @return ProductSourceLinkValidate
* @author admin
* @date 2025/03/12 10:03
*/
public function sceneAdd()
{
return $this->remove('id', true);
}
/**
* @notes 编辑场景
* @return ProductSourceLinkValidate
* @author admin
* @date 2025/03/12 10:03
*/
public function sceneEdit()
{
return $this->only(['id']);
}
/**
* @notes 删除场景
* @return ProductSourceLinkValidate
* @author admin
* @date 2025/03/12 10:03
*/
public function sceneDelete()
{
return $this->only(['id']);
}
/**
* @notes 详情场景
* @return ProductSourceLinkValidate
* @author admin
* @date 2025/03/12 10:03
*/
public function sceneDetail()
{
return $this->only(['id']);
}
}

View File

@ -0,0 +1,82 @@
<?php
namespace app\admin\validate\product_source_link_info;
use app\common\validate\BaseValidate;
/**
* 商品溯源详细验证器
* Class ProductSourceLinkInfoValidate
* @package app\admin\validate\product_source_link_info
*/
class ProductSourceLinkInfoValidate extends BaseValidate
{
/**
* 设置校验规则
* @var string[]
*/
protected $rule = [
'id' => 'require',
];
/**
* 参数描述
* @var string[]
*/
protected $field = [
'id' => 'id',
];
/**
* @notes 添加场景
* @return ProductSourceLinkInfoValidate
* @author admin
* @date 2025/03/12 10:08
*/
public function sceneAdd()
{
return $this->remove('id', true);
}
/**
* @notes 编辑场景
* @return ProductSourceLinkInfoValidate
* @author admin
* @date 2025/03/12 10:08
*/
public function sceneEdit()
{
return $this->only(['id']);
}
/**
* @notes 删除场景
* @return ProductSourceLinkInfoValidate
* @author admin
* @date 2025/03/12 10:08
*/
public function sceneDelete()
{
return $this->only(['id']);
}
/**
* @notes 详情场景
* @return ProductSourceLinkInfoValidate
* @author admin
* @date 2025/03/12 10:08
*/
public function sceneDetail()
{
return $this->only(['id']);
}
}

View File

@ -61,14 +61,100 @@ class IndexController extends BaseApiController
public function index()
{
// $arr=BeforehandOrderCartInfo::where('bhoid',1284)->select();
// foreach ($arr as $k=>$v){
// $product_id=StoreBranchProduct::where('id',$v['product_id'])->value('product_id');
// BeforehandOrderCartInfo::where('id',$v['id'])->update(['product_id'=>$product_id]);
// }
// $a=StoreOrderCartInfo::where('store_id',2)->whereBetweenTime('create_time','2025-01-01','2025-01-8')->select()->toArray();
// d($a);
// DemoLogic::test();
$arr=Db::connect('demo')->name('sheet1')->where('name','<>','')->limit(2)->select();
foreach ($arr as $k => $v) {
$find= Db::connect('demo')->name('store_product_unit')->where('value',$v['unit_name'])->find();
if(!$find){
$aa=['mer_id'=>7,'type'=>1,'value'=>$v['unit_name'],'status'=>1];
$id=Db::connect('demo')->name('store_product_unit')->insertGetId($aa);
}
$data=[
'mer_id'=>7,
'store_name'=>$v['name'],
'store_info'=>$v['name_tow'],
'cate_id'=>0,
'unit_name'=>$v['unit_name'],
'price'=>$v['price'],
'cost'=>$v['cost'],
'ot_price'=>0,
'image'=>$v['image'],
'slider_image'=>$v['image'],
'mer_svip_status'=>1,
'svip_price_type'=>2,
'svip_price'=>$v['cost'],
];
$product_id=Db::connect('demo')->name('store_product')->insertGetId($data);
$data2=[
'mer_id'=>7,
'product_id'=>$product_id,
'store_name'=>$v['name'],
'ot_price'=>0,
'image'=>$v['image'],
];
Db::connect('demo')->name('store_spu')->insert($data2);
$sku='';
$unique=substr(md5($sku . $product_id), 12, 10) . 0;
$data4=[
'product_id'=>$product_id,
'detail'=>'""',
'image'=>$v['image'],
'price'=>$v['price'],
'unique'=>$unique,
'svip_price'=>$v['cost'],
];
$vid=Db::connect('demo')->name('store_product_attr_value')->insertGetId($data4);
$json=[
'attr'=>[],
'attrValue'=>[
'value_id'=>$vid,
'product_id'=>$product_id,
'detail'=>'',
'sku'=>'',
'stock'=>0,
'brand_id'=>0,
'sales'>0,
'image'=>$v['image'],
'bar_code'=>'',
'cost'=>0,
'ot_price'=>0,
'price'=>$v['price'],
'svip_price'=>$v['cost'],
'weight'=>0,
'volume'=>0,
'type'=>0,
'extension_one'=>0,
'extension_two'=>0,
'unique'=>$unique,
'library_id'=>0,
'bar_code_number'=>'',
'is_default_select'=>0,
'is_show'=>1,
'productCdkey'=>[],
'select'=>1,
'list'=>[]
],
'params'=>[]
];
$data3=[
'product_id'=>$product_id,
'change_time'=>time(),
'result'=>json_encode($json),
];
Db::connect('demo')->name('store_product_attr_result')->insert($data3);
$data5=[
'product_id'=>$product_id,
'content'=>'',
'type'=>0,
];
Db::connect('demo')->name('store_product_content')->insert($data5);
}
d($arr);
d(1);
$arr = Db::name('ceshi_copy')->select();
foreach ($arr as $k => $v) {

View File

@ -85,6 +85,9 @@ class CartList extends BaseAdminDataLists implements ListsSearchInterface, Lists
if ($off_activity == 0 && $user_ship == 5 && $product['top_cate_id'] == 15189) {
$product['price'] = $product['cost'];
}
if ($user_ship == 4) {
$product['price'] = $product['cost'];
}
$item['goods_total_price'] = bcmul($item['cart_num'], $product['price'], 2);
$this->total_price = bcadd($this->total_price, $item['goods_total_price'], 2);
$item['batch'] = $product['batch'];

View File

@ -52,7 +52,7 @@ class OrderList extends BaseAdminDataLists implements ListsSearchInterface
->each(function ($item) {
$item['goods_list'] = StoreOrderCartInfo::where('oid', $item['id'])
->field('id,product_id,cart_num,verify_code,is_writeoff,writeoff_time,cart_info,status')
->limit(3)
// ->limit(3)
->select()
->each(function ($v) use ($item) {
$v['store_name'] = '';

View File

@ -125,6 +125,9 @@ class ProductLists extends BaseApiDataLists implements ListsSearchInterface, Lis
if ($off_activity == 0 && $user_ship == 5 && $item['top_cate_id'] == 15189) {
$item['price'] = $item['cost'];
}
if ($user_ship == 4) {
$item['price'] = $item['cost'];
}
if($item['is_lack']==1){
$tag='缺货';
}

View File

@ -546,6 +546,9 @@ class OrderLogic extends BaseLogic
if (empty($order)) {
throw new BusinessException('订单不存在');
}
if ($order['paid'] != 1) {
throw new BusinessException('订单未支付');
}
Db::startTrans();
try {
StoreOrder::update([

View File

@ -2,23 +2,19 @@
namespace app\common\logic;
use app\admin\logic\product_source_link_info\ProductSourceLinkInfoLogic;
use app\admin\logic\store_product\StoreProductLogic;
use app\admin\logic\user_ship\UserShipLogic;
use app\api\logic\order\OrderLogic;
use app\common\enum\OrderEnum;
use app\common\enum\PayEnum;
use app\common\enum\user\UserShipEnum;
use app\common\enum\YesNoEnum;
use app\common\logic\user_product_storage\UserProductStorageLogic;
use app\common\model\Config;
use app\common\model\dict\DictData;
use app\common\model\dict\DictType;
use app\common\model\finance\CapitalFlow;
use app\common\model\finance\PayNotifyLog;
use app\common\model\pay\PayNotify;
use app\common\model\product_source_link_info\ProductSourceLinkInfo;
use app\common\model\store_branch_product\StoreBranchProduct;
use app\common\model\store_cash_finance_flow\StoreCashFinanceFlow;
use app\common\model\store_finance_flow\StoreFinanceFlow;
use app\common\model\store_order\StoreOrder;
use app\common\model\store_order_cart_info\StoreOrderCartInfo;
use app\common\model\store_product\StoreProduct;
@ -28,13 +24,8 @@ use app\common\model\user\User;
use app\common\model\user\UserAddress;
use app\common\model\user\UserAuth;
use app\common\model\user\UserRecharge;
use app\common\model\user_ship\UserShip;
use app\common\model\user_sign\UserSign;
use app\common\model\vip_flow\VipFlow;
use app\common\service\Curl;
use app\common\service\PushService;
use app\common\service\xpyun\XpsdkPrintApi;
use app\Request;
use support\exception\BusinessException;
use support\Log;
use think\facade\Db;
@ -639,6 +630,21 @@ class PayNotifyLogic extends BaseLogic
'sales' => bcadd($branchProduct['sales'], $v['cart_num'], 2)
], ['id' => $branchProduct['id']]);
SqlChannelLog('StoreBranchProduct', $branchProduct['id'], $v['cart_num'], -1, Request()->url());
$productSourceLinkInfoLogic = new ProductSourceLinkInfoLogic();
$productSourceLinkInfoLogic->orderProduct = [
'product_id' => $v['product_id'],
'nums' => $v['cart_num'],
'price' => $branchProduct['price'],
'supply_price' => $branchProduct['purchase'],
];
$productSourceLinkInfoLogic->setInfo([
'is_store_order' => true,
'store_id' => $v['store_id'],
'link_id' => $v['id'],
'types' => ProductSourceLinkInfo::TypeOrder,
]);
$productSourceLinkInfoLogic->sale();
} else {
StoreProductLogic::ordinary(['id' => $v['product_id']], $v['store_id'], 0, $storeProduct);
StoreBranchProduct::update([

View File

@ -18,7 +18,7 @@ class BaseModel extends Model
*/
public function getImageAttr($value)
{
return trim($value) ? FileService::getFileUrl($value) : '';
return empty($value) ? '' : (trim($value) ? FileService::getFileUrl($value) : '');
}
/**
@ -30,7 +30,7 @@ class BaseModel extends Model
*/
public function setImageAttr($value)
{
return trim($value) ? FileService::setFileUrl($value) : '';
return empty($value) ? '' : (trim($value) ? FileService::setFileUrl($value) : '');
}
/**

View File

@ -0,0 +1,35 @@
<?php
namespace app\common\model;
use app\common\model\BaseModel;
/**
* PurchaseFunds模型
* Class PurchaseFunds
* @package app\common\model
*/
class PurchaseFunds extends BaseModel
{
protected $name = 'purchase_funds';
const StatusWait = 0; //待审核
const StatusApproved = 1; //审核通过
const StatusRejected = 2; //审核拒绝
public function getStatusName()
{
if ($this->status == self::StatusWait) {
return '待审核';
} else if ($this->status == self::StatusApproved) {
return '通过';
} else {
return '拒绝';
}
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace app\common\model\product_image;
use app\common\model\BaseModel;
use think\model\concern\SoftDelete;
/**
* 商品图库管理模型
* Class ProductImage
* @package app\common\model\product_image
*/
class ProductImage extends BaseModel
{
use SoftDelete;
protected $name = 'product_image';
protected $deleteTime = 'delete_time';
}

View File

@ -0,0 +1,37 @@
<?php
namespace app\common\model\product_source_link;
use app\common\model\BaseModel;
use app\common\model\delivery_service\DeliveryService;
use app\common\model\store_product\StoreProduct;
use app\common\model\warehouse\Warehouse;
use think\model\concern\SoftDelete;
/**
* 商品溯源管理模型
* Class ProductSourceLinkXsl
* @package app\common\model\product_source_link
*/
class ProductSourceLink extends BaseModel
{
use SoftDelete;
protected $name = 'product_source_link';
protected $deleteTime = 'delete_time';
public function product()
{
return $this->hasOne(StoreProduct::class, 'id', 'product_id')->bind(['product_name' => 'store_name', 'image']);
}
public function warehouse(){
return $this->hasOne(Warehouse::class, 'id', 'warehouse_id')->bind(['warehouse_name'=>'name']);
}
public function purchase(){
return $this->hasOne(DeliveryService::class, 'uid', 'purchase_uid')->bind(['purchase_nickname'=>'nickname']);
}
}

View File

@ -0,0 +1,53 @@
<?php
namespace app\common\model\product_source_link_info;
use app\common\model\BaseModel;
use app\common\model\store_product\StoreProduct;
use think\model\concern\SoftDelete;
/**
* 商品溯源详细模型
* Class ProductSourceLinkInfo
* @package app\common\model\product_source_link_info
*/
class ProductSourceLinkInfo extends BaseModel
{
use SoftDelete;
protected $name = 'product_source_link_info';
protected $deleteTime = 'delete_time';
const TypeIn = 1;
const TypeOut = 2;
const TypeStoreIn = 3;
const TypeOrder = 4;
const TypeOrderRefund = 5;
const TypeS2W = 6;
const TypeS2S = 7;
const TypeW2W = 8;
const TypeStoreOut = 301;
public function getTypeName()
{
$typeMap = [
self::TypeIn => '仓库入库',
self::TypeOut => '仓库出库',
self::TypeStoreIn => '门店入库',
self::TypeStoreOut => '门店退库',
self::TypeOrder => '订单出库',
self::TypeOrderRefund => '订单退货入库',
self::TypeS2W => '门店调拨至仓库',
self::TypeS2S => '门店调拨至门店',
self::TypeW2W => '仓库调拨至仓库',
];
return $typeMap[$this->getAttr('types')];
}
public function product()
{
return $this->hasOne(StoreProduct::class, 'id', 'product_id')->bind(['product_name' => 'store_name', 'image']);
}
}

View File

@ -55,4 +55,13 @@ class StoreProduct extends BaseModel
Log::error('product:'.$e->getMessage());
}
}
public function isSpecial()
{
if (in_array($this->top_cate_id, [15189, 6]) || in_array($this->cate_id, [15551, 15552,15569,15570]) || mb_strpos($this->store_name, '鸡精') !== false || mb_strpos($this->store_name, '生抽') !== false || mb_strpos($this->store_name, '多宝鱼') !== false || mb_strpos($this->store_name, '小青虾') !== false) {
return true;
}
return false;
}
}

View File

@ -24,4 +24,9 @@ class StoreProductPrice extends BaseModel
// 不生成该表的日志
public $doNotRecordLog = true;
public function product()
{
return $this->hasOne(StoreProduct::class, 'id', 'product_id')->field('id,store_name,top_cate_id,two_cate_id,cate_id');
}
}

View File

@ -0,0 +1,111 @@
<?php
namespace app\common\service\xlsx;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Border;
use Webman\Exception\BusinessException;
class InventoryTransferXlsx
{
public function export($data, $order)
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setTitle('调拨订单'); // 设置列宽
$sheet->getDefaultRowDimension()->setRowHeight(20); // 设置行高
$sheet->getDefaultColumnDimension()->setWidth(20); // 设置列宽
$sheet->getPageSetup()->setFitToPage(true); // 自动适应页面大小
$sheet->getPageSetup()->setHorizontalCentered(true); // 页面水平居中
$sheet->getPageSetup()->setVerticalCentered(true); // 页面垂直居中
$sheet->getPageMargins()->setTop(0.5); // 上边距
$sheet->getPageMargins()->setBottom(0.5); // 下边距
$sheet->getPageMargins()->setLeft(0.5); // 左边距
$sheet->getPageMargins()->setRight(0.5); // 右边距
$sheet->getPageMargins()->setHeader(0.5); // 页眉边距
$sheet->getPageMargins()->setFooter(0.5); // 页脚边距
$sheet->getStyle('A1:H1')->getFont()->setBold(true); // 设置标题字体加粗
$sheet->getStyle('A1:H1')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER); // 设置标题水平居中
$sheet->getStyle('A1:H1')->getAlignment()->setVertical(Alignment::VERTICAL_CENTER); // 设置标题垂直居中
$sheet->getStyle('A2:H2')->getFont()->setBold(true); // 设置标题字体加粗
$sheet->getStyle('A2:H2')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER); // 设置标题水平居中
// 合并单元格并设置标题
$sheet->mergeCells('A1:G1')->setCellValue('A1', '调拨订单');
$sheet->setCellValue('A2', '订单编号');
$sheet->setCellValue('B2', '转出方');
$sheet->setCellValue('C2', '方式');
$sheet->setCellValue('D2', '转入方');
$sheet->setCellValue('E2', '商品');
$sheet->setCellValue('F2', '数量');
$sheet->setCellValue('G2', '备注');
$sheet->setCellValue('H2', '创建时间');
// 设置列宽
$sheet->getColumnDimension('A')->setAutoSize(true);
$sheet->getColumnDimension('B')->setAutoSize(true);
$sheet->getColumnDimension('C')->setWidth(20);
$sheet->getColumnDimension('D')->setWidth(20);
$sheet->getColumnDimension('E')->setAutoSize(true);
$sheet->getColumnDimension('F')->setAutoSize(true);
$sheet->getColumnDimension('G')->setAutoSize(true);
$sheet->getColumnDimension('H')->setAutoSize(true);
// 设置默认的单元格样式
$defaultStyle = [
'alignment' => [
'horizontal' => Alignment::HORIZONTAL_CENTER,
'vertical' => Alignment::VERTICAL_CENTER,
],
];
$spreadsheet->getDefaultStyle()->applyFromArray($defaultStyle);
// 写入数据
$row = 3;
foreach ($data as $item) {
$sheet->setCellValue('A' . $row, $order['order_id'])
->setCellValue('B' . $row, $order['one_name'])
->setCellValue('C' . $row, $order['type_name'])
->setCellValue('D' . $row, $order['two_name'])
->setCellValue('E' . $row, $item['store_name'])
->setCellValue('F' . $row, $item['nums'])
->setCellValue('G' . $row, $item['remark'])
->setCellValue('H' . $row, $item['create_time']);
$row++;
}
$count = count($data);
// 应用默认样式到整个工作表
// 设置单元格的样式
$styleArray = [
'font' => [
'bold' => true,
'size' => 16,
],
];
$sheet->getStyle('A1')->applyFromArray($styleArray);
// 定义线框样式
$styleArray = [
'borders' => [
'allBorders' => [
'borderStyle' => Border::BORDER_THIN, // 线框样式
'color' => ['argb' => '000000'], // 线框颜色
],
],
];
$sheet->getStyle('A1:H' . ($count + 2))->applyFromArray($styleArray);
// 保存文件到 public 下
$writer = new Xlsx($spreadsheet);
$url = '/export/' . "调拨订单-" . date('YmdHi') . '.xlsx';
$file_path = public_path() . $url;
if (!is_dir(dirname($file_path))) {
mkdir(dirname($file_path), 0777, true);
}
$writer->save($file_path);
return getenv('APP_URL') . $url;
}
}

View File

@ -48,10 +48,10 @@ class OrderSupplyOutbound
$sheet->setCellValue('B3', '品名');
$sheet->setCellValue('C3', '单位');
$sheet->setCellValue('D3', '数量');
$sheet->setCellValue('E3', '出库单价');
$sheet->setCellValue('F3', '出库总价');
$sheet->setCellValue('G3', '供货价');
$sheet->setCellValue('H3', '供货总价');
$sheet->setCellValue('E3', '进货单价');
$sheet->setCellValue('F3', '进货总价');
$sheet->setCellValue('G3', '零售单价');
$sheet->setCellValue('H3', '零售总价');
$sheet->setCellValue('I3', '利润');
$sheet->setCellValue('J3', '备注');
@ -71,10 +71,10 @@ class OrderSupplyOutbound
$sheet->setCellValue('B' . ($k + 4), $v['store_name']);
$sheet->setCellValue('C' . ($k + 4), $v['unit_name']);
$sheet->setCellValue('D' . ($k + 4), $v['nums']);
$sheet->setCellValue('E' . ($k + 4), $v['price']);
$sheet->setCellValue('F' . ($k + 4), $v['total_price']);
$sheet->setCellValue('G' . ($k + 4), $v['purchase']);
$sheet->setCellValue('H' . ($k + 4), $v['pay_price']);
$sheet->setCellValue('E' . ($k + 4), $v['purchase']);
$sheet->setCellValue('F' . ($k + 4), $v['pay_price']);
$sheet->setCellValue('G' . ($k + 4), $v['price']);
$sheet->setCellValue('H' . ($k + 4), $v['total_price']);
$sheet->setCellValue('I' . ($k + 4), $v['profit']);
$sheet->mergeCells('J' . ($k + 4) . ':K' . $k + 4);
$sheet->setCellValue('J' . ($k + 4), $v['mark']);
@ -84,7 +84,7 @@ class OrderSupplyOutbound
$sheet->setCellValue('A' . ($count + 4),'合计');
$sheet->setCellValue('B' . ($count + 4),$count);
$sheet->setCellValue('J' . ($count + 4),$order['group_title']??'');
// $sheet->setCellValue('J' . ($count + 4),$order['group_title']??'');
$sheet->setCellValue('A' . ($count + 5),'累计接单:');
$sheet->setCellValue('C' . ($count + 5),'预收金额:');

View File

@ -0,0 +1,75 @@
<?php
namespace app\common\service\xlsx;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use Webman\Exception\BusinessException;
/**
* 订单出库
*/
class ProductSourceLinkXsl
{
public function export($data)
{
$title = '商品溯源信息';
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->mergeCells('A1:F1');
$sheet->setCellValue('A1', $title);
$sheet->setCellValue('A2', '商品ID:');
$sheet->setCellValue('B2', '商品名称:');
$sheet->setCellValue('C2', '入库数量:');
$sheet->setCellValue('D2', '出库数量');
$sheet->setCellValue('E2', '入库单号:');
$sheet->setCellValue('F2', '出库单号:');
// 设置默认的单元格样式
$defaultStyle = [
'alignment' => [
'horizontal' => Alignment::HORIZONTAL_CENTER,
'vertical' => Alignment::VERTICAL_CENTER,
],
];
// 应用默认样式到整个工作表
$spreadsheet->getDefaultStyle()->applyFromArray($defaultStyle);
foreach ($data as $k => $v) {
$sheet->setCellValue('A' . ($k + 3), $v['product_id']);
$sheet->setCellValue('B' . ($k + 3), $v['product_name']);
$sheet->setCellValue('C' . ($k + 3), $v['in_num']);
$sheet->setCellValue('D' . ($k + 3), $v['out_num']);
$sheet->setCellValue('E' . ($k + 3), $v['in_order_no']);
$sheet->setCellValue('F' . ($k + 3), $v['out_order_no']);
}
// 设置单元格的样式
$styleArray = [
'font' => [
'bold' => true,
'size' => 16,
],
];
$sheet->getStyle('A1')->applyFromArray($styleArray);
$writer = new Xlsx($spreadsheet);
$dir = public_path() . '/export/' . date('Y-m');
if (!file_exists($dir)) {
// 尝试创建目录
if (!mkdir($dir)) {
throw new BusinessException('创建目录失败:/export/' . date('Y-m'));
}
}
$file_path = $dir . '/' . $title . date('Y年m月d日H时i分') . '.xlsx';
$url = '/export/' . date('Y-m') . '/' . $title . date('Y年m月d日H时i分') . '.xlsx';
// 保存文件到 public 下
$writer->save($file_path);
return getenv('APP_URL') . $url;
}
}

View File

@ -583,4 +583,31 @@ function SqlChannelPriceLog($product_id=0, $group_id=0, $before_price=0,$after_p
// $orderId = $type . date('YmdHis', time());
// return $orderId;
// }
// }
// }
if (!function_exists('list2tree')) {
function list2tree(array $list, $idKey = 'id', $parentKey = 'pid', $childrenKey = 'children')
{
$tree = [];
$itemsByReference = [];
// 首先将所有项目按id存入引用数组
foreach ($list as &$item) {
$itemsByReference[$item[$idKey]] = &$item;
$item[$childrenKey] = [];
}
// 构建树
foreach ($list as &$item) {
if ($item[$parentKey] && isset($itemsByReference[$item[$parentKey]])) {
$itemsByReference[$item[$parentKey]][$childrenKey][] = &$item;
} else {
$tree[] = &$item;
}
}
return $tree;
}
}

View File

@ -58,7 +58,8 @@
"picqer/php-barcode-generator": "^2.4",
"overtrue/easy-sms": "^2.6",
"phpoffice/phpword": "^1.3",
"chance-fyi/operation-log": "^3.0"
"chance-fyi/operation-log": "^3.0",
"tencentcloud/tencentcloud-sdk-php": "^3.0"
},
"suggest": {
"ext-event": "For better performance. "

56
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "005401e7f7b2cce665fa8d6a9a1cb808",
"content-hash": "e0a6dbafa795991cf0ffd520af434c5c",
"packages": [
{
"name": "aliyuncs/oss-sdk-php",
@ -6760,6 +6760,56 @@
},
"time": "2022-08-27T08:29:08+00:00"
},
{
"name": "tencentcloud/tencentcloud-sdk-php",
"version": "3.0.1356",
"source": {
"type": "git",
"url": "https://github.com/TencentCloud/tencentcloud-sdk-php.git",
"reference": "927db31908964673afd2691528dda135e29c3e9a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/TencentCloud/tencentcloud-sdk-php/zipball/927db31908964673afd2691528dda135e29c3e9a",
"reference": "927db31908964673afd2691528dda135e29c3e9a",
"shasum": ""
},
"require": {
"guzzlehttp/guzzle": "^6.3 || ^7.0",
"php": ">=5.6.0"
},
"require-dev": {
"phpunit/phpunit": "^9.5"
},
"type": "library",
"autoload": {
"psr-4": {
"TencentCloud\\": "./src/TencentCloud"
},
"classmap": [
"src/QcloudApi/QcloudApi.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "coolli",
"email": "tencentcloudapi@tencent.com",
"homepage": "https://cloud.tencent.com/document/sdk/PHP",
"role": "Developer"
}
],
"description": "TencentCloudApi php sdk",
"homepage": "https://github.com/TencentCloud/tencentcloud-sdk-php",
"support": {
"issues": "https://github.com/TencentCloud/tencentcloud-sdk-php/issues",
"source": "https://github.com/TencentCloud/tencentcloud-sdk-php/tree/3.0.1356"
},
"time": "2025-04-07T20:07:18+00:00"
},
{
"name": "thenorthmemory/xml",
"version": "1.1.1",
@ -8112,7 +8162,7 @@
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"stability-flags": {},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
@ -8120,6 +8170,6 @@
"ext-json": "*",
"ext-bcmath": "*"
},
"platform-dev": [],
"platform-dev": {},
"plugin-api-version": "2.6.0"
}

View File

@ -55,7 +55,7 @@ return [
// 数据库编码默认采用utf8
'charset' => 'utf8mb4',
// 数据库表前缀
'prefix' => 'la_',
'prefix' => 'eb_',
],
],
];

1
public/output.text Normal file

File diff suppressed because one or more lines are too long

View File

@ -32,6 +32,11 @@ class InstalledVersions
*/
private static $installed;
/**
* @var bool
*/
private static $installedIsLocalDir;
/**
* @var bool|null
*/
@ -309,6 +314,12 @@ class InstalledVersions
{
self::$installed = $data;
self::$installedByVendor = array();
// when using reload, we disable the duplicate protection to ensure that self::$installed data is
// always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not,
// so we have to assume it does not, and that may result in duplicate data being returned when listing
// all installed packages for example
self::$installedIsLocalDir = false;
}
/**
@ -322,19 +333,27 @@ class InstalledVersions
}
$installed = array();
$copiedLocalDir = false;
if (self::$canGetVendors) {
$selfDir = strtr(__DIR__, '\\', '/');
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
$vendorDir = strtr($vendorDir, '\\', '/');
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require $vendorDir.'/composer/installed.php';
$installed[] = self::$installedByVendor[$vendorDir] = $required;
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
self::$installed = $installed[count($installed) - 1];
self::$installedByVendor[$vendorDir] = $required;
$installed[] = $required;
if (self::$installed === null && $vendorDir.'/composer' === $selfDir) {
self::$installed = $required;
self::$installedIsLocalDir = true;
}
}
if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) {
$copiedLocalDir = true;
}
}
}
@ -350,7 +369,7 @@ class InstalledVersions
}
}
if (self::$installed !== array()) {
if (self::$installed !== array() && !$copiedLocalDir) {
$installed[] = self::$installed;
}

View File

@ -21,6 +21,7 @@ return array(
'Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php',
'Override' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/Override.php',
'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
'QcloudApi' => $vendorDir . '/tencentcloud/tencentcloud-sdk-php/src/QcloudApi/QcloudApi.php',
'ReturnTypeWillChange' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php',
'SQLite3Exception' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/SQLite3Exception.php',
'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',

View File

@ -7,7 +7,7 @@ $baseDir = dirname($vendorDir);
return array(
'voku\\' => array($vendorDir . '/voku/portable-ascii/src/voku'),
'think\\' => array($vendorDir . '/topthink/think-container/src', $vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src'),
'think\\' => array($vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/think-container/src', $vendorDir . '/topthink/think-helper/src'),
'taoser\\' => array($vendorDir . '/taoser/webman-validate/src'),
'support\\' => array($vendorDir . '/workerman/webman-framework/src/support'),
'app\\View\\Components\\' => array($baseDir . '/app/view/components'),
@ -30,6 +30,7 @@ return array(
'Tinywan\\Storage\\' => array($vendorDir . '/tinywan/storage/src'),
'Tinywan\\Jwt\\' => array($vendorDir . '/tinywan/jwt/src'),
'TheNorthMemory\\Xml\\' => array($vendorDir . '/thenorthmemory/xml/src'),
'TencentCloud\\' => array($vendorDir . '/tencentcloud/tencentcloud-sdk-php/src/TencentCloud'),
'Symfony\\Polyfill\\Php83\\' => array($vendorDir . '/symfony/polyfill-php83'),
'Symfony\\Polyfill\\Php81\\' => array($vendorDir . '/symfony/polyfill-php81'),
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
@ -86,7 +87,7 @@ return array(
'Invoker\\' => array($vendorDir . '/php-di/invoker/src'),
'Intervention\\Image\\' => array($vendorDir . '/intervention/image/src'),
'Intervention\\Gif\\' => array($vendorDir . '/intervention/gif/src'),
'Illuminate\\Support\\' => array($vendorDir . '/illuminate/collections', $vendorDir . '/illuminate/conditionable', $vendorDir . '/illuminate/macroable', $vendorDir . '/illuminate/support'),
'Illuminate\\Support\\' => array($vendorDir . '/illuminate/support', $vendorDir . '/illuminate/collections', $vendorDir . '/illuminate/conditionable', $vendorDir . '/illuminate/macroable'),
'Illuminate\\Redis\\' => array($vendorDir . '/illuminate/redis'),
'Illuminate\\Contracts\\' => array($vendorDir . '/illuminate/contracts'),
'Hyperf\\Pimple\\' => array($vendorDir . '/hyperf/pimple/src'),

View File

@ -91,6 +91,7 @@ class ComposerStaticInitcefecbcff919f3c1c8084830bbb72adc
'Tinywan\\Storage\\' => 16,
'Tinywan\\Jwt\\' => 12,
'TheNorthMemory\\Xml\\' => 19,
'TencentCloud\\' => 13,
),
'S' =>
array (
@ -235,9 +236,9 @@ class ComposerStaticInitcefecbcff919f3c1c8084830bbb72adc
),
'think\\' =>
array (
0 => __DIR__ . '/..' . '/topthink/think-container/src',
1 => __DIR__ . '/..' . '/topthink/think-helper/src',
2 => __DIR__ . '/..' . '/topthink/think-orm/src',
0 => __DIR__ . '/..' . '/topthink/think-orm/src',
1 => __DIR__ . '/..' . '/topthink/think-container/src',
2 => __DIR__ . '/..' . '/topthink/think-helper/src',
),
'taoser\\' =>
array (
@ -327,6 +328,10 @@ class ComposerStaticInitcefecbcff919f3c1c8084830bbb72adc
array (
0 => __DIR__ . '/..' . '/thenorthmemory/xml/src',
),
'TencentCloud\\' =>
array (
0 => __DIR__ . '/..' . '/tencentcloud/tencentcloud-sdk-php/src/TencentCloud',
),
'Symfony\\Polyfill\\Php83\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php83',
@ -554,10 +559,10 @@ class ComposerStaticInitcefecbcff919f3c1c8084830bbb72adc
),
'Illuminate\\Support\\' =>
array (
0 => __DIR__ . '/..' . '/illuminate/collections',
1 => __DIR__ . '/..' . '/illuminate/conditionable',
2 => __DIR__ . '/..' . '/illuminate/macroable',
3 => __DIR__ . '/..' . '/illuminate/support',
0 => __DIR__ . '/..' . '/illuminate/support',
1 => __DIR__ . '/..' . '/illuminate/collections',
2 => __DIR__ . '/..' . '/illuminate/conditionable',
3 => __DIR__ . '/..' . '/illuminate/macroable',
),
'Illuminate\\Redis\\' =>
array (
@ -718,6 +723,7 @@ class ComposerStaticInitcefecbcff919f3c1c8084830bbb72adc
'Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php',
'Override' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/Override.php',
'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
'QcloudApi' => __DIR__ . '/..' . '/tencentcloud/tencentcloud-sdk-php/src/QcloudApi/QcloudApi.php',
'ReturnTypeWillChange' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php',
'SQLite3Exception' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/SQLite3Exception.php',
'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',

View File

@ -6739,6 +6739,59 @@
},
"install-path": "../taoser/webman-validate"
},
{
"name": "tencentcloud/tencentcloud-sdk-php",
"version": "3.0.1356",
"version_normalized": "3.0.1356.0",
"source": {
"type": "git",
"url": "https://github.com/TencentCloud/tencentcloud-sdk-php.git",
"reference": "927db31908964673afd2691528dda135e29c3e9a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/TencentCloud/tencentcloud-sdk-php/zipball/927db31908964673afd2691528dda135e29c3e9a",
"reference": "927db31908964673afd2691528dda135e29c3e9a",
"shasum": ""
},
"require": {
"guzzlehttp/guzzle": "^6.3 || ^7.0",
"php": ">=5.6.0"
},
"require-dev": {
"phpunit/phpunit": "^9.5"
},
"time": "2025-04-07T20:07:18+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"TencentCloud\\": "./src/TencentCloud"
},
"classmap": [
"src/QcloudApi/QcloudApi.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "coolli",
"email": "tencentcloudapi@tencent.com",
"homepage": "https://cloud.tencent.com/document/sdk/PHP",
"role": "Developer"
}
],
"description": "TencentCloudApi php sdk",
"homepage": "https://github.com/TencentCloud/tencentcloud-sdk-php",
"support": {
"issues": "https://github.com/TencentCloud/tencentcloud-sdk-php/issues",
"source": "https://github.com/TencentCloud/tencentcloud-sdk-php/tree/3.0.1356"
},
"install-path": "../tencentcloud/tencentcloud-sdk-php"
},
{
"name": "thenorthmemory/xml",
"version": "1.1.1",

View File

@ -902,6 +902,15 @@
'aliases' => array(),
'dev_requirement' => false,
),
'tencentcloud/tencentcloud-sdk-php' => array(
'pretty_version' => '3.0.1356',
'version' => '3.0.1356.0',
'reference' => '927db31908964673afd2691528dda135e29c3e9a',
'type' => 'library',
'install_path' => __DIR__ . '/../tencentcloud/tencentcloud-sdk-php',
'aliases' => array(),
'dev_requirement' => false,
),
'thenorthmemory/xml' => array(
'pretty_version' => '1.1.1',
'version' => '1.1.1.0',

View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,230 @@
# 简介
欢迎使用腾讯云开发者工具套件SDK3.0SDK3.0是云 API3.0 平台的配套工具。
为方便 PHP 开发者调试和接入腾讯云产品 API这里向您介绍适用于 PHP 的腾讯云开发工具包,并提供首次使用开发工具包的简单示例。让您快速获取腾讯云 PHP SDK 并开始调用。
# 依赖环境
1. PHP 5.6.0 版本及以上
2. 从腾讯云控制台 开通相应产品
3. 获取 SecretID、SecretKey 以及调用地址endpointendpoint 一般形式为 \*.tencentcloudapi.com如CVM 的调用地址为 cvm.tencentcloudapi.com具体参考各产品说明。
# 获取安装
安装 PHP SDK 前先获取安全凭证。在第一次使用云API之前用户首先需要在腾讯云控制台上申请安全凭证安全凭证包括 SecretID 和 SecretKey SecretID 是用于标识 API 调用者的身份SecretKey是用于加密签名字符串和服务器端验证签名字符串的密钥。SecretKey 必须严格保管,避免泄露。
## 通过 Composer 安装
通过 Composer 获取安装是使用 PHP SDK 的推荐方法Composer 是 PHP 的依赖管理工具,支持您项目所需的依赖项,并将其安装到项目中。关于 Composer 详细可参考 Composer 官网 。
安装Composer
windows环境请访问[Composer官网](https://getcomposer.org/download/)下载安装包安装。
unix环境在命令行中执行以下命令安装。
> curl -sS https://getcomposer.org/installer | php
> sudo mv composer.phar /usr/local/bin/composer
### 安装指定产品 SDK推荐
例如:安装指定产品包
```bash
composer require tencentcloud/指定产品包名缩写 # 如 CVM 产品包tencentcloud/cvm
```
具体产品的包名缩写请参考 [products.md](./products.md) 中的包名字段。
### 安装全产品 SDK
```bash
composer require tencentcloud/tencentcloud-sdk-php
```
全产品 SDK 包含了所有云产品的调用代码,体积偏大,对体积敏感的场景,推荐安装指定产品 SDK。
### 注意事项
- 安装全产品 SDK 和安装指定产品的 SDK 两种方式只能选择其中一种。
- 如果同时安装多个产品的包,建议多个产品的包和 common 包保持在同一个版本。
- 无法使用官方源的的用户可以设置镜像源,例如:`composer config -g repos.packagist composer https://mirrors.tencent.com/composer/`
- 推荐使用固定的 SDK 版本开发测试和发布应用,例如 `composer require tencentcloud/cvm=xx.yy.zz`。如果不需要 phpunit 等开发依赖,可以指定 `--update-no-dev` 选项。
- 在代码中添加以下引用代码。注意如下仅为示例composer 会在项目根目录下生成 vendor 目录,`/path/to/`为项目根目录的实际绝对路径,如果是在当前目录执行,可以省略绝对路径。
> require '/path/to/vendor/autoload.php';
# 示例
推荐使用 [API 3.0 Explorer](https://console.cloud.tencent.com/api/explorer)提供在线调用、签名验证、SDK 代码生成和快速检索接口等能力,能显著降低使用云 API 3.0 和 SDK 的难度。
还可以参考 SDK 仓库中 [examples](https://github.com/TencentCloud/tencentcloud-sdk-php/tree/master/examples) 目录中的示例,展示了更多的用法。
下面以查询实例接口DescribeInstances为例:
### 简略版
```php
<?php
require_once '/path/to/vendor/autoload.php';
use TencentCloud\Cvm\V20170312\CvmClient;
use TencentCloud\Cvm\V20170312\Models\DescribeInstancesRequest;
use TencentCloud\Common\Exception\TencentCloudSDKException;
use TencentCloud\Common\Credential;
try {
// 为了保护密钥安全,建议将密钥设置在环境变量中或者配置文件中。
// 硬编码密钥到代码中有可能随代码泄露而暴露,有安全隐患,并不推荐。
// $cred = new Credential("SecretId", "SecretKey");
$cred = new Credential(getenv("TENCENTCLOUD_SECRET_ID"),
getenv("TENCENTCLOUD_SECRET_KEY"));
$client = new CvmClient($cred, "ap-guangzhou");
$req = new DescribeInstancesRequest();
$resp = $client->DescribeInstances($req);
print_r($resp->toJsonString());
}
catch(TencentCloudSDKException $e) {
echo $e;
}
```
### 详细版
```php
<?php
require_once '/path/to/vendor/autoload.php';
// 导入对应产品模块的client
use TencentCloud\Cvm\V20170312\CvmClient;
// 导入要请求接口对应的Request类
use TencentCloud\Cvm\V20170312\Models\DescribeInstancesRequest;
use TencentCloud\Cvm\V20170312\Models\Filter;
use TencentCloud\Common\Exception\TencentCloudSDKException;
use TencentCloud\Common\Credential;
// 导入可选配置类
use TencentCloud\Common\Profile\ClientProfile;
use TencentCloud\Common\Profile\HttpProfile;
try {
// 实例化一个证书对象,入参需要传入腾讯云账户 SecretIdSecretKey
// 为了保护密钥安全,建议将密钥设置在环境变量中或者配置文件中。
// 硬编码密钥到代码中有可能随代码泄露而暴露,有安全隐患,并不推荐。
// $cred = new Credential("SecretId", "SecretKey");
$cred = new Credential(getenv("TENCENTCLOUD_SECRET_ID"),
getenv("TENCENTCLOUD_SECRET_KEY"));
// 实例化一个http选项可选的没有特殊需求可以跳过
$httpProfile = new HttpProfile();
// 配置代理
// $httpProfile->setProxy("https://ip:port");
$httpProfile->setReqMethod("GET"); // post请求(默认为post请求)
$httpProfile->setReqTimeout(30); // 请求超时时间,单位为秒(默认60秒)
$httpProfile->setEndpoint("cvm.ap-shanghai.tencentcloudapi.com"); // 指定接入地域域名(默认就近接入)
// 实例化一个client选项可选的没有特殊需求可以跳过
$clientProfile = new ClientProfile();
$clientProfile->setSignMethod("TC3-HMAC-SHA256"); // 指定签名算法(默认为HmacSHA256)
$clientProfile->setHttpProfile($httpProfile);
// 实例化要请求产品(以cvm为例)的client对象,clientProfile是可选的
$client = new CvmClient($cred, "ap-shanghai", $clientProfile);
// 实例化一个cvm实例信息查询请求对象,每个接口都会对应一个request对象。
$req = new DescribeInstancesRequest();
// 填充请求参数,这里request对象的成员变量即对应接口的入参
// 您可以通过官网接口文档或跳转到request对象的定义处查看请求参数的定义
$respFilter = new Filter(); // 创建Filter对象, 以zone的维度来查询cvm实例
$respFilter->Name = "zone";
$respFilter->Values = ["ap-shanghai-1", "ap-shanghai-2"];
$req->Filters = [$respFilter]; // Filters 是成员为Filter对象的列表
// 通过client对象调用DescribeInstances方法发起请求。注意请求方法名与请求对象是对应的
// 返回的resp是一个DescribeInstancesResponse类的实例与请求对象对应
$resp = $client->DescribeInstances($req);
// 输出json格式的字符串回包
print_r($resp->toJsonString());
// 也可以取出单个值。
// 您可以通过官网接口文档或跳转到response对象的定义处查看返回字段的定义
print_r($resp->TotalCount);
}
catch(TencentCloudSDKException $e) {
echo $e;
}
```
## Common Client
从 3.0.839 版本起,支持通用请求方式 Common Client可以发起 SDK 中未定义的接口请求。
注意:目前仅支持 POST 方法,签名方法仅支持签名方法 v3。
请参考 [调用示例](https://github.com/TencentCloud/tencentcloud-sdk-php/tree/master/examples/common/CommonClient.php)
# 常见问题
## 代理
如果是有代理的环境下,需要设置系统环境变量 `https_proxy` ,否则可能无法正常调用,抛出连接超时的异常。
或者使用 GuzzleHttp 代理配置:
```php
$httpProfile = new HttpProfile();
$httpProfile->setProxy('https://ip:port');
$clientProfile = new ClientProfile();
$clientProfile->setHttpProfile($httpProfile);
$client = new OcrClient($cred, 'ap-beijing', $this->clientProfile);
```
## 地域容灾
`3.0.933`起 腾讯云 Php SDK 支持地域容灾,当某个域名请求失败时,会自动切换到容灾域名。使用方式如下:
使用地域时有三种状态相互转换:关闭、全开和半开状态
关闭:使用主要域名请求,如果出现错误时,会切换到全开状态
全开:使用容灾域名请求,当达到一定时间时,会切换到半开状态
半开:此时会放少量的请求到主要域名,如果请求失败,则切换到全开状态,当请求成功数达到一定的数量时,会切换到关闭状态
相关设置如下
```php
use TencentCloud\Common\Profile\RegionBreakerProfile;
// 开启地域容灾
$clientProfile->enableRegionBreaker=true;
// 设置主备节点以cvm产品为例假设主节点在上海备节点在北京则配置如下
$regionBreakerProfile = new RegionBreakerProfile(
"cvm.ap-shanghai.tencentcloudapi.com", // 主节点
"cvm.ap-beijing.tencentcloudapi.com" // 备节点
);
$clientProfile->setRegionBreakerProfile($regionBreakerProfile);
```
## 证书问题
如果您的 PHP 环境证书有问题,可能会遇到报错,类似于 `cURL error 60: See http://curl.haxx.se/libcurl/c/libcurl-errors.html`,请尝试按如下步骤解决:
1. 到 [https://curl.haxx.se/ca/cacert.pem](https://curl.haxx.se/ca/cacert.pem) 下载证书文件 `cacert.pem`,将其保存到 PHP 安装路径下。
2. 编辑 `php.ini` 文件,删除 `curl.cainfo` 配置项前的分号注释符(;),值设置为保存的证书文件 `cacert.pem` 的绝对路径。
3. 重启依赖 PHP 的服务。
## php_curl 扩展
此 SDK 依赖的 GuzzleHttp 需要开启 php_curl 扩展,查看环境上的 php.ini 环境确认是否已启用,例如在 Linux 环境下PHP 7.1 版本,托管在 apache 下的服务,可以打开 /etc/php/7.1/apache2/php.ini 中查看 extension=php_curl.dll 配置项是否已被注释,请删除此项配置前的注释符并重启 apache。
## Web 访问异常
命令行下执行正常,但是放在 Web 服务器执行则报错:
cURL error 0: The cURL request was retried 3 times and did not succeed. The most likely reason for the failure is that cURL was unable to rewind the body of the request and subsequent retries resulted in the same error. Turn on the debug option to see what went wrong. See https://bugs.php.net/bug.php?id=47204 for more information. (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)
此问题出现情况不一。可以运行 `php -r "echo sys_get_temp_dir();"` 打印系统默认临时目录绝对路径,然后在 `php.ini` 配置 `sys_temp_dir` 为这个值尝试是否能解决。
## 源码安装问题
为了支持部分源码安装的需要,我们将依赖的包文件放在 vendor 目录中,又考虑到不能造成对 composer 的不兼容github 不得不设置禁止导出 vendor 目录,造成必须使用 `git clone` 命令才能拿到 vendor 目录的情况,对一些不熟悉 github 的用户造成了困扰。从 3.0.188 版本开始,我们暂时移除了源码安装,必须使用 composer 安装 SDK 和依赖的包。
## 关键字冲突问题
目前已知在 PHP 7.x 版本中,由于关键字冲突,弹性伸缩产品对应的 As 模块可能无法使用。可以考虑升级到 SDK 3.0.362 版本,使用 Autoscaling 模块。或者升级到 PHP 8 版本。
## 内存泄漏问题
如果使用 SDK 对接口进行循环调用,如:
```
while (true) {
$resp = $client->DescribeInstances($req);
}
```
可以看到进程占用的内存持续少量上涨,这是 SDK 依赖的 GuzzleHttp 存在[内存泄漏的问题](https://github.com/guzzle/guzzle/issues/2830),目前官方还未修复。
# 旧版SDK
新版 SDK 兼容旧版 SDK。旧版本的SDK存放于QcloudApi目录但不再维护更新推荐使用新版SDK。

View File

@ -0,0 +1,30 @@
{
"name": "tencentcloud/tencentcloud-sdk-php",
"description": "TencentCloudApi php sdk",
"type": "library",
"homepage": "https://github.com/TencentCloud/tencentcloud-sdk-php",
"license": "Apache-2.0",
"authors": [
{
"name": "coolli",
"email": "tencentcloudapi@tencent.com",
"homepage": "https://cloud.tencent.com/document/sdk/PHP",
"role": "Developer"
}
],
"require": {
"php": ">=5.6.0",
"guzzlehttp/guzzle": "^6.3 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "^9.5"
},
"autoload": {
"classmap": [
"src/QcloudApi/QcloudApi.php"
],
"psr-4": {
"TencentCloud\\": "./src/TencentCloud"
}
}
}

View File

@ -0,0 +1,262 @@
| 包名 | 产品中文名 | 更新时间 |
|-|-|-|
| aai | [](https://cloud.tencent.com/document/product) | 2019-08-08 23:15:13 |
| aca | [AI 临床助手](https://cloud.tencent.com/document/product/1388) | 2025-01-09 01:08:36 |
| acp | [应用合规平台](https://cloud.tencent.com/document/product/1553) | 2025-03-14 01:07:24 |
| advisor | [云顾问](https://cloud.tencent.com/document/product/1264) | 2025-03-25 01:07:48 |
| af | [借贷反欺诈](https://cloud.tencent.com/document/product/668) | 2024-11-22 11:20:38 |
| afc | [定制建模](https://cloud.tencent.com/document/product/1029) | 2024-05-31 01:07:25 |
| aiart | [大模型图像创作引擎](https://cloud.tencent.com/document/product/1668) | 2025-03-10 17:35:02 |
| ame | [正版曲库直通车](https://cloud.tencent.com/document/product/1155) | 2023-08-17 01:06:14 |
| ams | [音频内容安全](https://cloud.tencent.com/document/product/1219) | 2025-03-04 01:07:37 |
| anicloud | [动效素材服务](https://cloud.tencent.com/document/product/1641) | 2023-05-18 01:01:53 |
| antiddos | [T-Sec-DDoS防护(Anti-DDoS)](https://cloud.tencent.com/document/product/297) | 2025-03-31 01:07:28 |
| apcas | [汽车精准获客服务](https://cloud.tencent.com/document/product/1244) | 2022-04-04 06:05:36 |
| ape | [正版图库直通车](https://cloud.tencent.com/document/product/1181) | 2022-04-04 06:05:40 |
| api | [云 API](https://cloud.tencent.com/document/product/1278) | 2023-01-05 01:02:52 |
| apigateway | [API 网关](https://cloud.tencent.com/document/product/628) | 2025-03-28 01:08:35 |
| apm | [应用性能监控](https://cloud.tencent.com/document/product/1463) | 2025-03-24 01:09:19 |
| as | [弹性伸缩](https://cloud.tencent.com/document/product/377) | 2025-03-28 01:09:24 |
| asr | [语音识别](https://cloud.tencent.com/document/product/1093) | 2025-03-19 01:10:31 |
| asw | [应用与服务编排工作流](https://cloud.tencent.com/document/product/1272) | 2023-05-18 01:04:02 |
| ba | [ICP备案](https://cloud.tencent.com/document/product/243) | 2024-12-19 01:10:53 |
| batch | [批量计算](https://cloud.tencent.com/document/product/599) | 2025-04-02 01:08:33 |
| bda | [人体分析](https://cloud.tencent.com/document/product/1208) | 2024-11-14 01:10:31 |
| bh | [运维安全中心(堡垒机)](https://cloud.tencent.com/document/product/1025) | 2025-04-03 01:08:29 |
| bi | [商业智能分析 BI](https://cloud.tencent.com/document/product/590) | 2025-04-02 01:08:56 |
| billing | [费用中心](https://cloud.tencent.com/document/product/555) | 2025-03-20 01:11:13 |
| bizlive | [商业直播](https://cloud.tencent.com/document/product) | 2020-03-10 01:08:07 |
| bm | [黑石物理服务器CPM](https://cloud.tencent.com/document/product/386) | 2024-03-20 01:08:40 |
| bma | [品牌经营管家](https://cloud.tencent.com/document/product/1296) | 2024-10-18 01:04:14 |
| bmeip | [黑石弹性公网IP](https://cloud.tencent.com/document/product/1028) | 2024-03-20 01:08:53 |
| bmlb | [黑石负载均衡](https://cloud.tencent.com/document/product/1027) | 2024-03-20 01:08:56 |
| bmvpc | [黑石私有网络](https://cloud.tencent.com/document/product/1024) | 2024-03-20 01:09:02 |
| bpaas | [商业流程服务](https://cloud.tencent.com/document/product/1083) | 2024-11-29 01:10:03 |
| bri | [业务风险情报](https://cloud.tencent.com/document/product/1064) | 2024-06-19 01:13:52 |
| bsca | [软件成分分析](https://cloud.tencent.com/document/product/1483) | 2024-11-27 01:09:19 |
| btoe | [区块链可信取证](https://cloud.tencent.com/document/product/1259) | 2024-11-06 15:27:32 |
| ca | [腾讯云CA](https://cloud.tencent.com/document/product/1691) | 2025-01-16 01:08:56 |
| cam | [访问管理](https://cloud.tencent.com/document/product/598) | 2025-04-02 01:09:26 |
| captcha | [验证码](https://cloud.tencent.com/document/product/1110) | 2025-03-27 01:08:19 |
| car | [应用云渲染](https://cloud.tencent.com/document/product/1547) | 2024-12-27 10:53:11 |
| cat | [云拨测](https://cloud.tencent.com/document/product/280) | 2025-03-07 01:09:25 |
| cbs | [云硬盘](https://cloud.tencent.com/document/product/362) | 2025-04-02 01:09:47 |
| ccc | [云联络中心](https://cloud.tencent.com/document/product/679) | 2025-03-31 01:09:33 |
| cdb | [云数据库 MySQL](https://cloud.tencent.com/document/product/236) | 2025-03-28 01:13:58 |
| cdc | [本地专用集群](https://cloud.tencent.com/document/product/1346) | 2025-03-28 01:15:04 |
| cdn | [内容分发网络 CDN](https://cloud.tencent.com/document/product/228) | 2025-04-02 01:10:33 |
| cds | [T-Sec-数据安全审计DSA](https://cloud.tencent.com/document/product/856) | 2024-11-08 01:17:02 |
| cdwch | [腾讯云数据仓库TCHouse-C](https://cloud.tencent.com/document/product/1299) | 2025-03-24 01:16:39 |
| cdwdoris | [腾讯云数据仓库 TCHouse-D](https://cloud.tencent.com/document/product/1387) | 2025-03-28 01:16:20 |
| cdwpg | [云数据仓库 PostgreSQL](https://cloud.tencent.com/document/product/878) | 2025-03-27 01:12:24 |
| cdz | [专属可用区](https://cloud.tencent.com/document/product/1629) | 2025-03-28 01:16:55 |
| cfg | [混沌演练平台](https://cloud.tencent.com/document/product/1500) | 2025-04-02 01:11:14 |
| cfs | [文件存储](https://cloud.tencent.com/document/product/582) | 2025-03-28 01:17:07 |
| cfw | [云防火墙](https://cloud.tencent.com/document/product/1132) | 2025-04-04 01:11:14 |
| chc | [云托付物理服务器](https://cloud.tencent.com/document/product/1448) | 2025-03-28 01:18:07 |
| chdfs | [云 HDFS](https://cloud.tencent.com/document/product/1105) | 2025-04-02 01:11:44 |
| ciam | [账号风控平台](https://cloud.tencent.com/document/product/1441) | 2025-03-07 01:11:06 |
| cii | [智能保险助手](https://cloud.tencent.com/document/product/1368) | 2023-05-18 01:12:07 |
| cim | [](https://cloud.tencent.com/document/product) | 2019-05-16 17:21:18 |
| cis | [](https://cloud.tencent.com/document/product) | 2018-06-07 15:01:42 |
| ckafka | [消息队列 CKafka 版](https://cloud.tencent.com/document/product/597) | 2025-04-03 01:11:25 |
| clb | [负载均衡](https://cloud.tencent.com/document/product/214) | 2025-04-03 01:11:40 |
| cloudapp | [云应用](https://cloud.tencent.com/document/product/1689) | 2025-01-09 01:12:37 |
| cloudaudit | [操作审计](https://cloud.tencent.com/document/product/629) | 2025-03-26 01:21:06 |
| cloudhsm | [云加密机](https://cloud.tencent.com/document/product/639) | 2024-11-28 10:52:49 |
| cloudstudio | [Cloud Studio云端 IDE](https://cloud.tencent.com/document/product/1039) | 2025-02-28 01:15:03 |
| cls | [日志服务](https://cloud.tencent.com/document/product/614) | 2025-04-08 01:11:58 |
| cme | [多媒体创作引擎](https://cloud.tencent.com/document/product/1156) | 2025-03-27 20:17:54 |
| cmq | [消息队列 CMQ](https://cloud.tencent.com/document/product/406) | 2025-03-14 01:12:04 |
| cms | [内容安全](https://cloud.tencent.com/document/product/669) | 2024-06-20 01:24:47 |
| config | [配置审计](https://cloud.tencent.com/document/product/1579) | 2025-01-15 01:11:56 |
| controlcenter | [控制中心](https://cloud.tencent.com/document/product/1708) | 2025-04-02 01:12:54 |
| cpdp | [企业收付平台](https://cloud.tencent.com/document/product/1122) | 2023-09-21 02:09:54 |
| csip | [云安全一体化平台](https://cloud.tencent.com/document/product/664) | 2025-03-07 01:12:16 |
| csxg | [5G入云服务](https://cloud.tencent.com/document/product/1687) | 2024-03-20 01:12:25 |
| cvm | [云服务器](https://cloud.tencent.com/document/product/213) | 2025-04-01 01:13:17 |
| cwp | [主机安全](https://cloud.tencent.com/document/product/296) | 2025-04-03 18:32:35 |
| cws | [漏洞扫描服务](https://cloud.tencent.com/document/product) | 2019-11-22 12:16:15 |
| cynosdb | [TDSQL-C MySQL 版](https://cloud.tencent.com/document/product/1003) | 2025-03-31 01:14:08 |
| dasb | [运维安全中心(堡垒机)](https://cloud.tencent.com/document/product/1025) | 2024-11-19 01:26:13 |
| dataintegration | [数据接入平台](https://cloud.tencent.com/document/product/1591) | 2022-07-26 15:32:15 |
| dayu | [DDoS 高防包](https://cloud.tencent.com/document/product/1021) | 2023-05-18 01:20:11 |
| dbbrain | [数据库智能管家 DBbrain](https://cloud.tencent.com/document/product/1130) | 2025-04-02 01:15:06 |
| dbdc | [云数据库独享集群](https://cloud.tencent.com/document/product/1322) | 2025-03-27 01:23:17 |
| dc | [专线接入](https://cloud.tencent.com/document/product/216) | 2025-02-24 01:26:07 |
| dcdb | [TDSQL MySQL 版](https://cloud.tencent.com/document/product/557) | 2025-04-02 01:15:36 |
| dlc | [数据湖计算 DLC](https://cloud.tencent.com/document/product/1342) | 2025-04-01 01:15:35 |
| dnspod | [DNSPod](https://cloud.tencent.com/document/product/1427) | 2025-04-02 01:16:18 |
| domain | [域名注册](https://cloud.tencent.com/document/product/242) | 2025-03-28 01:29:59 |
| drm | [数字版权管理](https://cloud.tencent.com/document/product/1000) | 2025-01-09 01:16:10 |
| ds | [文档服务](https://cloud.tencent.com/document/product/869) | 2024-03-20 01:15:13 |
| dsgc | [数据安全治理中心](https://cloud.tencent.com/document/product/1087) | 2025-03-20 20:20:10 |
| dtf | [分布式事务](https://cloud.tencent.com/document/product/1224) | 2022-04-04 06:38:57 |
| dts | [数据传输服务](https://cloud.tencent.com/document/product/571) | 2025-04-02 16:33:03 |
| eb | [事件总线](https://cloud.tencent.com/document/product/1359) | 2025-03-25 15:22:50 |
| ecc | [英文作文批改](https://cloud.tencent.com/document/product/1076) | 2024-09-05 01:32:54 |
| ecdn | [全站加速网络](https://cloud.tencent.com/document/product/570) | 2025-03-28 01:32:15 |
| ecm | [边缘计算机器](https://cloud.tencent.com/document/product/1108) | 2025-01-10 01:15:40 |
| eiam | [数字身份管控平台(员工版)](https://cloud.tencent.com/document/product/1442) | 2024-06-25 01:14:34 |
| eis | [数据连接器](https://cloud.tencent.com/document/product/1270) | 2023-08-10 01:17:44 |
| emr | [弹性 MapReduce](https://cloud.tencent.com/document/product/589) | 2025-03-28 01:33:26 |
| es | [Elasticsearch Service](https://cloud.tencent.com/document/product/845) | 2025-03-18 01:35:57 |
| ess | [腾讯电子签企业版](https://cloud.tencent.com/document/product/1323) | 2025-04-01 01:17:53 |
| essbasic | [腾讯电子签(基础版)](https://cloud.tencent.com/document/product/1420) | 2025-04-01 01:18:12 |
| facefusion | [人脸融合](https://cloud.tencent.com/document/product/670) | 2025-04-02 01:18:44 |
| faceid | [人脸核身](https://cloud.tencent.com/document/product/1007) | 2025-02-28 01:30:36 |
| fmu | [人脸试妆](https://cloud.tencent.com/document/product/1172) | 2025-03-20 01:38:20 |
| ft | [人像变换](https://cloud.tencent.com/document/product/1202) | 2024-11-21 01:34:23 |
| gaap | [全球应用加速](https://cloud.tencent.com/document/product/608) | 2025-01-09 01:18:35 |
| gme | [游戏多媒体引擎](https://cloud.tencent.com/document/product/607) | 2025-02-21 01:35:33 |
| goosefs | [数据加速器 GooseFS](https://cloud.tencent.com/document/product/1424) | 2025-03-20 01:39:23 |
| gpm | [游戏玩家匹配](https://cloud.tencent.com/document/product/1294) | 2022-07-11 06:12:36 |
| gs | [云游戏](https://cloud.tencent.com/document/product/1162) | 2025-04-08 01:17:33 |
| gse | [游戏服务器伸缩](https://cloud.tencent.com/document/product/1165) | 2022-07-11 06:12:44 |
| gwlb | [网关负载均衡](https://cloud.tencent.com/document/product/1782) | 2025-03-28 01:37:42 |
| habo | [](https://cloud.tencent.com/document/product) | 2019-05-09 19:37:22 |
| hai | [高性能应用服务](https://cloud.tencent.com/document/product/1721) | 2025-04-01 01:19:03 |
| hasim | [高可用物联网卡](https://cloud.tencent.com/document/product/1482) | 2023-05-18 01:29:47 |
| hcm | [数学作业批改](https://cloud.tencent.com/document/product/1004) | 2024-05-09 01:16:27 |
| hunyuan | [腾讯混元大模型](https://cloud.tencent.com/document/product/1729) | 2025-03-27 01:34:12 |
| iai | [人脸识别](https://cloud.tencent.com/document/product/867) | 2024-12-27 11:13:24 |
| iap | [身份识别平台](https://cloud.tencent.com/document/product/1787) | 2025-03-26 01:41:04 |
| ic | [图片瘦身](https://cloud.tencent.com/document/product/636) | 2023-03-02 01:23:21 |
| icr | [对话机器人](https://cloud.tencent.com/document/product/1268) | 2024-04-22 01:17:48 |
| ie | [智能编辑](https://cloud.tencent.com/document/product/1186) | 2023-08-17 03:20:18 |
| iecp | [物联网边缘计算平台](https://cloud.tencent.com/document/product/1118) | 2024-09-25 01:22:07 |
| ig | [智能导诊](https://cloud.tencent.com/document/product/1273) | 2024-11-21 01:36:39 |
| iir | [智能识图](https://cloud.tencent.com/document/product/1217) | 2022-04-04 06:48:05 |
| ims | [图片内容安全](https://cloud.tencent.com/document/product/1125) | 2025-03-28 01:38:47 |
| ioa | [iOA 零信任安全管理系统](https://cloud.tencent.com/document/product/1092) | 2025-02-21 01:37:05 |
| iot | [加速物联网套件](https://cloud.tencent.com/document/product/568) | 2023-07-17 01:22:28 |
| iotcloud | [物联网通信](https://cloud.tencent.com/document/product/634) | 2025-04-01 01:19:27 |
| iotexplorer | [物联网开发平台](https://cloud.tencent.com/document/product/1081) | 2025-04-08 01:18:12 |
| iottid | [物联网设备身份认证](https://cloud.tencent.com/document/product/1086) | 2023-05-18 01:33:02 |
| iotvideo | [物联网智能视频服务](https://cloud.tencent.com/document/product/1131) | 2025-03-28 01:41:10 |
| iotvideoindustry | [物联网智能视频服务(行业版)](https://cloud.tencent.com/document/product/1361) | 2025-04-07 01:39:24 |
| irp | [智能推荐平台](https://cloud.tencent.com/document/product/1541) | 2024-10-17 01:22:29 |
| iss | [智能视图计算平台](https://cloud.tencent.com/document/product/1344) | 2025-04-02 01:21:10 |
| ivld | [媒体智能标签](https://cloud.tencent.com/document/product/1509) | 2024-12-16 01:41:44 |
| keewidb | [云数据库 KeeWiDB](https://cloud.tencent.com/document/product/1520) | 2025-03-10 01:41:29 |
| kms | [密钥管理系统](https://cloud.tencent.com/document/product/573) | 2025-03-14 01:19:50 |
| lcic | [实时互动-教育版](https://cloud.tencent.com/document/product/1639) | 2025-03-26 01:46:29 |
| lighthouse | [轻量应用服务器](https://cloud.tencent.com/document/product/1207) | 2025-03-31 01:21:08 |
| live | [云直播CSS](https://cloud.tencent.com/document/product/267) | 2025-04-01 01:21:49 |
| lke | [大模型知识引擎](https://cloud.tencent.com/document/product/1759) | 2025-03-31 01:21:48 |
| lkeap | [知识引擎原子能力](https://cloud.tencent.com/document/product/1772) | 2025-04-08 01:20:34 |
| lowcode | [云开发低码](https://cloud.tencent.com/document/product/1301) | 2025-03-20 01:49:29 |
| mall | [商场客留大数据](https://cloud.tencent.com/document/product/1707) | 2024-03-20 01:20:11 |
| mariadb | [云数据库 MariaDB](https://cloud.tencent.com/document/product/237) | 2025-04-02 01:23:06 |
| market | [云市场](https://cloud.tencent.com/document/product/306) | 2024-11-25 01:21:47 |
| memcached | [云数据库Memcached](https://cloud.tencent.com/document/product/241) | 2025-03-24 01:49:27 |
| mgobe | [游戏联机对战引擎](https://cloud.tencent.com/document/product/1038) | 2022-07-08 06:11:32 |
| mmps | [小程序安全](https://cloud.tencent.com/document/product/1223) | 2025-03-28 01:47:29 |
| mna | [多网聚合加速](https://cloud.tencent.com/document/product/1385) | 2025-04-08 01:20:55 |
| mongodb | [云数据库 MongoDB](https://cloud.tencent.com/document/product/240) | 2025-03-28 01:48:00 |
| monitor | [腾讯云可观测平台](https://cloud.tencent.com/document/product/248) | 2025-02-18 23:57:24 |
| mps | [媒体处理](https://cloud.tencent.com/document/product/862) | 2025-04-02 01:24:01 |
| mqtt | [消息队列 MQTT 版](https://cloud.tencent.com/document/product/1778) | 2025-04-02 01:24:29 |
| mrs | [医疗报告结构化](https://cloud.tencent.com/document/product/1314) | 2024-12-12 01:48:36 |
| ms | [移动应用安全](https://cloud.tencent.com/document/product/283) | 2024-11-14 01:54:52 |
| msp | [迁移服务平台](https://cloud.tencent.com/document/product/659) | 2024-12-25 01:51:10 |
| mvj | [营销价值判断](https://cloud.tencent.com/document/product) | 2020-03-19 08:11:44 |
| nlp | [NLP 技术](https://cloud.tencent.com/document/product/271) | 2025-01-14 01:21:36 |
| npp | [号码保护](https://cloud.tencent.com/document/product) | 2020-04-22 08:00:22 |
| oceanus | [流计算 Oceanus](https://cloud.tencent.com/document/product/849) | 2025-03-12 01:22:00 |
| ocr | [文字识别](https://cloud.tencent.com/document/product/866) | 2025-04-04 01:23:59 |
| omics | [腾讯健康组学平台](https://cloud.tencent.com/document/product/1643) | 2024-12-25 01:52:29 |
| organization | [集团账号管理](https://cloud.tencent.com/document/product/850) | 2025-04-02 01:25:20 |
| partners | [渠道合作伙伴](https://cloud.tencent.com/document/product/563) | 2025-04-01 10:32:48 |
| pds | [私域安全](https://cloud.tencent.com/document/product/1473) | 2023-05-18 01:44:14 |
| postgres | [云数据库 PostgreSQL](https://cloud.tencent.com/document/product/409) | 2025-03-28 01:53:55 |
| privatedns | [私有域解析 Private DNS](https://cloud.tencent.com/document/product/1338) | 2025-03-27 01:51:08 |
| pts | [云压测](https://cloud.tencent.com/document/product/1484) | 2025-03-07 01:23:46 |
| rce | [全栈式风控引擎](https://cloud.tencent.com/document/product/1343) | 2025-03-28 14:27:40 |
| redis | [云数据库Redis](https://cloud.tencent.com/document/product/239) | 2025-03-28 01:55:05 |
| region | [地域管理系统](https://cloud.tencent.com/document/product/1596) | 2025-03-28 01:55:44 |
| rum | [前端性能监控](https://cloud.tencent.com/document/product/1464) | 2025-03-14 01:24:07 |
| scf | [云函数](https://cloud.tencent.com/document/product/583) | 2025-03-28 01:56:14 |
| ses | [邮件推送](https://cloud.tencent.com/document/product/1288) | 2025-03-18 02:00:38 |
| smh | [智能媒资托管](https://cloud.tencent.com/document/product/1339) | 2025-03-13 01:55:19 |
| smop | [腾讯安心用户运营平台](https://cloud.tencent.com/document/product/1310) | 2025-02-13 01:55:34 |
| smpn | [营销号码安全](https://cloud.tencent.com/document/product/1127) | 2024-07-09 01:21:06 |
| sms | [短信](https://cloud.tencent.com/document/product/382) | 2025-03-07 01:24:40 |
| soe | [智聆口语评测](https://cloud.tencent.com/document/product/884) | 2024-11-13 02:01:41 |
| solar | [智汇零售](https://cloud.tencent.com/document/product) | 2020-03-19 08:01:59 |
| sqlserver | [云数据库 SQL Server](https://cloud.tencent.com/document/product/238) | 2025-04-02 01:27:02 |
| ssa | [安全运营中心](https://cloud.tencent.com/document/product/664) | 2023-11-15 02:18:28 |
| ssl | [SSL 证书](https://cloud.tencent.com/document/product/400) | 2025-03-28 01:58:23 |
| sslpod | [证书监控 SSLPod](https://cloud.tencent.com/document/product/1084) | 2024-03-20 01:24:03 |
| ssm | [凭据管理系统](https://cloud.tencent.com/document/product/1140) | 2024-11-08 02:01:05 |
| sts | [安全凭证服务](https://cloud.tencent.com/document/product/1312) | 2025-03-28 01:59:08 |
| svp | [节省计划](https://cloud.tencent.com/document/product/1761) | 2025-03-24 02:01:25 |
| taf | [流量反欺诈](https://cloud.tencent.com/document/product/1031) | 2025-03-27 01:55:50 |
| tag | [标签](https://cloud.tencent.com/document/product/651) | 2025-03-28 01:59:18 |
| tan | [碳引擎](https://cloud.tencent.com/document/product/1498) | 2024-03-20 01:24:15 |
| tat | [自动化助手](https://cloud.tencent.com/document/product/1340) | 2025-03-26 02:03:49 |
| tav | [文件检测](https://cloud.tencent.com/document/product) | 2019-11-28 22:10:04 |
| tbaas | [腾讯云区块链服务平台 TBaaS](https://cloud.tencent.com/document/product/663) | 2025-03-27 01:56:21 |
| tbm | [](https://cloud.tencent.com/document/product) | 2019-03-29 14:49:11 |
| tbp | [腾讯智能对话平台](https://cloud.tencent.com/document/product/1060) | 2024-03-20 01:24:24 |
| tcaplusdb | [游戏数据库 TcaplusDB](https://cloud.tencent.com/document/product/596) | 2024-08-05 02:05:20 |
| tcb | [云开发 CloudBase](https://cloud.tencent.com/document/product/876) | 2025-04-02 01:28:03 |
| tcbr | [云托管 CloudBase Run](https://cloud.tencent.com/document/product/1243) | 2025-02-28 01:54:37 |
| tccatalog | [统一Catalog服务](https://cloud.tencent.com/document/product/1784) | 2025-02-10 01:57:53 |
| tcex | [腾讯云释义](https://cloud.tencent.com/document/product/1266) | 2022-07-21 06:17:29 |
| tchd | [腾讯云健康看板](https://cloud.tencent.com/document/product/1688) | 2025-03-25 02:03:27 |
| tci | [腾讯智学课堂分析](https://cloud.tencent.com/document/product) | 2020-08-24 08:06:03 |
| tcm | [服务网格](https://cloud.tencent.com/document/product/1261) | 2025-01-06 01:25:44 |
| tcr | [容器镜像服务](https://cloud.tencent.com/document/product/1141) | 2025-03-28 02:01:20 |
| tcss | [容器安全服务](https://cloud.tencent.com/document/product/1285) | 2025-04-03 18:33:40 |
| tdcpg | [TDSQL-C PostgreSQL 版](https://cloud.tencent.com/document/product/1556) | 2025-03-20 12:23:05 |
| tdid | [分布式身份](https://cloud.tencent.com/document/product/1439) | 2025-03-28 02:04:11 |
| tdmq | [消息队列 TDMQ](https://cloud.tencent.com/document/product/1179) | 2025-04-01 01:29:00 |
| tds | [设备安全](https://cloud.tencent.com/document/product/1628) | 2025-03-13 02:01:24 |
| tem | [弹性微服务](https://cloud.tencent.com/document/product/1371) | 2024-12-31 01:29:59 |
| teo | [边缘安全加速平台](https://cloud.tencent.com/document/product/1552) | 2025-04-03 01:29:26 |
| thpc | [高性能计算平台](https://cloud.tencent.com/document/product/1527) | 2025-03-28 02:07:07 |
| tia | [智能钛机器学习](https://cloud.tencent.com/document/product/851) | 2021-10-21 11:12:52 |
| tic | [资源编排 TIC](https://cloud.tencent.com/document/product/1213) | 2023-08-17 05:26:08 |
| ticm | [智能鉴黄](https://cloud.tencent.com/document/product/864) | 2021-01-07 08:08:15 |
| tics | [威胁情报云查服务](https://cloud.tencent.com/document/product/1013) | 2024-03-20 01:27:08 |
| tiems | [腾讯云 TI 平台 TI-EMS ](https://cloud.tencent.com/document/product/1120) | 2022-07-19 06:19:39 |
| tiia | [图像分析](https://cloud.tencent.com/document/product/865) | 2024-12-23 11:03:45 |
| tione | [TI-ONE 训练平台](https://cloud.tencent.com/document/product/851) | 2025-04-03 01:29:58 |
| tiw | [互动白板](https://cloud.tencent.com/document/product/1137) | 2025-03-14 18:22:24 |
| tke | [容器服务](https://cloud.tencent.com/document/product/457) | 2025-03-28 02:09:13 |
| tkgdq | [腾讯知识图谱数据查询](https://cloud.tencent.com/document/product) | 2020-03-10 00:51:44 |
| tms | [文本内容安全](https://cloud.tencent.com/document/product/1124) | 2025-03-07 01:28:04 |
| tmt | [机器翻译](https://cloud.tencent.com/document/product/551) | 2025-03-28 02:09:24 |
| tourism | [文旅客情大数据](https://cloud.tencent.com/document/product/1684) | 2024-03-20 01:28:59 |
| trabbit | [消息队列 RabbitMQ Serverless 版](https://cloud.tencent.com/document/product/1495) | 2025-02-21 02:04:45 |
| trdp | [流量风险决策平台](https://cloud.tencent.com/document/product/1604) | 2023-05-18 02:01:19 |
| trocket | [消息队列 RocketMQ 版](https://cloud.tencent.com/document/product/1493) | 2025-03-28 02:09:45 |
| trp | [T-Sec-安心平台(RP)](https://cloud.tencent.com/document/product/1458) | 2025-03-06 01:27:29 |
| trro | [实时互动-工业能源版](https://cloud.tencent.com/document/product/1584) | 2025-03-31 12:32:21 |
| trtc | [实时音视频](https://cloud.tencent.com/document/product/647) | 2025-04-03 01:31:08 |
| tse | [微服务引擎](https://cloud.tencent.com/document/product/1364) | 2025-04-03 01:31:18 |
| tsf | [微服务平台 TSF](https://cloud.tencent.com/document/product/649) | 2025-03-27 02:08:38 |
| tsi | [腾讯同传系统](https://cloud.tencent.com/document/product/1399) | 2024-10-23 01:36:51 |
| tsw | [微服务观测平台 TSW](https://cloud.tencent.com/document/product/1311) | 2024-03-20 01:30:06 |
| tts | [语音合成](https://cloud.tencent.com/document/product/1073) | 2024-12-27 11:25:13 |
| ump | [客流数字化平台](https://cloud.tencent.com/document/product/1320) | 2024-03-20 01:30:08 |
| vcg | [视频生成](https://cloud.tencent.com/document/product/1770) | 2024-11-22 12:20:45 |
| vclm | [大模型视频创作引擎](https://cloud.tencent.com/document/product/1616) | 2025-03-13 02:09:17 |
| vcube | [音视频终端引擎](https://cloud.tencent.com/document/product/1449) | 2025-03-25 15:52:47 |
| vdb | [向量数据库](https://cloud.tencent.com/document/product/1709) | 2025-04-01 01:32:28 |
| vm | [视频内容安全](https://cloud.tencent.com/document/product/1265) | 2025-03-03 01:29:20 |
| vms | [语音消息](https://cloud.tencent.com/document/product/1128) | 2025-02-13 02:09:44 |
| vod | [云点播](https://cloud.tencent.com/document/product/266) | 2025-04-02 01:33:31 |
| vpc | [私有网络](https://cloud.tencent.com/document/product/215) | 2025-04-02 01:33:36 |
| vrs | [声音复刻](https://cloud.tencent.com/document/product/1283) | 2025-03-19 02:23:02 |
| vtc | [视频转译](https://cloud.tencent.com/document/product/1769) | 2024-10-16 01:32:39 |
| waf | [Web 应用防火墙](https://cloud.tencent.com/document/product/627) | 2025-03-28 02:18:53 |
| wav | [企业微信汽车行业版](https://cloud.tencent.com/document/product/1318) | 2024-11-20 02:21:21 |
| wedata | [数据开发治理平台 WeData](https://cloud.tencent.com/document/product/1267) | 2025-04-03 01:34:17 |
| weilingwith | [微瓴同业开放平台](https://cloud.tencent.com/document/product/1693) | 2025-04-01 01:35:15 |
| wss | [SSL证书管理服务](https://cloud.tencent.com/document/product) | 2020-04-01 08:53:44 |
| yinsuda | [音速达直播音乐版权引擎](https://cloud.tencent.com/document/product/1592) | 2024-06-05 02:38:46 |
| youmall | [](https://cloud.tencent.com/document/product) | 2019-01-11 11:24:15 |
| yunjing | [主机安全](https://cloud.tencent.com/document/product) | 2020-09-15 08:08:47 |
| yunsou | [腾讯云搜TCS](https://cloud.tencent.com/document/product/270) | 2024-03-20 01:33:14 |

View File

@ -0,0 +1,40 @@
<?php
/**
* QcloudApi_Common_Base
*/
abstract class QcloudApi_Common_Base
{
/**
* $_error
* 错误号
*/
protected $_error = 0;
/**
* setError
* 设置错误信息
*
* @param int $code 错误号
* @param string $message 错误信息
* @param string $ext 扩展信息
* @return object
*/
public function setError($code, $message, $ext = '')
{
require_once QCLOUDAPI_ROOT_PATH . '/Common/Error.php';
$this->_error = new QcloudApi_Common_Error($code, $message, $ext);
return $this->_error;
}
/**
* getError
* 获取错误信息
*
* @return object
*/
public function getError()
{
return $this->_error;
}
}

View File

@ -0,0 +1,75 @@
<?php
/**
* QcloudApi_Common_Error
*/
class QcloudApi_Common_Error
{
/**
* LOCAL_ERROR_CODE
*/
const LOCAL_ERROR_CODE = 3000;
/**
* RESOURCE_PARTLY_FAILED
*/
const RESOURCE_PARTLY_FAILED = 5400;
/**
* $_code
* 错误号
*/
protected $_code;
/**
* $_message
* 错误信息
*/
protected $_message;
/**
* $_ext
* 扩展信息
*/
protected $_ext;
/**
* __construct
* @param int $code 错误号
* @param string $message 错误信息
* @param string $ext 扩展信息
*/
public function __construct($code, $message, $ext = '')
{
$code = (int) $code;
$this->_code = $code ? $code : self::LOCAL_ERROR_CODE;
$this->_message = $message;
$this->_ext = $ext;
}
/**
* getCode
* 获取错误号
*/
public function getCode()
{
return $this->_code;
}
/**
* getMessage
* 获取错误信息
*/
public function getMessage()
{
return $this->_message;
}
/**
* getExt
* 获取扩展信息
*/
public function getExt()
{
return $this->_ext;
}
}

View File

@ -0,0 +1,183 @@
<?php
require_once QCLOUDAPI_ROOT_PATH . '/Common/Sign.php';
/**
* QcloudApi_Common_Request
*/
class QcloudApi_Common_Request
{
/**
* $_requestUrl
* 请求url
* @var string
*/
protected static $_requestUrl = '';
/**
* $_rawResponse
* 原始的返回信息
* @var string
*/
protected static $_rawResponse = '';
/**
* $_version
* @var string
*/
protected static $_version = 'SDK_PHP_2.0.6';
/**
* $_timeOut
* 设置连接主机的超时时间
* @var int 数量级:秒
* */
protected static $_timeOut = 10;
/**
* getRequestUrl
* 获取请求url
*/
public static function getRequestUrl()
{
return self::$_requestUrl;
}
/**
* getRawResponse
* 获取原始的返回信息
*/
public static function getRawResponse()
{
return self::$_rawResponse;
}
/**
* generateUrl
* 生成请求的URL
*
* @param array $paramArray
* @param string $secretId
* @param string $secretKey
* @param string $requestHost
* @param string $requestPath
* @param string $requestMethod
* @return
*/
public static function generateUrl($paramArray, $secretId, $secretKey, $requestMethod, $requestHost, $requestPath) {
if(!isset($paramArray['SecretId']))
$paramArray['SecretId'] = $secretId;
if (!isset($paramArray['Nonce']))
$paramArray['Nonce'] = rand(1, 65535);
if (!isset($paramArray['Timestamp']))
$paramArray['Timestamp'] = time();
$signMethod = 'HmacSHA1';
if (isset($paramArray['SignatureMethod']) && $paramArray['SignatureMethod'] == "HmacSHA256")
$signMethod= 'HmacSHA256';
$paramArray['RequestClient'] = self::$_version;
$plainText = QcloudApi_Common_Sign::makeSignPlainText($paramArray,
$requestMethod, $requestHost, $requestPath);
$paramArray['Signature'] = QcloudApi_Common_Sign::sign($plainText, $secretKey, $signMethod);
$url = 'https://' . $requestHost . $requestPath;
if ($requestMethod == 'GET') {
$url .= '?' . http_build_query($paramArray);
}
return $url;
}
/**
* send
* 发起请求
* @param array $paramArray 请求参数
* @param string $secretId secretId
* @param string $secretKey secretKey
* @param string $requestMethod 请求方式GET/POST
* @param string $requestHost 接口域名
* @param string $requestPath url路径
* @return
*/
public static function send($paramArray, $secretId, $secretKey, $requestMethod, $requestHost, $requestPath)
{
if(!isset($paramArray['SecretId']))
$paramArray['SecretId'] = $secretId;
if (!isset($paramArray['Nonce']))
$paramArray['Nonce'] = rand(1, 65535);
if (!isset($paramArray['Timestamp']))
$paramArray['Timestamp'] = time();
$signMethod = 'HmacSHA1';
if (isset($paramArray['SignatureMethod']) && $paramArray['SignatureMethod'] == "HmacSHA256")
$signMethod= 'HmacSHA256';
$paramArray['RequestClient'] = self::$_version;
$plainText = QcloudApi_Common_Sign::makeSignPlainText($paramArray,
$requestMethod, $requestHost, $requestPath);
$paramArray['Signature'] = QcloudApi_Common_Sign::sign($plainText, $secretKey, $signMethod);
$url = 'https://' . $requestHost . $requestPath;
$ret = self::_sendRequest($url, $paramArray, $requestMethod);
return $ret;
}
/**
* _sendRequest
* @param string $url 请求url
* @param array $paramArray 请求参数
* @param string $method 请求方法
* @return
*/
protected static function _sendRequest($url, $paramArray, $method = 'POST')
{
$ch = curl_init();
if ($method == 'POST')
{
$paramArray = is_array( $paramArray ) ? http_build_query( $paramArray ) : $paramArray;
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $paramArray);
}
else
{
$url .= '?' . http_build_query($paramArray);
}
self::$_requestUrl = $url;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT,self::$_timeOut);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if (false !== strpos($url, "https")) {
// 证书
// curl_setopt($ch,CURLOPT_CAINFO,"ca.crt");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
}
$resultStr = curl_exec($ch);
self::$_rawResponse = $resultStr;
$result = json_decode($resultStr, true);
if (!$result)
{
return $resultStr;
}
return $result;
}
}

View File

@ -0,0 +1,102 @@
<?php
/**
* QcloudApi_Common_Sign
* 签名类
*/
class QcloudApi_Common_Sign
{
/**
* sign
* 生成签名
* @param string $srcStr 拼接签名源文字符串
* @param string $secretKey secretKey
* @param string $method 请求方法
* @return
*/
public static function sign($srcStr, $secretKey, $method = 'HmacSHA1')
{
switch ($method) {
case 'HmacSHA1':
$retStr = base64_encode(hash_hmac('sha1', $srcStr, $secretKey, true));
break;
case 'HmacSHA256':
$retStr = base64_encode(hash_hmac('sha256', $srcStr, $secretKey, true));
break;
default:
throw new Exception($method . ' is not a supported encrypt method');
return false;
break;
}
return $retStr;
}
/**
* makeSignPlainText
* 生成拼接签名源文字符串
* @param array $requestParams 请求参数
* @param string $requestMethod 请求方法
* @param string $requestHost 接口域名
* @param string $requestPath url路径
* @return
*/
public static function makeSignPlainText($requestParams,
$requestMethod = 'GET', $requestHost = YUNAPI_URL,
$requestPath = '/v2/index.php')
{
$url = $requestHost . $requestPath;
// 取出所有的参数
$paramStr = self::_buildParamStr($requestParams, $requestMethod);
$plainText = $requestMethod . $url . $paramStr;
return $plainText;
}
/**
* _buildParamStr
* 拼接参数
* @param array $requestParams 请求参数
* @param string $requestMethod 请求方法
* @return
*/
protected static function _buildParamStr($requestParams, $requestMethod = 'GET')
{
$paramStr = '';
ksort($requestParams);
$i = 0;
foreach ($requestParams as $key => $value)
{
if ($key == 'Signature')
{
continue;
}
// 排除上传文件的参数
if ($requestMethod == 'POST' && substr($value, 0, 1) == '@') {
continue;
}
// 把 参数中的 _ 替换成 .
if (strpos($key, '_'))
{
$key = str_replace('_', '.', $key);
}
if ($i == 0)
{
$paramStr .= '?';
}
else
{
$paramStr .= '&';
}
$paramStr .= $key . '=' . $value;
++$i;
}
return $paramStr;
}
}

View File

@ -0,0 +1,15 @@
<?php
require_once QCLOUDAPI_ROOT_PATH . '/Module/Base.php';
/**
* QcloudApi_Module_Account
* 用户账户模块类
*/
class QcloudApi_Module_Account extends QcloudApi_Module_Base
{
/**
* $_serverHost
* 接口域名
* @var string
*/
protected $_serverHost = 'account.api.qcloud.com';
}

View File

@ -0,0 +1,15 @@
<?php
require_once QCLOUDAPI_ROOT_PATH . '/Module/Base.php';
/**
* QcloudApi_Module_Apigateway
* API网关
*/
class QcloudApi_Module_Apigateway extends QcloudApi_Module_Base
{
/**
* $_serverHost
* 接口域名
* @var string
*/
protected $_serverHost = 'apigateway.api.qcloud.com';
}

View File

@ -0,0 +1,15 @@
<?php
require_once QCLOUDAPI_ROOT_PATH . '/Module/Base.php';
/**
* QcloudApi_Module_Athena
* https://cloud.tencent.com/document/product/671
*/
class QcloudApi_Module_Athena extends QcloudApi_Module_Base
{
/**
* $_serverHost
* 接口域名
* @var string
*/
protected $_serverHost = 'athena.api.qcloud.com';
}

View File

@ -0,0 +1,262 @@
<?php
if (!defined('QCLOUDAPI_ROOT_PATH')) {
// 目录入口
define('QCLOUDAPI_ROOT_PATH', dirname(dirname(__FILE__)));
}
require_once QCLOUDAPI_ROOT_PATH . '/Common/Base.php';
/**
* QcloudApi_Module_Base
* 模块基类
*/
abstract class QcloudApi_Module_Base extends QcloudApi_Common_Base
{
/**
* $_serverHost
* 接口域名
* @var string
*/
protected $_serverHost = '';
/**
* $_serverUri
* url路径
* @var string
*/
protected $_serverUri = '/v2/index.php';
/**
* $_secretId
* secretId
* @var string
*/
protected $_secretId = "";
/**
* $_secretKey
* secretKey
* @var string
*/
protected $_secretKey = "";
/**
* $_defaultRegion
* 区域参数
* @var string
*/
protected $_defaultRegion = "";
/**
* $_requestMethod
* 请求方法
* @var string
*/
protected $_requestMethod = "GET";
/**
* __construct
* @param array $config [description]
*/
public function __construct($config = array())
{
if (!empty($config))
$this->setConfig($config);
}
/**
* setConfig
* 设置配置
* @param array $config 模块配置
*/
public function setConfig($config)
{
if (!is_array($config) || !count($config))
return false;
foreach ($config as $key => $val) {
switch ($key) {
case 'SecretId':
$this->setConfigSecretId($val);
break;
case 'SecretKey':
$this->setConfigSecretKey($val);
break;
case 'DefaultRegion':
$this->setConfigDefaultRegion($val);
break;
case 'RequestMethod':
$this->setConfigRequestMethod($val);
break;
default:
;
break;
}
}
return true;
}
/**
* setConfigSecretId
* 设置secretId
* @param string $secretId secretId
*/
public function setConfigSecretId($secretId)
{
$this->_secretId = $secretId;
return $this;
}
/**
* setConfigSecretKey
* 设置secretKey
* @param string $secretKey
*/
public function setConfigSecretKey($secretKey)
{
$this->_secretKey = $secretKey;
return $this;
}
/**
* setConfigDefaultRegion
* 设置区域参数
* @param string $region
*/
public function setConfigDefaultRegion($region)
{
$this->_defaultRegion = $region;
return $this;
}
/**
* setConfigRequestMethod
* 设置请求方法
* @param string $method
*/
public function setConfigRequestMethod($method)
{
$this->_requestMethod = strtoupper($method);
return $this;
}
/**
* getLastRequest
* 获取上次请求的url
* @return
*/
public function getLastRequest()
{
require_once QCLOUDAPI_ROOT_PATH . '/Common/Request.php';
return QcloudApi_Common_Request::getRequestUrl();
}
/**
* getLastResponse
* 获取请求的原始返回
* @return
*/
public function getLastResponse()
{
require_once QCLOUDAPI_ROOT_PATH . '/Common/Request.php';
return QcloudApi_Common_Request::getRawResponse();
}
/**
* generateUrl
* 生成请求的URL不发起请求
* @param string $name 接口方法名
* @param array $params 请求参数
* @return
*/
public function generateUrl($name, $params)
{
require_once QCLOUDAPI_ROOT_PATH . '/Common/Request.php';
$action = ucfirst($name);
$params['Action'] = $action;
if (!isset($params['Region']))
$params['Region'] = $this->_defaultRegion;
return QcloudApi_Common_Request::generateUrl($params, $this->_secretId, $this->_secretKey, $this->_requestMethod,
$this->_serverHost, $this->_serverUri);
}
/**
* __call
* 通过__call转发请求
* @param string $name 方法名
* @param array $arguments 参数
* @return
*/
public function __call($name, $arguments)
{
$response = $this->_dispatchRequest($name, $arguments);
return $this->_dealResponse($response);
}
/**
* _dispatchRequest
* 发起接口请求
* @param string $name 接口名
* @param array $arguments 接口参数
* @return
*/
protected function _dispatchRequest($name, $arguments)
{
$action = ucfirst($name);
$params = array();
if (is_array($arguments) && !empty($arguments)) {
$params = (array) $arguments[0];
}
$params['Action'] = $action;
if (!isset($params['Region']))
$params['Region'] = $this->_defaultRegion;
require_once QCLOUDAPI_ROOT_PATH . '/Common/Request.php';
$response = QcloudApi_Common_Request::send($params, $this->_secretId, $this->_secretKey, $this->_requestMethod,
$this->_serverHost, $this->_serverUri);
return $response;
}
/**
* _dealResponse
* 处理返回
* @param array $rawResponse
* @return
*/
protected function _dealResponse($rawResponse)
{
if (!is_array($rawResponse) || (!isset($rawResponse['code']) && !isset($rawResponse['Response']))) {
$this->setError("", 'request falied!');
return false;
}
if ($rawResponse['code']) {
$ext = '';
require_once QCLOUDAPI_ROOT_PATH . '/Common/Error.php';
if (isset($rawResponse['detail'])) {
// 批量异步操作,返回任务失败信息
$ext = $rawResponse['detail'];
}
$this->setError($rawResponse['code'], $rawResponse['message'], $ext);
return false;
}
unset($rawResponse['code'], $rawResponse['message']);
if (count($rawResponse))
return $rawResponse;
else
return true;
}
}

View File

@ -0,0 +1,15 @@
<?php
require_once QCLOUDAPI_ROOT_PATH . '/Module/Base.php';
/**
* QcloudApi_Module_Batch
* 批量计算
*/
class QcloudApi_Module_Batch extends QcloudApi_Module_Base
{
/**
* $_serverHost
* 接口域名
* @var string
*/
protected $_serverHost = 'batch.api.qcloud.com';
}

View File

@ -0,0 +1,15 @@
<?php
require_once QCLOUDAPI_ROOT_PATH . '/Module/Base.php';
/**
* QcloudApi_Module_Bgpip
* 大禹网络安全模块
*/
class QcloudApi_Module_Bgpip extends QcloudApi_Module_Base
{
/**
* $_serverHost
* 接口域名
* @var string
*/
protected $_serverHost = 'bgpip.api.qcloud.com';
}

View File

@ -0,0 +1,15 @@
<?php
require_once QCLOUDAPI_ROOT_PATH . '/Module/Base.php';
/**
* QcloudApi_Module_Bill
* Bill账单模块类
*/
class QcloudApi_Module_Bill extends QcloudApi_Module_Base
{
/**
* $_serverHost
* 接口域名
* @var string
*/
protected $_serverHost = 'bill.api.qcloud.com';
}

View File

@ -0,0 +1,15 @@
<?php
require_once QCLOUDAPI_ROOT_PATH . '/Module/Base.php';
/**
* QcloudApi_Module_Bm
* 黑石类
*/
class QcloudApi_Module_Bm extends QcloudApi_Module_Base
{
/**
* $_serverHost
* 接口域名
* @var string
*/
protected $_serverHost = 'bm.api.qcloud.com';
}

View File

@ -0,0 +1,15 @@
<?php
require_once QCLOUDAPI_ROOT_PATH . '/Module/Base.php';
/**
* QcloudApi_Module_Bmeip
* 黑石eip模块类
*/
class QcloudApi_Module_Bmeip extends QcloudApi_Module_Base
{
/**
* $_serverHost
* 接口域名
* @var string
*/
protected $_serverHost = 'bmeip.api.qcloud.com';
}

View File

@ -0,0 +1,15 @@
<?php
require_once QCLOUDAPI_ROOT_PATH . '/Module/Base.php';
/**
* QcloudApi_Module_Bmlb
* 黑石LB类
*/
class QcloudApi_Module_Bmlb extends QcloudApi_Module_Base
{
/**
* $_serverHost
* 接口域名
* @var string
*/
protected $_serverHost = 'bmlb.api.qcloud.com';
}

View File

@ -0,0 +1,15 @@
<?php
require_once QCLOUDAPI_ROOT_PATH . '/Module/Base.php';
/**
* QcloudApi_Module_Bmvpc
* 黑石VPC模块类
*/
class QcloudApi_Module_Bmvpc extends QcloudApi_Module_Base
{
/**
* $_serverHost
* 接口域名
* @var string
*/
protected $_serverHost = 'bmvpc.api.qcloud.com';
}

View File

@ -0,0 +1,15 @@
<?php
require_once QCLOUDAPI_ROOT_PATH . '/Module/Base.php';
/**
* QcloudApi_Module_Cbs
* 云硬盘模块类
*/
class QcloudApi_Module_Cbs extends QcloudApi_Module_Base
{
/**
* $_serverHost
* 接口域名
* @var string
*/
protected $_serverHost = 'cbs.api.qcloud.com';
}

View File

@ -0,0 +1,15 @@
<?php
require_once QCLOUDAPI_ROOT_PATH . '/Module/Base.php';
/**
* QcloudApi_Module_Ccs
* 容器服务
*/
class QcloudApi_Module_Ccs extends QcloudApi_Module_Base
{
/**
* $_serverHost
* 接口域名
* @var string
*/
protected $_serverHost = 'ccs.api.qcloud.com';
}

View File

@ -0,0 +1,15 @@
<?php
require_once QCLOUDAPI_ROOT_PATH . '/Module/Base.php';
/**
* QcloudApi_Module_Cdb
* CDB数据库模块类
*/
class QcloudApi_Module_Cdb extends QcloudApi_Module_Base
{
/**
* $_serverHost
* 接口域名
* @var string
*/
protected $_serverHost = 'cdb.api.qcloud.com';
}

View File

@ -0,0 +1,51 @@
<?php
require_once QCLOUDAPI_ROOT_PATH . '/Module/Base.php';
/**
* QcloudApi_Module_Cdn
* CDN模块类
*/
class QcloudApi_Module_Cdn extends QcloudApi_Module_Base
{
/**
* $_serverHost
* 接口域名
* @var string
*/
protected $_serverHost = 'cdn.api.qcloud.com';
/**
* UploadCdnEntity
* 上传CDN文件
* @param array $params 请求参数
*/
public function UploadCdnEntity($params) {
$name = 'UploadCdnEntity';
$entityFile = $params['entityFile'];
if (!file_exists($entityFile)) {
$this->setError('', 'entityFile is not exists.');
return false;
}
if (!$params['entityFileMd5']) {
$params['entityFileMd5'] = md5_file($entityFile);
}
$params['entityFile'] = '@' . $entityFile;
$response = $this->_dispatchRequest($name, array($params));
if (!$response) {
$this->setError("", 'request falied!');
return false;
}
if (is_array($response) && $response['code']) {
$this->setError($response['code'], $response['message']);
return false;
}
unset($response['code'], $response['message']);
return $response;
}
}

View File

@ -0,0 +1,15 @@
<?php
require_once QCLOUDAPI_ROOT_PATH . '/Module/Base.php';
/**
* QcloudApi_Module_Cloudaudit
* 云审计模块类
*/
class QcloudApi_Module_Cloudaudit extends QcloudApi_Module_Base
{
/**
* $_serverHost
* 接口域名
* @var string
*/
protected $_serverHost = 'cloudaudit.api.qcloud.com';
}

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