first commit
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
CREATE TABLE `posts` (
|
||||
`id` text PRIMARY KEY NOT NULL,
|
||||
`slug` text NOT NULL,
|
||||
`title` text NOT NULL,
|
||||
`excerpt` text,
|
||||
`content` text NOT NULL,
|
||||
`meta_description` text,
|
||||
`status` text DEFAULT 'draft' NOT NULL,
|
||||
`published_at` integer,
|
||||
`updated_at` integer NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX `idx_posts_slug` ON `posts` (`slug`);--> statement-breakpoint
|
||||
CREATE INDEX `idx_posts_published_at` ON `posts` (`published_at`);--> statement-breakpoint
|
||||
CREATE INDEX `idx_posts_status` ON `posts` (`status`);
|
||||
@@ -0,0 +1,33 @@
|
||||
CREATE TABLE `cases` (
|
||||
`id` text PRIMARY KEY NOT NULL,
|
||||
`title` text NOT NULL,
|
||||
`location` text,
|
||||
`completed_at` text,
|
||||
`description` text,
|
||||
`image_url` text,
|
||||
`sort_order` integer DEFAULT 0 NOT NULL,
|
||||
`status` text DEFAULT 'published' NOT NULL,
|
||||
`updated_at` integer NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE INDEX `idx_cases_status` ON `cases` (`status`,`sort_order`);--> statement-breakpoint
|
||||
CREATE TABLE `content_items` (
|
||||
`id` text PRIMARY KEY NOT NULL,
|
||||
`kind` text NOT NULL,
|
||||
`title` text NOT NULL,
|
||||
`description` text DEFAULT '' NOT NULL,
|
||||
`extra` text,
|
||||
`sort_order` integer DEFAULT 0 NOT NULL,
|
||||
`status` text DEFAULT 'published' NOT NULL,
|
||||
`updated_at` integer NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE INDEX `idx_items_kind` ON `content_items` (`kind`,`status`,`sort_order`);--> statement-breakpoint
|
||||
CREATE TABLE `site_settings` (
|
||||
`key` text PRIMARY KEY NOT NULL,
|
||||
`value` text DEFAULT '' NOT NULL,
|
||||
`updated_at` integer NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `posts` ADD `cover_image` text;--> statement-breakpoint
|
||||
ALTER TABLE `posts` ADD `tags` text;
|
||||
@@ -0,0 +1,35 @@
|
||||
# migrations/AGENTS.md
|
||||
|
||||
## Purpose
|
||||
|
||||
Cloudflare D1 的 schema migration 同種子資料。
|
||||
|
||||
## Ownership
|
||||
|
||||
- 擁有 `migrations/` 全部 SQL、`migrations/meta/` 同 `seed.sql`。
|
||||
- Drizzle schema 定義喺 `src/db/schema.ts`(見 `src/db/AGENTS.md`)。
|
||||
|
||||
## Local Contracts
|
||||
|
||||
- **Migration 由工具產生**:`0000_*.sql`、`0001_*.sql` 由 `npm run db:generate`(drizzle-kit)依 `schema.ts` 產生;`migrations/meta/` 係產生檔。**唔好手改**呢啲檔或 meta。
|
||||
- **`seed.sql` 係手寫、獨立於 migration**:全部用 `INSERT OR REPLACE`,可重複執行。`db:migrate` **唔會**執行 seed。
|
||||
- **指令**(本機用 `:local`,雲端省略):
|
||||
- `npm run db:generate` — 由 schema 產生 migration
|
||||
- `npm run db:migrate:local` / `npm run db:migrate` — 套用 migration
|
||||
- `npm run db:seed:local` / `npm run db:seed` — 匯入種子
|
||||
- **Seed 內容**:公司資料(`site_settings`)、首頁內容(`content_items`:service/feature/step/faq)、`cases`、一篇示範 `posts`。
|
||||
- DB 名稱 `yingfung-solar-db`,binding 喺 `wrangler.jsonc`(`database_id` 仍係佔位,部署前要填)。
|
||||
|
||||
## Work Guidance
|
||||
|
||||
- 改 schema → 先 `db:generate`,再 `db:migrate:local`;改 seed → 直接 `db:seed:local`。
|
||||
- 新增 setting key 時同步更新 `src/data/settings-fields.ts`。
|
||||
|
||||
## Verification
|
||||
|
||||
- `npm run db:migrate:local && npm run db:seed:local`,再用 `npm run db:studio` 或 SQL 查證。
|
||||
- `npm run build`。
|
||||
|
||||
## Child DOX Index
|
||||
|
||||
無。
|
||||
@@ -0,0 +1,114 @@
|
||||
{
|
||||
"version": "6",
|
||||
"dialect": "sqlite",
|
||||
"id": "2547788f-b994-4f91-b149-618f655c643b",
|
||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
||||
"tables": {
|
||||
"posts": {
|
||||
"name": "posts",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"slug": {
|
||||
"name": "slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"excerpt": {
|
||||
"name": "excerpt",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"meta_description": {
|
||||
"name": "meta_description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"status": {
|
||||
"name": "status",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "'draft'"
|
||||
},
|
||||
"published_at": {
|
||||
"name": "published_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"idx_posts_slug": {
|
||||
"name": "idx_posts_slug",
|
||||
"columns": [
|
||||
"slug"
|
||||
],
|
||||
"isUnique": true
|
||||
},
|
||||
"idx_posts_published_at": {
|
||||
"name": "idx_posts_published_at",
|
||||
"columns": [
|
||||
"published_at"
|
||||
],
|
||||
"isUnique": false
|
||||
},
|
||||
"idx_posts_status": {
|
||||
"name": "idx_posts_status",
|
||||
"columns": [
|
||||
"status"
|
||||
],
|
||||
"isUnique": false
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"enums": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
{
|
||||
"version": "6",
|
||||
"dialect": "sqlite",
|
||||
"id": "13b1956d-d6ac-4a99-82db-372bdb300834",
|
||||
"prevId": "2547788f-b994-4f91-b149-618f655c643b",
|
||||
"tables": {
|
||||
"cases": {
|
||||
"name": "cases",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"location": {
|
||||
"name": "location",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"completed_at": {
|
||||
"name": "completed_at",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"description": {
|
||||
"name": "description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"image_url": {
|
||||
"name": "image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"sort_order": {
|
||||
"name": "sort_order",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": 0
|
||||
},
|
||||
"status": {
|
||||
"name": "status",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "'published'"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"idx_cases_status": {
|
||||
"name": "idx_cases_status",
|
||||
"columns": [
|
||||
"status",
|
||||
"sort_order"
|
||||
],
|
||||
"isUnique": false
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"content_items": {
|
||||
"name": "content_items",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"kind": {
|
||||
"name": "kind",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"description": {
|
||||
"name": "description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "''"
|
||||
},
|
||||
"extra": {
|
||||
"name": "extra",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"sort_order": {
|
||||
"name": "sort_order",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": 0
|
||||
},
|
||||
"status": {
|
||||
"name": "status",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "'published'"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"idx_items_kind": {
|
||||
"name": "idx_items_kind",
|
||||
"columns": [
|
||||
"kind",
|
||||
"status",
|
||||
"sort_order"
|
||||
],
|
||||
"isUnique": false
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"posts": {
|
||||
"name": "posts",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"slug": {
|
||||
"name": "slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"excerpt": {
|
||||
"name": "excerpt",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"cover_image": {
|
||||
"name": "cover_image",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"tags": {
|
||||
"name": "tags",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"meta_description": {
|
||||
"name": "meta_description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"status": {
|
||||
"name": "status",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "'draft'"
|
||||
},
|
||||
"published_at": {
|
||||
"name": "published_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"idx_posts_slug": {
|
||||
"name": "idx_posts_slug",
|
||||
"columns": [
|
||||
"slug"
|
||||
],
|
||||
"isUnique": true
|
||||
},
|
||||
"idx_posts_published_at": {
|
||||
"name": "idx_posts_published_at",
|
||||
"columns": [
|
||||
"published_at"
|
||||
],
|
||||
"isUnique": false
|
||||
},
|
||||
"idx_posts_status": {
|
||||
"name": "idx_posts_status",
|
||||
"columns": [
|
||||
"status"
|
||||
],
|
||||
"isUnique": false
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"site_settings": {
|
||||
"name": "site_settings",
|
||||
"columns": {
|
||||
"key": {
|
||||
"name": "key",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"value": {
|
||||
"name": "value",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "''"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"enums": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"version": "7",
|
||||
"dialect": "sqlite",
|
||||
"entries": [
|
||||
{
|
||||
"idx": 0,
|
||||
"version": "6",
|
||||
"when": 1789022396039,
|
||||
"tag": "0000_init",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 1,
|
||||
"version": "6",
|
||||
"when": 1789107074198,
|
||||
"tag": "0001_regular_multiple_man",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
-- 盈豐太陽能工程有限公司 — 種子資料
|
||||
-- 用法: npm run db:seed:local / npm run db:seed
|
||||
-- 全部使用 INSERT OR REPLACE,可重複執行。
|
||||
|
||||
INSERT OR REPLACE INTO site_settings (key, value, updated_at) VALUES
|
||||
('company_name', '盈豐太陽能工程有限公司', strftime('%s','now')*1000),
|
||||
('company_short_name', '盈豐太陽能', strftime('%s','now')*1000),
|
||||
('license_no', '電業承辦商編號:待填', strftime('%s','now')*1000),
|
||||
('phone', '+852 0000 0000', strftime('%s','now')*1000),
|
||||
('whatsapp', '85200000000', strftime('%s','now')*1000),
|
||||
('email', '[email protected]', strftime('%s','now')*1000),
|
||||
('address', '香港新界(地址待填)', strftime('%s','now')*1000),
|
||||
('facebook_url', '', strftime('%s','now')*1000),
|
||||
('hero_eyebrow', '香港村屋太陽能專家', strftime('%s','now')*1000),
|
||||
('hero_title', '善用村屋天台 發電慳電賺回報', strftime('%s','now')*1000),
|
||||
('hero_subtitle', '由現場評估、方案建議、安裝施工,到申請同跟進,我哋用清晰易明嘅方式,陪你完成整個村屋太陽能項目。', strftime('%s','now')*1000),
|
||||
('hero_primary_cta', '免費預約評估', strftime('%s','now')*1000),
|
||||
('hero_secondary_cta', '睇完成案例', strftime('%s','now')*1000),
|
||||
('hero_image', 'https://images.unsplash.com/photo-1509391366360-2e959784a276?auto=format&fit=crop&w=1600&q=80', strftime('%s','now')*1000),
|
||||
('seo_default_title', '盈豐太陽能工程有限公司 — 香港村屋太陽能一站式服務', strftime('%s','now')*1000),
|
||||
('seo_default_description', '專營香港村屋太陽能系統:現場評估、合法支架、代辦申請、專業安裝及驗收認證。透明報價,專人跟進,幫你善用天台賺取發電回報。', strftime('%s','now')*1000),
|
||||
('og_image', 'https://images.unsplash.com/photo-1509391366360-2e959784a276?auto=format&fit=crop&w=1200&q=80', strftime('%s','now')*1000);
|
||||
|
||||
INSERT OR REPLACE INTO content_items (id, kind, title, description, extra, sort_order, status, updated_at) VALUES
|
||||
('svc-001', 'service', '村屋天台太陽能系統', '善用村屋天台空間,安裝高效太陽能板,將閒置天台變成穩定收入來源。', 'sun', 1, 'published', strftime('%s','now')*1000),
|
||||
('svc-002', 'service', '合法合規支架工程', '按村屋結構同法規設計鋁合金支架,穩固耐用,確保合乎相關要求。', 'shield', 2, 'published', strftime('%s','now')*1000),
|
||||
('svc-003', 'service', '代辦申請及文件', '由中電/港燈申請、上網電價計劃(FiT)到相關政府文件,全程代辦。', 'file', 3, 'published', strftime('%s','now')*1000),
|
||||
('svc-004', 'service', '專業安裝及驗收', '由認可人士(AP)及註冊電工施工,簽發所需認證文件,安全合法。', 'check', 4, 'published', strftime('%s','now')*1000),
|
||||
('svc-005', 'service', '降低頂樓室溫', '太陽能板為天台遮蔭,有效降低頂樓單位溫度,同時慳冷氣電費。', 'snow', 5, 'published', strftime('%s','now')*1000),
|
||||
('svc-006', 'service', '收益及回本分析', '按日照、面積同電價,提供清晰嘅發電量同回本估算,一目了然。', 'chart', 6, 'published', strftime('%s','now')*1000),
|
||||
|
||||
('feat-001', 'feature', '熟悉香港村屋環境', '深耕本地市場,充分掌握村屋結構、法規同地理限制。', 'map', 1, 'published', strftime('%s','now')*1000),
|
||||
('feat-002', 'feature', '流程清晰易明', '用最簡單直白嘅方式解說回本期同技術細節,絕無花巧術語。', 'file', 2, 'published', strftime('%s','now')*1000),
|
||||
('feat-003', 'feature', '專人快速跟進', '一對一顧問服務,由評估到完工全程透明,隨時解答疑問。', 'user', 3, 'published', strftime('%s','now')*1000),
|
||||
('feat-004', 'feature', '美觀與效率兼備', '追求發電效率之餘,極致重視施工整齊度同建築美感。', 'sparkle', 4, 'published', strftime('%s','now')*1000),
|
||||
('feat-005', 'feature', '重視施工安全', '嚴選耐用器材、嚴格執行安全程序,確保系統長久穩定。', 'shield', 5, 'published', strftime('%s','now')*1000),
|
||||
('feat-006', 'feature', '不硬銷真誠建議', '先幫你了解安裝可行性,未必即刻做,最緊要係問清楚。', 'heart', 6, 'published', strftime('%s','now')*1000),
|
||||
|
||||
('step-001', 'step', '初步諮詢 / 現場評估', '專人上門視察環境,提供專業技術建議。', '01', 1, 'published', strftime('%s','now')*1000),
|
||||
('step-002', 'step', '申請文件處理', '代辦電力公司同政府部門所需嘅申請文件。', '02', 2, 'published', strftime('%s','now')*1000),
|
||||
('step-003', 'step', '安裝施工', '專業團隊進場施工,確保工期同施工品質安全。', '03', 3, 'published', strftime('%s','now')*1000),
|
||||
('step-004', 'step', '驗收認證', '由認可人士及合資格電工簽發 C/PVS、WR1、GF1 等文件。', '04', 4, 'published', strftime('%s','now')*1000),
|
||||
('step-005', 'step', '掛表正式發電', '電力公司掛上電表後,正式開始享受太陽能發電收益。', '05', 5, 'published', strftime('%s','now')*1000),
|
||||
|
||||
('faq-001', 'faq', '村屋天台可以安裝太陽能嗎?', '大部分村屋天台都可以。我哋會先上門評估結構、日照同遮擋情況,再判斷可行性同建議方案。', NULL, 1, 'published', strftime('%s','now')*1000),
|
||||
('faq-002', 'faq', '安裝太陽能大概幾錢?幾時回本?', '造價視乎面積、支架形式同系統容量。一般村屋系統回本期約 6–9 年,之後發電收益基本上係淨賺。我哋會提供清晰報價同回本估算。', NULL, 2, 'published', strftime('%s','now')*1000),
|
||||
('faq-003', 'faq', '需要幾大天台面積?', '一般每 1 kW 系統約需 60–80 平方呎,我哋會按實際可用面積設計最合適嘅容量。', NULL, 3, 'published', strftime('%s','now')*1000),
|
||||
('faq-004', 'faq', '安裝太陽能合唔合法?會唔會影響樓宇結構?', '合規嘅村屋太陽能系統須符合相關法規同電力條例。我哋由設計到施工都依法處理,並由認可人士簽發所需文件。', NULL, 4, 'published', strftime('%s','now')*1000),
|
||||
('faq-005', 'faq', '系統需要保養嗎?', '需要基本保養,例如定期清洗太陽能板同檢查線路。優質器材一般可用 20–25 年,保養得宜發電更穩定。', NULL, 5, 'published', strftime('%s','now')*1000),
|
||||
('faq-006', 'faq', '申請上網電價(FiT)麻煩嗎?', '唔麻煩,我哋會代辦中電或港燈嘅上網電價計劃申請,由填表到掛表全程跟進。', NULL, 6, 'published', strftime('%s','now')*1000);
|
||||
|
||||
INSERT OR REPLACE INTO cases (id, title, location, completed_at, description, image_url, sort_order, status, updated_at) VALUES
|
||||
('case-001', '大埔上碗窯 — 雙玻光伏板 航空鋁支架', '大埔半山', '2026年2月', '採用雙玻光伏板配航空級鋁合金支架,兼顧發電效率同天台景觀。', 'https://images.unsplash.com/photo-1613665813446-82a78c468a1d?auto=format&fit=crop&w=1200&q=80', 1, 'published', strftime('%s','now')*1000),
|
||||
('case-002', '元朗山下村 — 香檳色鋁合金支架', '元朗屏山', '2025年7月', '香檳色支架配合村屋外牆色調,施工整齊,發電穩定。', 'https://images.unsplash.com/photo-1592833159155-c62df1b65634?auto=format&fit=crop&w=1200&q=80', 2, 'published', strftime('%s','now')*1000),
|
||||
('case-003', '西貢西澳村 — 焗白色鋁合金支架', '新界西貢', '2025年5月', '焗白色支架低調美觀,善用天台每一寸可用空間。', 'https://images.unsplash.com/photo-1508514177221-188b1cf16e9d?auto=format&fit=crop&w=1200&q=80', 3, 'published', strftime('%s','now')*1000);
|
||||
|
||||
INSERT OR REPLACE INTO posts (id, slug, title, excerpt, content, cover_image, tags, meta_description, status, published_at, updated_at) VALUES
|
||||
('post-001', 'village-house-solar-guide', '村屋安裝太陽能前,你要知嘅 5 件事', '想喺村屋天台裝太陽能?由天台面積、日照、支架法規到回本期,呢篇幫你一次過搞清楚。',
|
||||
'村屋天台係香港少數可以合法大規模安裝太陽能嘅地方。不過落決定之前,以下 5 點你一定要知。
|
||||
|
||||
## 1. 天台面積有幾大?
|
||||
|
||||
一般每 1 kW 系統約需 60–80 平方呎可用面積。天台有無水箱、樓梯屋或其他遮擋,都會影響實際可安裝容量。
|
||||
|
||||
## 2. 日照同遮擋
|
||||
|
||||
向南、無遮擋嘅天台發電表現最好。我哋會用現場評估同工具分析你屋企嘅日照情況。
|
||||
|
||||
## 3. 支架要合法合規
|
||||
|
||||
村屋太陽能支架須符合相關法規。專業設計嘅鋁合金支架唔單止穩固,亦確保合乎要求。
|
||||
|
||||
## 4. 回本期有幾長?
|
||||
|
||||
一般村屋系統回本期約 6–9 年,之後嘅發電收益基本上係淨賺。實際數字視乎系統容量同電價。
|
||||
|
||||
## 5. 邊個幫你申請?
|
||||
|
||||
由中電/港燈嘅上網電價計劃(FiT)到政府文件,我哋會全程代辦,你唔需要自己四圍撲。
|
||||
|
||||
想知你屋企啱唔啱裝?歡迎 WhatsApp 我哋預約免費評估。',
|
||||
'https://images.unsplash.com/photo-1509391366360-2e959784a276?auto=format&fit=crop&w=1600&q=80', '村屋,太陽能,指南', '村屋安裝太陽能前必知:天台面積、日照、支架法規、回本期同申請流程,一次講清楚。', 'published', strftime('%s','now')*1000, strftime('%s','now')*1000);
|
||||
Reference in New Issue
Block a user