creasi / laravel-nusa
一个旨在提供印度尼西亚行政数据的 Laravel 扩展包
Requires
- php: ^8.1
- ext-sqlite3: *
- laravel/framework: ^9.0|^10.0|^11.0
Requires (Dev)
- composer-runtime-api: *
- laravel/pint: ^1.1
- nunomaduro/collision: ^7.4|^8.0
- orchestra/testbench: ^8.5|^9.0
README
Creasi Nusa
一个简单的库,旨在提供包括坐标和邮政编码在内的印度尼西亚行政区域数据,易于集成到我们的 Laravel 项目中。
要求
- PHP
>=v8.1
以及php-sqlite3
扩展 - Laravel
>=10.0
为什么?
你可能会问,为什么不直接使用现有的 laravolt/indonesia 包?这个包已经存在一段时间了,并且已经被数百人使用,的确如此。但是,我们需要一个安装后即可使用的包。
我一直在使用 edwardsamuel/Wilayah-Administratif-Indonesia 并对其做出了一些贡献,但它似乎自 2018 年以来就不再维护。更重要的是,它是用 Python 而不是 PHP 编写的。
这就是我们选择 cahyadsn/wilayah 的原因,它在法律方面具有稳健和强大的数据库,但它实际上不是一个可以作为依赖项安装的包。换句话说,它还有一些工作要做。
我们还发现,w3appdev/kodepos 提供了更好的数据库结构,可以轻松地与 cahyadsn/wilayah 的数据库进行单一查询映射。
我们对“易于集成”和“安装后即可使用”的理解是,我们不应该处理数据迁移和播种,因为印度尼西亚不是一个小的国家,运行播种器处理如此大量的数据需要相当长的时间,更不用说应用程序播种器了。
为什么是 PHP >=8.1
和 Laravel >=10.0
,你可能会问?因为为什么不呢!
安装
composer require creasi/laravel-nusa
就是这样
路线图
- 基本模型
- 省份,包括
laltitude
、longitude
和coordinates
- 区,包括
laltitude
、longitude
和coordinates
- 市镇
- 村庄,包括
postal_code
- 省份,包括
- 路由
用法
幸运的是,Laravel 提供了一种方便的方式来拥有某种“关系”,无论数据库引擎如何。因此,我们可以将行政数据放入 sqlite
数据中,一旦我们安装了它,我们就可以方便地使用 eloquent 模型来从我们的项目中使用它。
ReSTful API
-
获取所有省份
GET {APP_URL}/nusa/provinces
-
查询参数
-
示例
-
GET http://localhost:8000/nusa/provinces
{ "data": [ { "code": 33, "name": "Jawa Tengah", "latitude": -6.9934809206806, "longitude": 110.42024335421, "coordinates": [...], "postal_codes": [...], }, { ... } ], "links": { "first": "http://localhost:8000/nusa/provinces?page=1", "last": "http://localhost:8000/nusa/provinces?page=3", "prev": null, "next": "http://localhost:8000/nusa/provinces?page=2", }, "meta": { "current_page": 1, "from": 1, "last_page": 3, "links": [ { "url": null, "label": "« Previous", "active": false, }, { "url": "http://localhost:8000/nusa/provinces?page=1", "label": "1", "active": true, }, { ... }, { "url": "http://localhost/nusa/provinces?page=2", "label": "Next »", "active": false, }, ], "path": "http://localhost:8000/nusa/provinces", "per_page": 15, "to": 15, "total": 34 } }
-
-
-
显示一个省份
GET {APP_URL}/nusa/provinces/{province}
- 路由参数:
{province}
省份代码 - 示例
-
GET http://localhost:8000/nusa/provinces/33
{ "data": { "code": 33, "name": "Jawa Tengah", "latitude": -6.9934809206806, "longitude": 110.42024335421, "coordinates": [...], "postal_codes": [...], }, "meta": {} }
-
- 路由参数:
-
获取一个省份中的所有区
GET {APP_URL}/nusa/provinces/{province}/regencies
- 路由参数:
{province}
省份代码 - 示例
-
GET http://localhost:8000/nusa/provinces/33/regencies
{ "data": [ { "code": 3375, "province_code": 33, "name": "Kota Pekalongan", "latitude": -6.8969497174987, "longitude": 109.66208089654, "coordinates": [...], "postal_codes": [...], }, { ... } ], "links": { "first": "http://localhost:8000/nusa/provinces/33/regencies?page=1", "last": "http://localhost:8000/nusa/provinces/33/regencies?page=3", "prev": null, "next": "http://localhost:8000/nusa/provinces/33/regencies?page=2", }, "meta": { "current_page": 1, "from": 1, "last_page": 3, "links": [ { "url": null, "label": "« Previous", "active": false, }, { "url": "http://localhost:8000/nusa/provinces/33/regencies?page=1", "label": "1", "active": true, }, { ... }, { "url": "http://localhost/nusa/provinces/33/regencies?page=2", "label": "Next »", "active": false, }, ], "path": "http://localhost:8000/nusa/provinces/33/regencies", "per_page": 15, "to": 15, "total": 35 } }
-
- 路由参数:
-
获取一个省份中的所有市镇
GET {APP_URL}/nusa/provinces/{province}/districts
- 路由参数:
{province}
省份代码 - 示例
-
GET http://localhost:8000/nusa/provinces/33/districts
{ "data": [ { "code": 330101, "regency_code": 3301, "province_code": 33, "name": "Kedungreja", "postal_codes": [ 53263 ] }, { ... } ], "links": { "first": "http://localhost:8000/nusa/provinces/33/districts?page=1", "last": "http://localhost:8000/nusa/provinces/33/districts?page=39", "prev": null, "next": "http://localhost/nusa/provinces/33/districts?page=2", }, "meta": { "current_page": 1, "from": 1, "last_page": 39, "links": [ { "url": null, "label": "« Previous", "active": false, }, { "url": "http://localhost:8000/nusa/provinces/33/districts?page=1", "label": "1", "active": true, }, { ... }, { "url": "http://localhost/nusa/provinces/33/districts?page=2", "label": "Next »", "active": false, }, ], "path": "http://localhost:8000/nusa/provinces/33/districts", "per_page": 15, "to": 15, "total": 576 } }
-
- 路由参数:
-
获取一个省份中的所有村庄
GET {APP_URL}/nusa/provinces/{province}/villages
- 路由参数:
{province}
省份代码 - 示例
-
GET http://localhost:8000/nusa/provinces/33/villages
{ "data": [ { "code": 3301012001, "district_code": 330101, "regency_code": 3301, "province_code": 33, "name": "Tambakreja", "postal_code": 53263, }, { ... } ], "links": { "first": "http://localhost:8000/nusa/provinces/33/villages?page=1", "last": "http://localhost:8000/nusa/provinces/33/villages?page=571", "prev": null, "next": "http://localhost:8000/nusa/provinces/33/villages?page=2", }, "meta": { "current_page": 1, "from": 1, "last_page": 571, "links": [ { "url": null, "label": "« Previous", "active": false, }, { "url": "http://localhost:8000/nusa/provinces/33/villages?page=1", "label": "1", "active": true, }, { ... }, { "url": "http://localhost:8000/nusa/provinces/33/villages?page=2", "label": "Next »", "active": false, }, ], "path": "http://localhost:8000/nusa/provinces/33/villages", "per_page": 15, "to": 15, "total": 8562 } }
-
- 路由参数:
-
获取所有地区
GET {APP_URL}/nusa/regencies
-
查询参数
-
示例
-
GET http://localhost:8000/nusa/regencies
{ "data": [ { "code": 3375, "province_code": 33, "name": "Kota Pekalongan", "latitude": -6.8969497174987, "longitude": 109.66208089654, "coordinates": [...], "postal_codes": [...], }, { ... } ], "links": { "first": "http://localhost:8000/nusa/regencies?page=1", "last": "http://localhost:8000/nusa/regencies?page=35", "prev": null, "next": "http://localhost:8000/nusa/regencies?page=2", }, "meta": { "current_page": 1, "from": 1, "last_page": 35, "links": [ { "url": null, "label": "« Previous", "active": false, }, { "url": "http://localhost:8000/nusa/regencies?page=1", "label": "1", "active": true, }, { ... }, { "url": "http://localhost/nusa/regencies?page=2", "label": "Next »", "active": false, }, ], "path": "http://localhost:8000/nusa/regencies", "per_page": 15, "to": 15, "total": 514 } }
-
-
-
显示一个地区
GET {APP_URL}/nusa/regencies/{地区}
- 路由参数:
{地区}
地区代码 - 示例
-
GET http://localhost:8000/nusa/regencies/3375
{ "data": { "code": 3375, "province_code": 33, "name": "Kota Pekalongan", "latitude": -6.8969497174987, "longitude": 109.66208089654, "coordinates": [...], "postal_codes": [...], }, "meta": {} }
-
- 路由参数:
-
获取一个地区下的所有区
GET {APP_URL}/nusa/regencies/{地区}/districts
- 路由参数:
{地区}
地区代码 - 示例
-
GET http://localhost:8000/nusa/regencies/3375/districts
{ "data": [ { "code": 337501, "regency_code": 3375, "province_code": 33, "name": "Pekalongan Barat", "postal_codes": [ 51111 51112 51113 51116 51117 51151 ] }, { ... } ], "links": { "first": "http://localhost:8000/nusa/regencies/3375/districts?page=1", "last": "http://localhost:8000/nusa/regencies/3375/districts?page=1", "prev": null, "next": null, }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false, }, { "url": "http://localhost:8000/nusa/regencies/3375/districts?page=1", "label": "1", "active": true, }, { ... }, { "url": null, "label": "Next »", "active": false, }, ], "path": "http://localhost:8000/nusa/regencies/3375/districts", "per_page": 15, "to": 4, "total": 4 } }
-
- 路由参数:
-
获取一个地区下的所有村庄
GET {APP_URL}/nusa/regencies/{地区}/villages
- 路由参数:
{地区}
地区代码 - 示例
-
GET http://localhost:8000/nusa/regencies/3375/villages
{ "data": [ { "code": 3375011002, "district_code": 337501, "regency_code": 3375, "province_code": 33, "name": "Medono", "postal_code": 51111, }, { ... } ], "links": { "first": "http://localhost:8000/nusa/regencies/3375/villages?page=1", "last": "http://localhost:8000/nusa/regencies/3375/villages?page=2", "prev": null, "next": "http://localhost:8000/nusa/regencies/3375/villages?page=2", }, "meta": { "current_page": 1, "from": 1, "last_page": 2, "links": [ { "url": null, "label": "« Previous", "active": false, }, { "url": "http://localhost:8000/nusa/regencies/3375/villages?page=1", "label": "1", "active": true, }, { ... }, { "url": "http://localhost:8000/nusa/regencies/3375/villages?page=2", "label": "Next »", "active": false, }, ], "path": "http://localhost:8000/nusa/regencies/3375/villages", "per_page": 15, "to": 15, "total": 27 } }
-
- 路由参数:
-
获取所有区
GET {APP_URL}/nusa/districts
-
查询参数
-
示例
-
GET http://localhost:8000/nusa/districts
{ "data": [ { "code": 110101, "regency_code": 1101, "province_code": 11, "name": "Bakongan", "postal_codes": [ 23773 ], }, { ... } ], "links": { "first": "http://localhost:8000/nusa/districts?page=1", "last": "http://localhost:8000/nusa/districts?page=485", "prev": null, "next": "http://localhost:8000/nusa/districts?page=2", }, "meta": { "current_page": 1, "from": 1, "last_page": 485, "links": [ { "url": null, "label": "« Previous", "active": false, }, { "url": "http://localhost:8000/nusa/districts?page=1", "label": "1", "active": true, }, { ... }, { "url": "http://localhost:8000/nusa/districts?page=2", "label": "Next »", "active": false, }, ], "path": "http://localhost:8000/nusa/districts", "per_page": 15, "to": 15, "total": 7266 } }
-
-
-
显示一个区
GET {APP_URL}/nusa/districts/{区}
- 路由参数:
{区}
区代码 - 示例
-
GET http://localhost:8000/nusa/districts/337503
{ "data": { "code": 337503, "regency_code": 3375, "province_code": 33, "name": "Pekalongan Utara", "postal_codes": [ 51141 51143 51146 51147 51148 51149 ], }, "meta": {} }
-
- 路由参数:
-
获取一个区下的所有村庄
GET {APP_URL}/nusa/districts/{区}/villages
- 路由参数:
{区}
区代码 - 示例
-
GET http://localhost:8000/nusa/districts/337503/villages
{ "data": [ { "code": 3375031002, "district_code": 337503, "regency_code": 3375, "province_code": 33, "name": "Krapyak", "postal_code": 51147, }, { ... } ], "links": { "first": "http://localhost:8000/nusa/districts/337503/villages?page=1", "last": "http://localhost:8000/nusa/districts/337503/villages?page=1", "prev": null, "next": null, }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Previous", "active": false, }, { "url": "http://localhost:8000/nusa/districts/337503/villages?page=1", "label": "1", "active": true, }, { ... }, { "url": null, "label": "Next »", "active": false, }, ], "path": "http://localhost:8000/nusa/districts/337503/villages", "per_page": 15, "to": 7, "total": 7 } }
-
- 路由参数:
-
获取所有村庄
GET {APP_URL}/nusa/villages
-
查询参数
-
示例
-
GET http://localhost:8000/nusa/villages
{ "data": [ { "code": 1101012001, "district_code": 110101, "regency_code": 1101, "province_code": 11, "name": "Keude Bakongan", "postal_code": 23773, }, { ... } ], "links": { "first": "http://localhost:8000/nusa/villages?page=1", "last": "http://localhost:8000/nusa/villages?page=5565", "prev": null, "next": "http://localhost:8000/nusa/villages?page=2", }, "meta": { "current_page": 1, "from": 1, "last_page": 5565, "links": [ { "url": null, "label": "« Previous", "active": false, }, { "url": "http://localhost:8000/nusa/villages?page=1", "label": "1", "active": true, }, { ... }, { "url": "http://localhost:8000/nusa/villages?page=2", "label": "Next »", "active": false, }, ], "path": "http://localhost:8000/nusa/villages", "per_page": 15, "to": 15, "total": 83467 } }
-
-
-
获取一个村庄
GET {APP_URL}/nusa/villages/{村庄}
- 路由参数:
{村庄}
村庄代码 - 示例
-
GET http://localhost:8000/nusa/villages/3375031006
{ "data": { "code": 3375031006, "district_code": 337503, "regency_code": 3375, "province_code": 33, "name": "Padukuhan Kraton", "postal_code": 51146, }, "meta": {} }
-
- 路由参数:
模型
本库包含以下4个主要模型:
Creasi\Nusa\Models\Province
Creasi\Nusa\Models\Regency
Creasi\Nusa\Models\District
Creasi\Nusa\Models\Village
每个模型都提供相似的接口,这意味着每个模型都具有code
和name
字段,您还可以使用search()
作用域方法通过code
或name
查询模型。例如:
use Creasi\Nusa\Models\Province; $province = Province::search(33)->first(); // or $province = Province::search('Jawa Tengah')->first();
请注意,只有Province
和Regency
包含latitude
、longitude
和coordinates
数据,而Village
包含postal_code
。这是由于cahyadsn/wilayah
提供的。
因此,我们期望Province
、Regency
和District
能够访问该地区内可用的所有postal_codes
,我们相信这可能在某些情况下很有帮助。就是这样。
// Retrieve distict list of postal codes available in the province $province->postal_codes;
根据我们开发各种产品的经验,我们最需要此类数据的情况是填写地址表单。但每个项目的需求可能有所不同。因此,我们还提供了最基础的Address
模型,它使用默认的数据库连接,并可以轻松扩展以满足项目的需求。
在这种情况下,您可能想要使用我们的WithAddresses
或WithAdress
特性来扩展现有的模型,如下所示:
use Creasi\Nusa\Contracts\HasAddresses; use Creasi\Nusa\Models\Concerns\WithAddresses; class User extends Model implements HasAddresses { use WithAddresses; }
要使用Address
模型,您需要发布迁移,如下所示:
php artisan vendor:publish --tag creasi-migrations
然后简单地运行artisan migrate
以应用额外的迁移。
数据库
有关数据库结构文档,请参阅database/README.md
。
自定义
默认情况下,nusa
将为您的项目添加另一个database.connections
配置,并将其用作所有nusa
模型的默认数据库,并且您可以任意进行自定义。
-
通过运行以下命令发布
nusa
的配置:./artisan vendor:publish --tag creasi-nusa-config
-
添加新的
database.connections
,键为您的creasi.nusa.connection
,例如您有:// config/nusa.php return [ 'connection' => 'indonesia', ];
因此,您需要:
// config/database.php return [ 'connections' => [ 'indonesia' => [ // ... ] ], ];
在扩展Address
模型方面,如果您想使用自己的Address
模型实现,请查看creasi.nusa.addressable
配置。
注意
目前,只有connection
名称和table
名称可供自定义,我们只使用sqlite
驱动程序进行测试。如果您在使用其他数据库驱动程序时遇到任何问题,请告诉我们。
贡献
-
克隆仓库并
cd
进入它git clone --recurse-submodules git@github.com:creasico/laravel-nusa.git
-
安装依赖项
composer install
-
创建新数据库,默认配置如下:
dbname
:nusantara
dbhost
:127.0.0.1
dbuser
:root
dbpass
:secret
mysql -e 'create database nusantara;'
-
最后但并非最不重要的是,运行
db:import
命令composer db:import
如果您使用了不同的配置,您可以编辑此文件,但请不要提交您的更改。
完成您有意义的贡献后,运行以下命令以确保一切按预期工作。
composer test
注意
- 提交约定:本项目遵循使用Conventional Commits,并使用@commitlint/config-conventional作为标准,因此请确保您已安装其npm依赖项。
- 代码风格:本项目使用
Laravel Pint
的laravel
预设作为编码标准,因此请确保您遵循规则。
致谢
许可证
此库是开源软件,受MIT许可证许可。