| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- <?php
- /**
- * 商品控制器 (控制台脚本)
- *
- * 用途:用于定时任务、命令行脚本处理商品数据,如复制花材、预售到期自动取消等。
- * 谁用:系统定时任务 (Cron Job) 自动调用。
- * 解决什么问题:解决商品后台定时数据维护问题,如预售到期自动取消与部分日期到期更新。
- */
- namespace console\controllers;
- use biz\item\classes\PtItemClass;
- use biz\product\classes\ProductClass;
- use biz\product\models\Product;
- use biz\shop\classes\ShopClass;
- use bizGhs\item\classes\ItemClass;
- use bizGhs\item\models\Item;
- use common\components\stringUtil;
- use common\components\util;
- use yii\console\Controller;
- use Yii;
- class ProductController extends Controller
- {
- //复制花材 ssh 20240422
- public function actionClone()
- {
- ini_set('memory_limit', '5045M');
- set_time_limit(0);
- if (getenv('YII_ENV') == 'production') {
- $shopId = 23580;
- } else {
- $shopId = 36523;
- }
- $shop = ShopClass::getById($shopId, true);
- if (empty($shop)) {
- util::stop();
- }
- $mainId = $shop->mainId ?? 0;
- $productList = ProductClass::getAllByCondition(['mainId' => $mainId, 'classId' => ['in', [64848, 64849, 64850, 64851, 64852, 64853, 64854, 64855, 64856, 64857, 64858, 64859, 64860, 64861, 64862, 64863, 64865, 64866]]], null, '*');
- if (!empty($productList)) {
- foreach ($productList as $post) {
- $post['copy'] = 1;
- $post['auth'] = 0;
- $post['skPrice'] = $post['price'];
- $post['hjPrice'] = $post['price'];
- $post['sjId'] = $shop->sjId ?? 0;
- unset($post['viewNum']);
- unset($post['actualSold']);
- unset($post['itemId']);
- unset($post['id']);
- unset($post['delStatus']);
- $a = $post;
- $a['name'] = $a['name'] . ' A级';
- $a['py'] = stringUtil::py($a['name']);
- \bizGhs\product\classes\ProductClass::addProduct($a, $shop);
- $b = $post;
- $b['name'] = $b['name'] . ' B级';
- $b['py'] = stringUtil::py($b['name']);
- \bizGhs\product\classes\ProductClass::addProduct($b, $shop);
- $ab = $post;
- $ab['name'] = $ab['name'] . ' AB级';
- $ab['py'] = stringUtil::py($ab['name']);
- \bizGhs\product\classes\ProductClass::addProduct($ab, $shop);
- // $c = $post;
- // $c['name'] = $c['name'] . ' C级';
- // $c['py'] = stringUtil::py($c['name']);
- // \bizGhs\product\classes\ProductClass::addProduct($c, $shop);
- //
- // $d = $post;
- // $d['name'] = $d['name'] . ' D级';
- // $d['py'] = stringUtil::py($d['name']);
- // \bizGhs\product\classes\ProductClass::addProduct($d, $shop);
- // $e = $post;
- // $e['name'] = $e['name'] . ' E级';
- // $e['py'] = stringUtil::py($e['name']);
- // \bizGhs\product\classes\ProductClass::addProduct($e, $shop);
- }
- }
- }
- public function actionChangeSk()
- {
- ini_set('memory_limit', '2045M');
- set_time_limit(0);
- //$id = 36523;
- $id = 520;
- $shop = ShopClass::getById($id, true);
- $mainId = $shop->mainId ?? 0;
- $sjId = $shop->sjId ?? 0;
- $chainShopList = ShopClass::getAllByCondition(['sjId' => $sjId, 'join' => 0], null, '*', null, true);
- $default = $shop->default ?? 0;
- $productList = ProductClass::getAllByCondition(['mainId' => $mainId], null, '*', 'id', true);
- if (!empty($productList)) {
- foreach ($productList as $product) {
- $price = $product->price ?? 0;
- $skPrice = bcadd(floatval($price), 3, 0);
- $product->skPrice = $skPrice;
- $product->save();
- $ptItemId = $product->itemId ?? 0;
- if ($default == 1) {
- foreach ($chainShopList as $chain) {
- if ($chain->id == $shop->id) {
- continue;
- }
- $chainMainId = $chain->mainId ?? 0;
- $chainProduct = ProductClass::getByCondition(['mainId' => $chainMainId, 'itemId' => $ptItemId], true);
- if (!empty($chainProduct)) {
- $chainProduct->skPrice = $skPrice;
- $chainProduct->save();
- }
- }
- }
- }
- }
- }
- //修改散客比批发价格贵 ssh 20220609
- public function actionSkMore()
- {
- $query = new \yii\db\Query();
- $query->from(Item::tableName());
- $query->where(['>', 'id', 0]);
- foreach ($query->batch() as $batchItem) {
- foreach ($batchItem as $item) {
- $addPrice = $item['addPrice'] ?? 0;
- $id = $item['id'] ?? 0;
- $skAddPrice = $item['skAddPrice'] ?? 0;
- if ($skAddPrice > $addPrice) {
- $add = bcsub($skAddPrice, $addPrice, 2);
- ItemClass::updateById($id, ['skMore' => $add]);
- } else {
- echo "零售加价小于批发加价 {$id}\n";
- }
- }
- }
- }
- //更新纯彩花艺的价格 ./yii product/update-price ssh 20211020
- public function actionUpdatePrice()
- {
- $list = ProductClass::getAllByCondition(['shopId' => 10], null, '*', null, true);
- if (!empty($list)) {
- foreach ($list as $key => $item) {
- $price = $item->price ?? 0;
- $addPrice = $item->addPrice ?? 0;
- $skAddPrice = $item->skAddPrice ?? 0;
- $hjAddPrice = $item->hjAddPrice ?? 0;
- $zsAddPrice = $item->zsAddPrice ?? 0;
- $skDiff = bcsub($addPrice, $skAddPrice, 2);
- $skPrice = bcsub($price, $skDiff, 2);
- $hjDiff = bcsub($addPrice, $hjAddPrice, 2);
- $hkPrice = bcsub($price, $hjDiff, 2);
- $zsDiff = bcsub($addPrice, $zsAddPrice, 2);
- $zsPrice = bcsub($price, $zsDiff, 2);
- $item->skPrice = $skPrice;
- $item->hjPrice = $hkPrice;
- $item->zsPrice = $zsPrice;
- $item->save();
- }
- }
- }
- // ./yii product/reset-cover
- public function actionResetCover()
- {
- $sql = "SELECT * FROM `" . Product::tableName() . "` WHERE cover not like '%.%'";
- $command = Yii::$app->db->createCommand($sql);
- $data = $command->queryAll();
- if (empty($data)) {
- return false;
- }
- foreach ($data as $item) {
- $id = $item['id'] ?? 0;
- $ptItemId = $item['itemId'] ?? 0;
- $preCover = $item['cover'] ?? '';
- $ptItem = PtItemClass::getById($ptItemId, true);
- $cover = $ptItem->cover ?? '';
- if (!empty($cover)) {
- ProductClass::updateById($id, ['cover' => $cover]);
- echo "productId:" . $id . "原图:{$preCover}, 恢复图片:" . $cover . "\n";
- } else {
- echo "productId:" . $id . " 恢复图片没有成功-----------------\n";
- }
- }
- }
- // ./yii product/sk-price
- public function actionSkPrice()
- {
- ini_set('memory_limit', '2045M');
- set_time_limit(0);
- $list = ProductClass::getAllByCondition([], null, '*', null, true);
- if (empty($list)) {
- return false;
- }
- foreach ($list as $key => $item) {
- $price = $item->price ?? 0;
- $skAddPrice = $item->skAddPrice ?? 0;
- $addPrice = $item->addPrice ?? 0;
- $diff = bcsub($skAddPrice, $addPrice, 2);
- $currentPrice = $price;
- if ($diff > 0) {
- $currentPrice = bcadd($price, $diff, 2);
- }
- $item->skPrice = $currentPrice;
- $item->save();
- }
- }
- //二个空间问题
- public function actionSame()
- {
- ini_set('memory_limit', '5045M');
- set_time_limit(0);
- if (getenv('YII_ENV') == 'production') {
- $mainId = 8164;
- } else {
- $mainId = 644;
- }
- $list = ProductClass::getAllByCondition(['mainId' => $mainId], null, '*', null);
- if (!empty($list)) {
- $ids = array_column($list, 'itemId');
- $ptInfo = PtItemClass::getByIds($ids, null, 'id');
- foreach ($list as $item) {
- $id = $item['id'] ?? 0;
- $name = $item['name'] ?? '';
- $ptItemId = $item['itemId'] ?? 0;
- $pt = $ptInfo[$ptItemId];
- $ptName = $pt['name'] ?? '';
- if ($name != $ptName) {
- echo $id . ' ' . $name . ' ' . $ptName . "\n";
- }
- }
- }
- }
- //二个空间问题
- public function actionEmpty()
- {
- ini_set('memory_limit', '5045M');
- set_time_limit(0);
- $list = PtItemClass::getAllByCondition(['delStatus' => 0], null, '*', null, true);
- if (!empty($list)) {
- foreach ($list as $item) {
- $name = $item->name ?? '';
- $name = trim($name);
- $name = str_replace(" ", " ", $name);
- $name = str_replace(" ", " ", $name);
- $item->name = $name;
- $item->save();
- }
- }
- }
- //恢复花材初始名称 ssh 20250213
- public function actionRecover()
- {
- ini_set('memory_limit', '5045M');
- set_time_limit(0);
- if (getenv('YII_ENV') == 'production') {
- $mainId = 26374;
- } else {
- $mainId = 644;
- }
- $list = ProductClass::getAllByCondition(['mainId' => $mainId], null, '*', null);
- if (!empty($list)) {
- $ids = array_column($list, 'itemId');
- $ptInfo = PtItemClass::getByIds($ids, null, 'id');
- foreach ($list as $item) {
- $id = $item['id'] ?? 0;
- $name = $item['name'] ?? '';
- $ptItemId = $item['itemId'] ?? 0;
- $pt = $ptInfo[$ptItemId];
- $ptName = $pt['name'] ?? '';
- if (!empty($ptName)) {
- $ptPy = stringUtil::py($ptName);
- ProductClass::updateById($id, ['name' => $ptName, 'py' => $ptPy]);
- }
- }
- }
- }
- /**
- * 预售到期自动取消与更新脚本
- *
- * 职责:每天凌晨执行,扫描所有预售商品,若预售日期已到则进行清除或更新。
- * 入参/返回:无(定时脚本,无入参,无返回值)
- * 副作用:会修改商品表(product)的 presell 和 presellDate 字段,并修改 Redis 缓存。
- * 关键边界:
- * 1. 如果设置的全部预售日期都到了,则彻底清除预售状态(presell = 0,presellDate = ''),并删除 Redis 缓存。
- * 2. 如果只到了其中部分日期,则只清除已到期的日期,保留未到期的日期,预售继续(presell = 1,更新 presellDate),并更新 Redis 缓存为剩余最早日期。
- */
- public function actionCancelPresell()
- {
- try{
- $now = time(); //注意脚本执行时间要在凌晨0点之后,否则会出问题
- $redis = Yii::$app->redis;
- $cursor = '0';
- do {
- $scanResult = $redis->executeCommand('SCAN', [$cursor, 'MATCH', 'product_presell:*', 'COUNT', 500]);
- $cursor = $scanResult[0] ?? '0';
- $keys = $scanResult[1] ?? [];
- if (empty($keys)) {
- continue;
- }
- foreach ($keys as $key) {
- $firstDate = (int)$redis->get($key);
- if ($firstDate >= $now) {
- continue;
- }
- $id = (int)str_replace('product_presell:', '', $key);
- if ($id <= 0) {
- $redis->del($key);
- continue;
- }
- $item = ProductClass::getById($id, true);
- if (empty($item)) {
- $redis->del($key);
- continue;
- }
- if ((int)$item->presell !== 1) {
- $redis->del($key);
- continue;
- }
- // 解析商品当前的预售日期列表,干什么:获取所有设置的预售日期时间戳,为什么:需要逐一比对是否到期
- $presellDateStr = trim($item->presellDate ?? '');
- if (empty($presellDateStr)) {
- // 预售日期为空,干什么:直接清除预售状态,为什么:没有日期的预售是无效数据,必须清除并删缓存
- $item->presell = 0;
- $item->presellDate = '';
- $item->save();
- $redis->del($key);
- continue;
- }
- $presellDates = explode(',', $presellDateStr);
- $presellDates = array_unique(array_filter(array_map('intval', $presellDates)));
- // 过滤掉所有已经到期(小于当前时间)的预售日期,干什么:筛选出未来还未到期的预售日期,为什么:只保留未到期的预售日期
- $remainingDates = [];
- foreach ($presellDates as $date) {
- if ($date >= $now) {
- $remainingDates[] = $date;
- }
- }
- // 根据剩余日期情况,决定是完全清除预售还是只清除部分日期
- if (empty($remainingDates)) {
- // 全部预售日期都到了,干什么:清除预售状态,删除 Redis 缓存,为什么:所有预售日期都已过期,商品不再是预售商品
- $item->presell = 0;
- $item->presellDate = '';
- $item->save();
- $redis->del($key);
- } else {
- // 只到了其中部分日期,干什么:清除已到期的日期,预售继续,并更新 Redis 缓存为剩余的最早日期,为什么:部分日期未到,预售仍需继续
- sort($remainingDates);
- $item->presellDate = implode(',', $remainingDates);
- $item->save();
- $redis->set($key, $remainingDates[0]);
- }
- }
- } while ($cursor !== '0');
- Yii::info('预售到期自动取消脚本成功执行');
- }catch(\Exception $e){
- Yii::error('预售到期自动取消脚本执行失败:' . $e->getMessage());
- }
- }
- }
|