mirror of
https://github.com/sky-systems/sky_phone.git
synced 2026-08-29 00:01:29 +00:00
ADD - introduce SkyRide taxi platform
This commit is contained in:
@@ -320,3 +320,100 @@ Config.Calendar = {
|
||||
FutureSeconds = 5 * 365 * 24 * 60 * 60,
|
||||
ReminderPollSeconds = 15,
|
||||
}
|
||||
|
||||
Config.SkyRide = {
|
||||
PaymentAccount = "bank",
|
||||
Currency = "$",
|
||||
DistanceUnit = "kilometer", -- kilometer or mile
|
||||
QuoteLifetimeSeconds = 120,
|
||||
HistoryLimit = 50,
|
||||
ReadsPerMinute = 120,
|
||||
ActionsPerMinute = 30,
|
||||
QuotesPerMinute = 20,
|
||||
RecoveryIntervalSeconds = 15,
|
||||
PaymentPendingRecoverySeconds = 30,
|
||||
PickupSelectionRadius = 150.0,
|
||||
ArrivalRadius = 40.0,
|
||||
CompletionRadius = 80.0,
|
||||
MinimumDistanceMeters = 250,
|
||||
MaximumDistanceMeters = 40000,
|
||||
RouteDistanceMultiplier = 1.25,
|
||||
AverageSpeedMetersPerSecond = 12.0,
|
||||
DriverPayoutPercent = 85,
|
||||
RatingCommentMaxLength = 300,
|
||||
MaximumTip = 10000,
|
||||
CustomFare = {
|
||||
Enabled = true,
|
||||
MinimumPrice = 5,
|
||||
MaximumPrice = 100000,
|
||||
MinimumCalculatedMultiplier = 0.5,
|
||||
MaximumCalculatedMultiplier = 3.0,
|
||||
},
|
||||
DriverJobs = {
|
||||
taxi = 0,
|
||||
},
|
||||
Services = {
|
||||
{
|
||||
Id = "taxi",
|
||||
Seats = 4,
|
||||
EtaMinutes = 3,
|
||||
BaseFare = 12,
|
||||
PricePerKilometer = 18,
|
||||
PricePerMile = 29,
|
||||
PricePerMinute = 1,
|
||||
MinimumFare = 15,
|
||||
},
|
||||
{
|
||||
Id = "comfort",
|
||||
Seats = 4,
|
||||
EtaMinutes = 5,
|
||||
BaseFare = 16,
|
||||
PricePerKilometer = 24,
|
||||
PricePerMile = 39,
|
||||
PricePerMinute = 2,
|
||||
MinimumFare = 22,
|
||||
},
|
||||
{
|
||||
Id = "xl",
|
||||
Seats = 6,
|
||||
EtaMinutes = 7,
|
||||
BaseFare = 20,
|
||||
PricePerKilometer = 30,
|
||||
PricePerMile = 48,
|
||||
PricePerMinute = 2,
|
||||
MinimumFare = 28,
|
||||
},
|
||||
{
|
||||
Id = "premium",
|
||||
Seats = 4,
|
||||
EtaMinutes = 8,
|
||||
BaseFare = 28,
|
||||
PricePerKilometer = 40,
|
||||
PricePerMile = 64,
|
||||
PricePerMinute = 3,
|
||||
MinimumFare = 38,
|
||||
},
|
||||
},
|
||||
QuickLocations = {
|
||||
{
|
||||
Id = "legion-square",
|
||||
Label = "Legion Square",
|
||||
Coords = { x = -265.1, y = -960.2, z = 31.2 },
|
||||
},
|
||||
{
|
||||
Id = "diamond-casino",
|
||||
Label = "Diamond Casino",
|
||||
Coords = { x = 925.2, y = 46.4, z = 81.1 },
|
||||
},
|
||||
{
|
||||
Id = "airport",
|
||||
Label = "Los Santos Airport",
|
||||
Coords = { x = -1037.7, y = -2737.8, z = 20.2 },
|
||||
},
|
||||
{
|
||||
Id = "vinewood",
|
||||
Label = "Vinewood",
|
||||
Coords = { x = -594.4, y = -929.9, z = 23.9 },
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -396,6 +396,95 @@ Locales["en"] = {
|
||||
request_failed = "The garage request failed.", default = "The garage request failed.",
|
||||
},
|
||||
},
|
||||
skyride = {
|
||||
name = "SkyRide", loading = "Loading SkyRide", unavailable = "SkyRide unavailable", tryAgain = "Try Again",
|
||||
mode = { rider = "Ride", driver = "Drive" },
|
||||
riderEyebrow = "Ride anywhere", whereTo = "Where to?", pickup = "Pickup", destination = "Destination",
|
||||
currentLocation = "Current location", notSelected = "Not selected", location = "Choose a location",
|
||||
chooseLocation = { pickup = "Set pickup", destination = "Choose destination" },
|
||||
chooseOnMap = "Choose on map", chooseOnMapBody = "Tap a precise point on the Los Santos map.",
|
||||
pickOnMap = { pickup = "Tap your pickup point", destination = "Tap your destination" },
|
||||
tapMapHint = "Drag and zoom the map, then tap to place the pin.", mapPoint = "Map pin", map = "Map", useGps = "Use your live position",
|
||||
zoomIn = "Zoom in", zoomOut = "Zoom out", resetMap = "Reset map view",
|
||||
savedPlaces = "Saved places", savedPlace = "Saved place", quickDestinations = "Quick destinations",
|
||||
quickLocations = { ["legion-square"] = "Legion Square", ["diamond-casino"] = "Diamond Casino", airport = "Los Santos Airport", vinewood = "Vinewood" },
|
||||
viewRides = "View Ride Options", change = "Change", requestRide = "Request SkyRide",
|
||||
serviceMeta = "{eta} min away · {seats} seats", distanceMeters = "{distance} m",
|
||||
distanceKilometers = "{distance} km", distanceMiles = "{distance} mi", durationMinutes = "{minutes} min",
|
||||
fare = "Trip fare", calculatedFare = "Calculated", customFare = "Own price",
|
||||
calculatedFareBody = "Distance, time, and selected service included.",
|
||||
customFareRange = "Allowed range: {minimum} to {maximum}", applyCustomFare = "Apply Own Price",
|
||||
perKilometer = "{price} / km", perMile = "{price} / mi", rideStatus = "Ride status",
|
||||
services = {
|
||||
taxi = { name = "Taxi" }, comfort = { name = "Comfort" }, xl = { name = "XL" }, premium = { name = "Premium" },
|
||||
},
|
||||
ride = "SkyRide",
|
||||
driver = {
|
||||
online = "You are online", offline = "You are offline",
|
||||
onlineBody = "New ride requests can reach you now.", offlineBody = "Go online when you are ready to drive.",
|
||||
toggleStatus = "Toggle driver status", today = "Today", requests = "Nearby requests", accept = "Accept Ride",
|
||||
noRequests = "No nearby requests", noRequestsBody = "New requests will appear here automatically.",
|
||||
goOnline = "Go online to receive rides", goOnlineBody = "Switch your driver status on to see nearby requests.",
|
||||
statusBody = {
|
||||
searching = "A passenger is waiting for a driver.", accepted = "Navigate to the passenger pickup.",
|
||||
driver_arriving = "You are heading to the passenger.", arrived = "Confirm when the passenger is in the vehicle.",
|
||||
in_progress = "Follow the route to the destination.", completed = "The ride has been completed.",
|
||||
cancelled = "This ride was cancelled.",
|
||||
},
|
||||
actions = { arrive = "I Have Arrived", start = "Start Ride", complete = "Complete Ride" },
|
||||
},
|
||||
passenger = "Passenger", vehicle = "Vehicle", navigate = "Navigate", call = "Call", message = "Message",
|
||||
cancelRide = "Cancel Ride", cancelTitle = "Cancel this ride?",
|
||||
cancelBody = "Your driver or passenger will be notified. A cancellation fee may apply.",
|
||||
safetyNote = "Trip details are shared only while this ride is active.", waypointSet = "Route added to your GPS.",
|
||||
status = {
|
||||
searching = "Finding a driver", accepted = "Driver found", driver_arriving = "Driver en route",
|
||||
arrived = "Driver arrived", in_progress = "On the way", completed = "Completed", cancelled = "Cancelled",
|
||||
},
|
||||
statusBody = {
|
||||
searching = "We are matching you with a nearby driver.", accepted = "Your driver is preparing to pick you up.",
|
||||
driver_arriving = "Your driver is on the way to your pickup.", arrived = "Your driver is waiting at the pickup point.",
|
||||
in_progress = "You are on the way to your destination.", completed = "You have arrived at your destination.",
|
||||
cancelled = "This ride is no longer active.",
|
||||
},
|
||||
navigation = "SkyRide navigation",
|
||||
tabs = { home = "Home", rides = "Rides", activity = "Activity", messages = "Messages", profile = "Profile" },
|
||||
rides = "Your Rides", ridesBody = "Review completed and cancelled rides.", noRides = "No rides yet",
|
||||
noRidesBody = "Completed and cancelled rides will appear here.", activity = "Activity",
|
||||
activityBody = "Recent trip updates and milestones.", noActivity = "No recent activity",
|
||||
noActivityBody = "Ride updates will appear here.", messages = "Messages",
|
||||
messagesBody = "Contact your active driver or passenger.", noMessages = "No active contact",
|
||||
noMessagesBody = "Book or accept a ride to contact the other person.", openMessages = "Open Messages",
|
||||
account = "Account", paymentMethod = "Payment Method", paymentMethods = { bank = "Bank", cash = "Cash", default = "Payment method" }, safety = "Safety Center",
|
||||
safetyBody = "Help, trip sharing, and emergency information", driverMode = "Driver Mode",
|
||||
driverModeBody = "Accept ride requests and track your earnings", completedRides = "Completed",
|
||||
cancelledRides = "Cancelled", acceptance = "Acceptance", rating = "Rating", notAvailable = "N/A",
|
||||
memberSince = "SkyRide member since {date}", rideComplete = "Ride Complete", rateRide = "Rate your ride",
|
||||
rateRideBody = "How was your trip? Your feedback helps every rider.", ratingValue = "{rating} stars",
|
||||
tip = "Add a tip", noTip = "No tip", comment = "Comment", commentPlaceholder = "Share an optional note...",
|
||||
submitRating = "Submit Rating", notNow = "Not Now", ratingSaved = "Thanks for your feedback.",
|
||||
errors = {
|
||||
skyride_unavailable = "SkyRide is currently unavailable.",
|
||||
invalid_location = "Choose a valid pickup and destination.", quote_not_found = "These ride options are no longer available.",
|
||||
pickup_too_far = "Move closer to the selected pickup point.", invalid_route = "No suitable route was found for this ride.",
|
||||
invalid_custom_fare = "Choose an own price inside the allowed range.",
|
||||
quote_expired = "These ride options expired. Request a new quote.", active_ride_exists = "Finish or cancel your active ride first.",
|
||||
invalid_driver_status = "That driver status is not available.", driver_not_eligible = "This account is not eligible for Driver Mode.",
|
||||
driver_offline = "Go online before accepting a ride.", driver_unavailable = "That driver is no longer available.",
|
||||
driver_vehicle_required = "Sit in the driver's seat of a vehicle before accepting a ride.",
|
||||
ride_not_found = "This ride is no longer available.", not_ride_participant = "You are not part of this ride.",
|
||||
invalid_ride_status = "This action is not available for the ride.", invalid_rating = "Choose a rating from one to five stars.",
|
||||
driver_too_far = "Move closer to the required ride location.", passenger_too_far = "The passenger is not close enough to start.",
|
||||
destination_too_far = "Move closer to the destination to complete the ride.", payout_failed = "The driver payout could not be completed.",
|
||||
refund_failed = "The ride refund could not be completed.", invalid_cancel_reason = "Choose a valid cancellation reason.",
|
||||
invalid_tip = "Choose a valid tip amount.", invalid_comment = "The rating comment is not valid.",
|
||||
tip_failed = "The tip could not be processed.", insufficient_funds = "Your selected payment method has insufficient funds.",
|
||||
rate_limited = "Please wait a moment before trying again.", request_failed = "SkyRide could not complete the request.",
|
||||
device_not_open = "Open the phone again to use SkyRide.", device_not_owned = "This phone does not belong to this character.",
|
||||
device_locked = "Unlock this phone to use SkyRide.",
|
||||
default = "SkyRide could not complete the request.",
|
||||
},
|
||||
},
|
||||
calculator = { name = "Calculator" },
|
||||
snake = {
|
||||
name = "Snake", backToMenu = "Back to game menu", board = "Snake game board",
|
||||
|
||||
@@ -27,6 +27,7 @@ client_scripts {
|
||||
'source/client/animations.lua',
|
||||
'source/client/camera.lua',
|
||||
'source/client/garage.lua',
|
||||
'source/client/skyride.lua',
|
||||
'source/bridge/client/radio.lua',
|
||||
'source/client/main.lua',
|
||||
'source/client/radio.lua',
|
||||
@@ -61,6 +62,7 @@ server_scripts {
|
||||
'source/server/fliptok.lua',
|
||||
'source/server/picstagram.lua',
|
||||
'source/server/map.lua',
|
||||
'source/server/skyride.lua',
|
||||
'source/server/calendar.lua',
|
||||
'source/server/radio.lua',
|
||||
}
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
local server_callbacks = {
|
||||
"skyride:bootstrap",
|
||||
"skyride:quote",
|
||||
"skyride:request",
|
||||
"skyride:set-driver-status",
|
||||
"skyride:accept",
|
||||
"skyride:arrive",
|
||||
"skyride:start",
|
||||
"skyride:complete",
|
||||
"skyride:cancel",
|
||||
"skyride:rate",
|
||||
"skyride:history",
|
||||
}
|
||||
|
||||
local function normalize_person(person)
|
||||
if type(person) ~= "table" then
|
||||
return
|
||||
end
|
||||
if person.avatarUrl == false then
|
||||
person.avatarUrl = json.null
|
||||
end
|
||||
end
|
||||
|
||||
local function normalize_ride(ride)
|
||||
if type(ride) ~= "table" then
|
||||
return
|
||||
end
|
||||
normalize_person(ride.passenger)
|
||||
if ride.driver == false then
|
||||
ride.driver = json.null
|
||||
return
|
||||
end
|
||||
if type(ride.driver) ~= "table" then
|
||||
return
|
||||
end
|
||||
normalize_person(ride.driver)
|
||||
local vehicle = ride.driver.vehicle
|
||||
local model_hash = type(vehicle) == "table" and tonumber(vehicle.model) or nil
|
||||
if not model_hash then
|
||||
return
|
||||
end
|
||||
local display_name = GetDisplayNameFromVehicleModel(model_hash)
|
||||
local label = display_name and GetLabelText(display_name) or nil
|
||||
if label and label ~= "NULL" and label ~= "CARNOTFOUND" then
|
||||
vehicle.model = label
|
||||
end
|
||||
end
|
||||
|
||||
local function normalize_rides(rides)
|
||||
if type(rides) ~= "table" then
|
||||
return
|
||||
end
|
||||
for index = 1, #rides do
|
||||
normalize_ride(rides[index])
|
||||
end
|
||||
end
|
||||
|
||||
local function normalize_state(data)
|
||||
if type(data) ~= "table" then
|
||||
return
|
||||
end
|
||||
if data.activeRide == false then
|
||||
data.activeRide = json.null
|
||||
else
|
||||
normalize_ride(data.activeRide)
|
||||
end
|
||||
if data.pendingRating == false then
|
||||
data.pendingRating = json.null
|
||||
else
|
||||
normalize_ride(data.pendingRating)
|
||||
end
|
||||
normalize_rides(data.availableRequests)
|
||||
normalize_rides(data.history)
|
||||
normalize_rides(data.items)
|
||||
if type(data.profile) == "table" then
|
||||
if data.profile.acceptanceRate == false then
|
||||
data.profile.acceptanceRate = json.null
|
||||
end
|
||||
if data.profile.avatarUrl == false then
|
||||
data.profile.avatarUrl = json.null
|
||||
end
|
||||
if data.profile.earningsToday == false then
|
||||
data.profile.earningsToday = json.null
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for index = 1, #server_callbacks do
|
||||
local callback_name = server_callbacks[index]
|
||||
RegisterNUICallback(callback_name, function(data, cb)
|
||||
local result = Bridge.Callbacks.Trigger("sky_phone:" .. callback_name, data or {})
|
||||
if not result then
|
||||
cb({ success = false, error = "request_failed" })
|
||||
return
|
||||
end
|
||||
if result.success and type(result.data) == "table" then
|
||||
normalize_state(result.data)
|
||||
end
|
||||
cb(result)
|
||||
end)
|
||||
end
|
||||
|
||||
RegisterNUICallback("skyride:get-player-coords", function(_, cb)
|
||||
local coords = GetEntityCoords(PlayerPedId())
|
||||
cb({
|
||||
success = true,
|
||||
data = {
|
||||
coords = {
|
||||
x = coords.x,
|
||||
y = coords.y,
|
||||
z = coords.z,
|
||||
},
|
||||
},
|
||||
})
|
||||
end)
|
||||
|
||||
RegisterNetEvent("sky_phone:skyride:changed", function(data)
|
||||
normalize_state(data)
|
||||
SendNUIMessage({ type = "skyride:changed", data = data })
|
||||
end)
|
||||
@@ -1517,6 +1517,125 @@ local schema = {
|
||||
},
|
||||
tableOptions = "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
|
||||
},
|
||||
{
|
||||
name = "sky_phone_skyride_profiles",
|
||||
columns = {
|
||||
{ name = "id", type = "CHAR(36) NOT NULL", characterSet = "ascii", collation = "ascii_bin" },
|
||||
{
|
||||
name = "owner_identifier",
|
||||
type = "VARCHAR(80) NOT NULL",
|
||||
characterSet = "ascii",
|
||||
collation = "ascii_bin",
|
||||
},
|
||||
{ name = "created_at", type = "DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP" },
|
||||
},
|
||||
primaryKey = "id",
|
||||
uniqueKeys = {
|
||||
{ name = "uniq_sky_phone_skyride_owner", columns = "(`owner_identifier`)" },
|
||||
},
|
||||
tableOptions = "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
|
||||
},
|
||||
{
|
||||
name = "sky_phone_skyride_rides",
|
||||
columns = {
|
||||
{ name = "id", type = "CHAR(36) NOT NULL", characterSet = "ascii", collation = "ascii_bin" },
|
||||
{
|
||||
name = "passenger_profile_id",
|
||||
type = "CHAR(36) NOT NULL",
|
||||
characterSet = "ascii",
|
||||
collation = "ascii_bin",
|
||||
},
|
||||
{
|
||||
name = "driver_profile_id",
|
||||
type = "CHAR(36) NULL",
|
||||
characterSet = "ascii",
|
||||
collation = "ascii_bin",
|
||||
},
|
||||
{ name = "passenger_name", type = "VARCHAR(80) NOT NULL" },
|
||||
{ name = "driver_name", type = "VARCHAR(80) NULL" },
|
||||
{
|
||||
name = "status",
|
||||
type = "ENUM('payment_pending','searching','accepted','arrived','in_progress','completing','completed','cancelled') NOT NULL",
|
||||
},
|
||||
{
|
||||
name = "service_class",
|
||||
type = "ENUM('taxi','comfort','xl','premium') NOT NULL",
|
||||
},
|
||||
{ name = "pickup_label", type = "VARCHAR(80) NOT NULL" },
|
||||
{ name = "pickup_x", type = "DECIMAL(10,3) NOT NULL" },
|
||||
{ name = "pickup_y", type = "DECIMAL(10,3) NOT NULL" },
|
||||
{ name = "pickup_z", type = "DECIMAL(10,3) NOT NULL" },
|
||||
{ name = "destination_label", type = "VARCHAR(80) NOT NULL" },
|
||||
{ name = "destination_x", type = "DECIMAL(10,3) NOT NULL" },
|
||||
{ name = "destination_y", type = "DECIMAL(10,3) NOT NULL" },
|
||||
{ name = "destination_z", type = "DECIMAL(10,3) NOT NULL" },
|
||||
{ name = "distance_meters", type = "INT UNSIGNED NOT NULL" },
|
||||
{ name = "duration_seconds", type = "INT UNSIGNED NOT NULL" },
|
||||
{ name = "price", type = "INT UNSIGNED NOT NULL" },
|
||||
{ name = "payout_amount", type = "INT UNSIGNED NOT NULL" },
|
||||
{
|
||||
name = "currency",
|
||||
type = "VARCHAR(8) NOT NULL",
|
||||
characterSet = "ascii",
|
||||
collation = "ascii_general_ci",
|
||||
},
|
||||
{ name = "driver_vehicle_model", type = "VARCHAR(64) NULL" },
|
||||
{ name = "driver_vehicle_color", type = "VARCHAR(64) NULL" },
|
||||
{ name = "driver_vehicle_plate", type = "VARCHAR(16) NULL" },
|
||||
{ name = "cancelled_by", type = "ENUM('passenger','driver','system') NULL" },
|
||||
{ name = "cancel_reason", type = "VARCHAR(32) NULL" },
|
||||
{ name = "passenger_rating", type = "TINYINT UNSIGNED NULL" },
|
||||
{ name = "rating_comment", type = "VARCHAR(300) NULL" },
|
||||
{ name = "tip_amount", type = "INT UNSIGNED NOT NULL DEFAULT 0" },
|
||||
{
|
||||
name = "refund_status",
|
||||
type = "ENUM('none','pending','processing','completed') NOT NULL DEFAULT 'none'",
|
||||
},
|
||||
{
|
||||
name = "tip_status",
|
||||
type = "ENUM('none','processing','completed','failed') NOT NULL DEFAULT 'none'",
|
||||
},
|
||||
{ name = "created_at", type = "DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP" },
|
||||
{
|
||||
name = "updated_at",
|
||||
type = "DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP",
|
||||
},
|
||||
{ name = "accepted_at", type = "DATETIME NULL" },
|
||||
{ name = "arrived_at", type = "DATETIME NULL" },
|
||||
{ name = "started_at", type = "DATETIME NULL" },
|
||||
{ name = "completed_at", type = "DATETIME NULL" },
|
||||
{ name = "cancelled_at", type = "DATETIME NULL" },
|
||||
{ name = "refunded_at", type = "DATETIME NULL" },
|
||||
{ name = "paid_out_at", type = "DATETIME NULL" },
|
||||
},
|
||||
primaryKey = "id",
|
||||
indexes = {
|
||||
{
|
||||
name = "idx_sky_phone_skyride_passenger",
|
||||
columns = "(`passenger_profile_id`, `status`, `updated_at`)",
|
||||
},
|
||||
{
|
||||
name = "idx_sky_phone_skyride_driver",
|
||||
columns = "(`driver_profile_id`, `status`, `updated_at`)",
|
||||
},
|
||||
{ name = "idx_sky_phone_skyride_requests", columns = "(`status`, `created_at`)" },
|
||||
{
|
||||
name = "idx_sky_phone_skyride_refunds",
|
||||
columns = "(`refund_status`, `status`, `updated_at`)",
|
||||
},
|
||||
},
|
||||
foreignKeys = {
|
||||
{
|
||||
column = "passenger_profile_id",
|
||||
references = "`sky_phone_skyride_profiles` (`id`) ON DELETE CASCADE",
|
||||
},
|
||||
{
|
||||
column = "driver_profile_id",
|
||||
references = "`sky_phone_skyride_profiles` (`id`) ON DELETE SET NULL",
|
||||
},
|
||||
},
|
||||
tableOptions = "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
|
||||
},
|
||||
}
|
||||
|
||||
Bridge.Database.Migrate("sky_phone", schema)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -614,3 +614,60 @@ CREATE TABLE IF NOT EXISTS `sky_phone_picstagram_moderation_audit` (
|
||||
KEY `idx_sky_phone_picstagram_audit_target` (`target_type`,`target_id`,`created_at`),
|
||||
FOREIGN KEY (`report_id`) REFERENCES `sky_phone_picstagram_reports` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sky_phone_skyride_profiles` (
|
||||
`id` CHAR(36) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
|
||||
`owner_identifier` VARCHAR(80) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uniq_sky_phone_skyride_owner` (`owner_identifier`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sky_phone_skyride_rides` (
|
||||
`id` CHAR(36) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
|
||||
`passenger_profile_id` CHAR(36) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
|
||||
`driver_profile_id` CHAR(36) CHARACTER SET ascii COLLATE ascii_bin NULL,
|
||||
`passenger_name` VARCHAR(80) NOT NULL,
|
||||
`driver_name` VARCHAR(80) NULL,
|
||||
`status` ENUM('payment_pending','searching','accepted','arrived','in_progress','completing','completed','cancelled') NOT NULL,
|
||||
`service_class` ENUM('taxi','comfort','xl','premium') NOT NULL,
|
||||
`pickup_label` VARCHAR(80) NOT NULL,
|
||||
`pickup_x` DECIMAL(10,3) NOT NULL,
|
||||
`pickup_y` DECIMAL(10,3) NOT NULL,
|
||||
`pickup_z` DECIMAL(10,3) NOT NULL,
|
||||
`destination_label` VARCHAR(80) NOT NULL,
|
||||
`destination_x` DECIMAL(10,3) NOT NULL,
|
||||
`destination_y` DECIMAL(10,3) NOT NULL,
|
||||
`destination_z` DECIMAL(10,3) NOT NULL,
|
||||
`distance_meters` INT UNSIGNED NOT NULL,
|
||||
`duration_seconds` INT UNSIGNED NOT NULL,
|
||||
`price` INT UNSIGNED NOT NULL,
|
||||
`payout_amount` INT UNSIGNED NOT NULL,
|
||||
`currency` VARCHAR(8) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL,
|
||||
`driver_vehicle_model` VARCHAR(64) NULL,
|
||||
`driver_vehicle_color` VARCHAR(64) NULL,
|
||||
`driver_vehicle_plate` VARCHAR(16) NULL,
|
||||
`cancelled_by` ENUM('passenger','driver','system') NULL,
|
||||
`cancel_reason` VARCHAR(32) NULL,
|
||||
`passenger_rating` TINYINT UNSIGNED NULL,
|
||||
`rating_comment` VARCHAR(300) NULL,
|
||||
`tip_amount` INT UNSIGNED NOT NULL DEFAULT 0,
|
||||
`refund_status` ENUM('none','pending','processing','completed') NOT NULL DEFAULT 'none',
|
||||
`tip_status` ENUM('none','processing','completed','failed') NOT NULL DEFAULT 'none',
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`accepted_at` DATETIME NULL,
|
||||
`arrived_at` DATETIME NULL,
|
||||
`started_at` DATETIME NULL,
|
||||
`completed_at` DATETIME NULL,
|
||||
`cancelled_at` DATETIME NULL,
|
||||
`refunded_at` DATETIME NULL,
|
||||
`paid_out_at` DATETIME NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_sky_phone_skyride_passenger` (`passenger_profile_id`,`status`,`updated_at`),
|
||||
KEY `idx_sky_phone_skyride_driver` (`driver_profile_id`,`status`,`updated_at`),
|
||||
KEY `idx_sky_phone_skyride_requests` (`status`,`created_at`),
|
||||
KEY `idx_sky_phone_skyride_refunds` (`refund_status`,`status`,`updated_at`),
|
||||
FOREIGN KEY (`passenger_profile_id`) REFERENCES `sky_phone_skyride_profiles` (`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`driver_profile_id`) REFERENCES `sky_phone_skyride_profiles` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
Reference in New Issue
Block a user