首页/ phph5/ 甜趣蛋糕 · 烘焙蛋糕店 PHP+H5 商城 + 商家后台/ 代码预览

💻 代码预览 · 甜趣蛋糕 · 烘焙蛋糕店 PHP+H5 商城 + 商家后台

ph_mall · 上传者 驰旭教育
← 返回详情
r117/core/Database.php · 约 17429 字符
1<?php2/**3 * SQLite 数据库单例 + 自动迁移 + 演示数据播种4 */5class Database {6    private static $pdo = null;78    public static function pdo(): PDO {9        if (self::$pdo === null) {10            if (!is_dir(DATA_DIR)) { mkdir(DATA_DIR, 0755, true); }11            $pdo = new PDO('sqlite:' . DB_FILE);12            $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);13            $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);14            $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);15            $pdo->exec('PRAGMA journal_mode=WAL;');16            $pdo->exec('PRAGMA busy_timeout=5000;');17            $pdo->exec('PRAGMA foreign_keys=ON;');18            self::$pdo = $pdo;19            self::migrate($pdo);20        }21        return self::$pdo;22    }2324    private static function migrate(PDO $pdo): void {25        $pdo->exec("CREATE TABLE IF NOT EXISTS banners (26            id INTEGER PRIMARY KEY AUTOINCREMENT,27            title TEXT NOT NULL DEFAULT '',28            image TEXT NOT NULL DEFAULT '',29            link  TEXT NOT NULL DEFAULT '',30            sort  INTEGER NOT NULL DEFAULT 0,31            status INTEGER NOT NULL DEFAULT 132        )");33        $pdo->exec("CREATE TABLE IF NOT EXISTS categories (34            id    INTEGER PRIMARY KEY AUTOINCREMENT,35            name  TEXT NOT NULL,36            type  TEXT NOT NULL DEFAULT 'kind',37            sort  INTEGER NOT NULL DEFAULT 0,38            status INTEGER NOT NULL DEFAULT 139        )");40        $pdo->exec("CREATE TABLE IF NOT EXISTS products (41            id             INTEGER PRIMARY KEY AUTOINCREMENT,42            name           TEXT NOT NULL,43            kind_id        INTEGER NOT NULL DEFAULT 0,44            scenes         TEXT NOT NULL DEFAULT '',45            price          REAL NOT NULL DEFAULT 0,46            original_price REAL NOT NULL DEFAULT 0,47            sales          INTEGER NOT NULL DEFAULT 0,48            rating         REAL NOT NULL DEFAULT 5,49            stock          INTEGER NOT NULL DEFAULT 99,50            status         INTEGER NOT NULL DEFAULT 1,51            is_new         INTEGER NOT NULL DEFAULT 0,52            is_hot         INTEGER NOT NULL DEFAULT 0,53            is_recommend   INTEGER NOT NULL DEFAULT 0,54            description    TEXT NOT NULL DEFAULT '',55            ingredients    TEXT NOT NULL DEFAULT '',56            allergen       TEXT NOT NULL DEFAULT '',57            shelf_life     TEXT NOT NULL DEFAULT '',58            advice         TEXT NOT NULL DEFAULT '',59            images         TEXT NOT NULL DEFAULT '[]',60            tags           TEXT NOT NULL DEFAULT ''61        )");62        $pdo->exec("CREATE TABLE IF NOT EXISTS skus (63            id         INTEGER PRIMARY KEY AUTOINCREMENT,64            product_id INTEGER NOT NULL,65            size       TEXT NOT NULL DEFAULT '8寸',66            flavor     TEXT NOT NULL DEFAULT '原味',67            price      REAL NOT NULL DEFAULT 0,68            stock      INTEGER NOT NULL DEFAULT 99,69            sales      INTEGER NOT NULL DEFAULT 070        )");71        $pdo->exec("CREATE TABLE IF NOT EXISTS members (72            id       INTEGER PRIMARY KEY AUTOINCREMENT,73            username TEXT NOT NULL DEFAULT '',74            phone    TEXT NOT NULL DEFAULT '',75            level    TEXT NOT NULL DEFAULT 'normal',76            points   INTEGER NOT NULL DEFAULT 0,77            balance  REAL NOT NULL DEFAULT 0,78            growth   INTEGER NOT NULL DEFAULT 0,79            birthday TEXT NOT NULL DEFAULT '',80            status   INTEGER NOT NULL DEFAULT 1,81            created_at TEXT NOT NULL DEFAULT (datetime('now','localtime'))82        )");83        $pdo->exec("CREATE TABLE IF NOT EXISTS coupons (84            id          INTEGER PRIMARY KEY AUTOINCREMENT,85            name        TEXT NOT NULL DEFAULT '',86            type        TEXT NOT NULL DEFAULT 'full_reduce',87            threshold   REAL NOT NULL DEFAULT 0,88            value       REAL NOT NULL DEFAULT 0,89            discount    REAL NOT NULL DEFAULT 1,90            valid_days  INTEGER NOT NULL DEFAULT 30,91            total       INTEGER NOT NULL DEFAULT 0,92            received    INTEGER NOT NULL DEFAULT 0,93            used        INTEGER NOT NULL DEFAULT 0,94            status      INTEGER NOT NULL DEFAULT 195        )");96        $pdo->exec("CREATE TABLE IF NOT EXISTS coupon_user (97            id         INTEGER PRIMARY KEY AUTOINCREMENT,98            coupon_id  INTEGER NOT NULL,99            member_id  INTEGER NOT NULL DEFAULT 0,100            status     TEXT NOT NULL DEFAULT 'unused',101            received_at TEXT NOT NULL DEFAULT (datetime('now','localtime')),102            used_at     TEXT NOT NULL DEFAULT ''103        )");104        $pdo->exec("CREATE TABLE IF NOT EXISTS carts (105            id         INTEGER PRIMARY KEY AUTOINCREMENT,106            member_id  INTEGER NOT NULL DEFAULT 0,107            product_id INTEGER NOT NULL,108            sku_id     INTEGER NOT NULL DEFAULT 0,109            qty        INTEGER NOT NULL DEFAULT 1110        )");111        $pdo->exec("CREATE TABLE IF NOT EXISTS orders (112            id             INTEGER PRIMARY KEY AUTOINCREMENT,113            order_no       TEXT NOT NULL DEFAULT '',114            member_id      INTEGER NOT NULL DEFAULT 0,115            contact_name   TEXT NOT NULL DEFAULT '',116            phone          TEXT NOT NULL DEFAULT '',117            address        TEXT NOT NULL DEFAULT '',118            delivery_type  TEXT NOT NULL DEFAULT 'delivery',119            delivery_time  TEXT NOT NULL DEFAULT '',120            card_msg       TEXT NOT NULL DEFAULT '',121            remark         TEXT NOT NULL DEFAULT '',122            coupon_id      INTEGER NOT NULL DEFAULT 0,123            coupon_amount  REAL NOT NULL DEFAULT 0,124            points_used    INTEGER NOT NULL DEFAULT 0,125            total_amount   REAL NOT NULL DEFAULT 0,126            pay_amount     REAL NOT NULL DEFAULT 0,127            status         TEXT NOT NULL DEFAULT 'pending',128            created_at     TEXT NOT NULL DEFAULT (datetime('now','localtime'))129        )");130        $pdo->exec("CREATE TABLE IF NOT EXISTS order_items (131            id         INTEGER PRIMARY KEY AUTOINCREMENT,132            order_id   INTEGER NOT NULL,133            product_id INTEGER NOT NULL,134            sku_id     INTEGER NOT NULL DEFAULT 0,135            name       TEXT NOT NULL DEFAULT '',136            size       TEXT NOT NULL DEFAULT '',137            flavor     TEXT NOT NULL DEFAULT '',138            price      REAL NOT NULL DEFAULT 0,139            qty        INTEGER NOT NULL DEFAULT 1,140            subtotal   REAL NOT NULL DEFAULT 0141        )");142        $pdo->exec("CREATE TABLE IF NOT EXISTS reviews (143            id         INTEGER PRIMARY KEY AUTOINCREMENT,144            order_id   INTEGER NOT NULL DEFAULT 0,145            product_id INTEGER NOT NULL DEFAULT 0,146            member_id  INTEGER NOT NULL DEFAULT 0,147            rating     INTEGER NOT NULL DEFAULT 5,148            content    TEXT NOT NULL DEFAULT '',149            images     TEXT NOT NULL DEFAULT '[]',150            reply      TEXT NOT NULL DEFAULT '',151            status     INTEGER NOT NULL DEFAULT 1,152            created_at TEXT NOT NULL DEFAULT (datetime('now','localtime'))153        )");154        $pdo->exec("CREATE TABLE IF NOT EXISTS custom_cakes (155            id        INTEGER PRIMARY KEY AUTOINCREMENT,156            member_id INTEGER NOT NULL DEFAULT 0,157            image     TEXT NOT NULL DEFAULT '',158            text      TEXT NOT NULL DEFAULT '',159            shape     TEXT NOT NULL DEFAULT '',160            size      TEXT NOT NULL DEFAULT '8寸',161            note      TEXT NOT NULL DEFAULT '',162            status    TEXT NOT NULL DEFAULT 'pending',163            created_at TEXT NOT NULL DEFAULT (datetime('now','localtime'))164        )");165        $pdo->exec("CREATE TABLE IF NOT EXISTS settings (166            k TEXT PRIMARY KEY,167            v TEXT NOT NULL DEFAULT ''168        )");169170        self::seed($pdo);171    }172173    private static function seed(PDO $pdo): void {174        $cnt = $pdo->query("SELECT COUNT(*) FROM products")->fetchColumn();175        if ($cnt > 0) return;176177        // ---- banners ----178        $banners = [179            ['新品上市 · 当季限定', '🎂', '#category', 1],180            ['生日蛋糕专场 · 免费升磅', '🎉', '#category', 2],181            ['会员日福利 · 积分兑好礼', '❤️', '#member', 3],182            ['精致下午茶套餐', '☕', '#category', 4],183        ];184        $ins = $pdo->prepare("INSERT INTO banners (title,image,link,sort) VALUES (?,?,?,?)");185        foreach ($banners as $b) { $ins->execute($b); }186187        // ---- categories ----188        $scenes = ['生日蛋糕','婚礼庆典','聚会派对','商务茶歇','儿童节','情侣下午茶','长辈祝寿','节日礼盒'];189        $kinds  = ['奶油蛋糕','慕斯蛋糕','芝士蛋糕','巧克力蛋糕','水果蛋糕','无糖蛋糕','翻糖蛋糕'];190        $sizes  = ['6寸','8寸','10寸','12寸','14寸','多层'];191        $stmt = $pdo->prepare("INSERT INTO categories (name,type,sort) VALUES (?,?,?)");192        $s = 1; foreach ($scenes as $n) { $stmt->execute([$n,'scene',$s++]); }193        $s = 1; foreach ($kinds as $n) { $stmt->execute([$n,'kind',$s++]); }194        $s = 1; foreach ($sizes as $n) { $stmt->execute([$n,'size',$s++]); }195196        // kind id 映射(按插入顺序)197        $kindMap = [];198        $rows = $pdo->query("SELECT id,name FROM categories WHERE type='kind' ORDER BY id")->fetchAll();199        foreach ($rows as $r) { $kindMap[$r['name']] = $r['id']; }200201        // ---- products ----202        $products = [203            ['经典草莓奶油蛋糕','奶油蛋糕','生日蛋糕|情侣下午茶',168,218,true,true,false,204             '选用新鲜草莓与动物奶油,口感轻盈不腻,是生日与约会的经典之选。',205             '小麦粉、鸡蛋、牛奶、动物奶油、草莓','含麸质、蛋、奶','冷藏 2 天','0-4℃ 冷藏保存,食用前回温 10 分钟口感更佳',206             '🍓|🎂|🍰','招牌'],207            ['芒果千层慕斯','慕斯蛋糕','情侣下午茶|聚会派对',158,198,false,false,true,208             '层层薄饼夹芒果慕斯,入口即化,酸甜清新。',209             '小麦粉、鸡蛋、芒果、动物奶油','含麸质、蛋、奶、芒果','冷藏 2 天','冷藏保存,避免反复冻融',210             '🥭|🍰|✨','人气'],211            ['海盐芝士蛋糕','芝士蛋糕','商务茶歇|情侣下午茶',178,228,false,false,false,212             '微咸海盐平衡芝士厚重,风味层次丰富。',213             '奶酪、鸡蛋、饼干底、海盐','含蛋、奶、麸质','冷藏 3 天','冷藏保存',214             '🧀|🍰|💛','咸香'],215            ['黑森林巧克力蛋糕','巧克力蛋糕','生日蛋糕|聚会派对',188,238,false,true,false,216             '浓郁黑巧克力与樱桃酒香,经典德式风味。',217             '巧克力、樱桃、奶油、小麦粉','含蛋、奶、麸质','冷藏 2 天','冷藏保存',218             '🍫|🎂|🖤','微醺'],219            ['鲜果缤纷水果蛋糕','水果蛋糕','生日蛋糕|儿童节',198,258,true,false,true,220             '当季时令鲜果铺满,颜值与营养兼具,孩子最爱。',221             '草莓、蓝莓、芒果、动物奶油、小麦粉','含麸质、蛋、奶','冷藏 2 天','即做即食风味最佳',222             '🍓|🫐|🥭|🎂','鲜果'],223            ['轻享无糖燕麦蛋糕','无糖蛋糕','长辈祝寿|商务茶歇',168,208,true,false,false,224             '0 添加蔗糖,燕麦谷香,长辈控糖也能安心吃。',225             '燕麦、鸡蛋、代糖、植物油','含蛋、麸质','冷藏 3 天','糖尿病人群亦可适量食用',226             '🌾|🍰|💚','无糖'],227            ['迪士尼公主翻糖蛋糕','翻糖蛋糕','儿童节|生日蛋糕',288,358,true,true,false,228             '手工翻糖造型,公主城堡立体呈现,生日派对焦点。',229             '翻糖、蛋糕胚、食用色素','含麸质、蛋、奶','常温 1 天/冷藏 3 天','避免阳光直射',230             '👑|🏰|🎂','定制'],231            ['法式覆盆子慕斯','慕斯蛋糕','情侣下午茶|商务茶歇',198,248,false,false,true,232             '覆盆子酸甜与慕斯柔滑交织,红粉诱惑。',233             '覆盆子、动物奶油、小麦粉','含麸质、蛋、奶','冷藏 2 天','冷藏保存',234             '🍇|🍰|🌸','法式'],235            ['提拉米苏芝士','芝士蛋糕','聚会派对|情侣下午茶',176,216,false,true,false,236             '马斯卡彭与咖啡酒香,意式经典。',237             '马斯卡彭、手指饼、咖啡、蛋','含蛋、奶、麸质','冷藏 3 天','冷藏保存',238             '☕|🍰|🤎','意式'],239            ['红丝绒巧克力','巧克力蛋糕','婚礼庆典|情侣下午茶',208,268,false,false,true,240             '红丝绒胚体配白巧奶油,浪漫喜庆。',241             '可可、奶油芝士、小麦粉','含蛋、奶、麸质','冷藏 2 天','冷藏保存',242             '🌹|🍰|❤️','浪漫'],243            ['抹茶红豆慕斯','慕斯蛋糕','生日蛋糕|情侣下午茶',168,208,true,false,false,244             '宇治抹茶微苦回甘,红豆绵密。',245             '抹茶、红豆、动物奶油、小麦粉','含麸质、蛋、奶','冷藏 2 天','冷藏保存',246             '🍵|🍰|💚','和风'],247            ['寿桃无糖祝寿蛋糕','无糖蛋糕','长辈祝寿',238,298,false,true,false,248             '寿桃造型无糖配方,祝寿宴席体面之选。',249             '燕麦、代糖、坚果、植物油','含蛋、麸质、坚果','冷藏 3 天','祝寿专属',250             '🍑|🎂|🎊','祝寿'],251        ];252        $insP = $pdo->prepare("INSERT INTO products253            (name,kind_id,scenes,price,original_price,is_new,is_hot,is_recommend,description,ingredients,allergen,shelf_life,advice,images,tags)254            VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");255        $sizeMul = ['6寸'=>0.7,'8寸'=>1.0,'10寸'=>1.35,'12寸'=>1.7,'14寸'=>2.1,'多层'=>3.0];256        $flavors = [['原味',0],['招牌',10]];257        $pid = 0;258        foreach ($products as $p) {259            $kindId = $kindMap[$p[1]] ?? 0;260            $insP->execute([$p[0],$kindId,$p[2],$p[3],$p[4],261                $p[5]?1:0,$p[6]?1:0,$p[7]?1:0,$p[8],$p[9],$p[10],$p[11],$p[12],$p[13],$p[14]]);262            $pid = $pdo->lastInsertId();263            // 生成 SKU:4 种尺寸 × 2 口味264            $insS = $pdo->prepare("INSERT INTO skus (product_id,size,flavor,price,stock) VALUES (?,?,?,?,?)");265            foreach (['6寸','8寸','10寸','12寸'] as $sz) {266                foreach ($flavors as $fl) {267                    $price = round($p[3]*$sizeMul[$sz] + $fl[1]);268                    $insS->execute([$pid,$sz,$fl[0],$price,99]);269                }270            }271        }272273        // ---- coupons ----274        $coupons = [275            ['新人专享券','newcomer',0,20,1,30,999],276            ['满199减30','full_reduce',199,30,1,30,999],277            ['满299减50','full_reduce',299,50,1,30,999],278            ['会员尊享8折','discount',0,0,0.8,30,500],279            ['无门槛5元券','no_threshold',0,5,1,15,999],280            ['生日专享券','birthday',0,30,1,7,300],281        ];282        $insCou = $pdo->prepare("INSERT INTO coupons (name,type,threshold,value,discount,valid_days,total) VALUES (?,?,?,?,?,?,?)");283        foreach ($coupons as $c) { $insCou->execute($c); }284285        // ---- members ----286        $members = [287            ['小甜','13800000001','normal',120,0,120,'',1],288            ['阿慕','阿慕',  'gold',   880,200,1500,'',1],289            ['寿星婆婆','13900000003','diamond',2600,500,3200,'1949-10-01',1],290        ];291        $insM = $pdo->prepare("INSERT INTO members (username,phone,level,points,balance,growth,birthday,status) VALUES (?,?,?,?,?,?,?,?)");292        foreach ($members as $m) { $insM->execute($m); }293294        // ---- reviews ----295        $reviews = [296            [1,1,1,5,'蛋糕很新鲜,草莓超甜,配送也准时,下次还来!','[]'],297            [3,2,2,5,'海盐芝士味道惊艳,不太腻,办公室下午茶首选。','[]'],298            [5,3,1,4,'水果很丰富,孩子很喜欢,就是有点小贵哈哈。','[]'],299        ];300        $insR = $pdo->prepare("INSERT INTO reviews (product_id,member_id,order_id,rating,content,images) VALUES (?,?,?,?,?,?)");301        foreach ($reviews as $r) { $insR->execute($r); }302303        // ---- custom_cakes ----304        $pdo->prepare("INSERT INTO custom_cakes (member_id,image,text,shape,size,note,status) VALUES (?,?,?,?,?,?,?)")305            ->execute([2,'','宝贝生日快乐','城堡','10寸','请加卡通蜡烛','pending']);306307        // ---- settings ----308        $sets = [309            ['shop_name', SITE_NAME],310            ['phone', '400-888-6688'],311            ['address', '西安市雁塔区科技路 18 号甜趣烘焙工坊'],312            ['delivery_fee', '15'],313            ['free_delivery_amount', '199'],314            ['delivery_range_km', '10'],315            ['delivery_advance_hours', '6'],316            ['open_time', '09:00-21:00'],317            ['notice', '蛋糕为新鲜手工制作,请提前 6 小时预约;定制化蛋糕建议提前 1 天。'],318        ];319        $insS = $pdo->prepare("INSERT INTO settings (k,v) VALUES (?,?)");320        foreach ($sets as $s) { $insS->execute($s); }321    }322}323