diff --git a/app/Domains/Real/Commands/Sync/MongoSync.php b/app/Domains/Real/Commands/Sync/MongoSync.php index 6c4b69f9..ab149825 100644 --- a/app/Domains/Real/Commands/Sync/MongoSync.php +++ b/app/Domains/Real/Commands/Sync/MongoSync.php @@ -35,7 +35,8 @@ class MongoSync extends Command $blocs = app(BlocRepository::class)->get()->pluck('id', 'sn')->toArray(); $query = DB::connection('mongo')->table('tblCard') - ->select(['cNo', 'bNo', 'iccid', 'imsi', 'comId', 'oType', 'saDate', 'sDate']) + ->select(['cNo', 'bNo', 'iccid', 'imsi', 'comId', 'oType', 'saDate', 'sDate']) + ->where('pNo', 'No00000000768') ->where('oRDate', '>', $utcDateTime) ->where('sDate', 'exists', true) ->orderBy('sDate'); diff --git a/app/Domains/Real/Commands/Sync/PackageSync.php b/app/Domains/Real/Commands/Sync/PackageSync.php index 0800db3f..a8d5d175 100644 --- a/app/Domains/Real/Commands/Sync/PackageSync.php +++ b/app/Domains/Real/Commands/Sync/PackageSync.php @@ -216,8 +216,8 @@ class PackageSync extends Command $package['id'] = ($package['type'] + 1) * 1000000 + $package['id']; $package['parent_id'] = $package['parent_id'] ?? 0; $package['carrier_operator'] = self::$carrier_operator[$package['carrier_operator']] ?? 255; - $package['cost_price'] = intval($package['cost_price'] * 100); - $package['guide_price'] = intval($package['guide_price'] * 100); + $package['cost_price'] = intval(floatval($package['cost_price']) * 100); + $package['guide_price'] = intval(floatval($package['guide_price']) * 100); $package['flows'] = intval($package['flows']); $package['voices'] = intval($package['voices']); $package['messages'] = intval($package['messages']); diff --git a/app/Domains/Virtual/Commands/Sync/LogSync.php b/app/Domains/Virtual/Commands/Sync/LogSync.php index 41745b6e..0bee9f2f 100644 --- a/app/Domains/Virtual/Commands/Sync/LogSync.php +++ b/app/Domains/Virtual/Commands/Sync/LogSync.php @@ -60,6 +60,7 @@ class LogSync extends Command if ($page === 1) { Artisan::call('virtual:sync-company'); Artisan::call('virtual:sync-package'); + Artisan::call('virtual:sync-product'); } echo 'sync_log_cursor page #: ' . $page . ' nextId #: ' . $nextId . PHP_EOL; @@ -109,11 +110,14 @@ class LogSync extends Command } $relationData = [ + 'type' => $type, 'sim' => $value['sim'], 'order_id' => $order->id, 'company_id' => $order->company_id, 'package_id' => $order->package_id, 'counts' => 1, + 'service_start_at' => date('Y-m-d H:i:s', intval($value['valid_start_time'])), + 'service_end_at' => date('Y-m-d H:i:s', intval($value['valid_end_time'])), 'created_at' => date('Y-m-d H:i:s', $value['create_time']), 'updated_at' => date('Y-m-d H:i:s'), ]; diff --git a/app/Domains/Virtual/Commands/Sync/PackageSync.php b/app/Domains/Virtual/Commands/Sync/PackageSync.php index e8b77dee..a0978485 100644 --- a/app/Domains/Virtual/Commands/Sync/PackageSync.php +++ b/app/Domains/Virtual/Commands/Sync/PackageSync.php @@ -47,8 +47,8 @@ class PackageSync extends Command 'name' => $item->name, 'type' => 0, 'carrier_operator' => self::$carrier_operator[$item->carrieroperator], - 'cost_price' => intval($item->price * 100), - 'guide_price' => intval($item->package_rp * 100), + 'cost_price' => intval(floatval($item->price) * 100), + 'guide_price' => intval(floatval($item->package_rp) * 100), 'flows' => ($item->tag == 10) ? intval($item->package_value) : 0, 'voices' => ($item->tag == 11) ? intval($item->package_value) : 0, 'messages' => 0, diff --git a/app/Models/Virtual/OrderCardPartition.php b/app/Models/Virtual/OrderCardPartition.php new file mode 100644 index 00000000..e5f74145 --- /dev/null +++ b/app/Models/Virtual/OrderCardPartition.php @@ -0,0 +1,30 @@ +belongsToMany(Package::class, 'virtual_order_renewal_cards', 'sim', 'package_id', 'sim', 'id')->withPivot('created_at', 'counts'); + } + + public function renewalPackages() + { + return $this->belongsToMany(Package::class, 'virtual_order_renewal_package_cards', 'sim', 'package_id', 'sim', 'id')->withPivot('created_at', 'counts'); + } + + public function flowPackages() + { + return $this->belongsToMany(Package::class, 'virtual_order_flows_package_cards', 'sim', 'package_id', 'sim', 'id')->withPivot('created_at', 'counts'); + } +} diff --git a/database/migrations/2018_12_24_164728_create_virtual_company_accounts_table.php b/database/migrations/2018_12_24_164728_create_virtual_company_accounts_table.php index 66b842c9..f819998a 100644 --- a/database/migrations/2018_12_24_164728_create_virtual_company_accounts_table.php +++ b/database/migrations/2018_12_24_164728_create_virtual_company_accounts_table.php @@ -21,7 +21,7 @@ class CreateVirtualCompanyAccountsTable extends Migration $table->increments('id')->comment('自增ID'); $table->integer('company_id')->unsigned()->default(0)->comment('企业ID'); $table->string('nickname', 32)->default('')->comment('昵称'); - $table->string('mobile', 20)->default('')->comment('手机号'); + $table->string('mobile', 20)->nullable()->comment('手机号'); $table->string('username', 32)->default('')->comment('登录名'); $table->string('password', 32)->default('')->comment('密码'); $table->string('salt', 6)->default('')->comment('盐'); diff --git a/database/migrations/2018_12_24_170946_create_virtual_order_cards_tables.php b/database/migrations/2018_12_24_170946_create_virtual_order_cards_tables.php index f86597c4..455f89c9 100644 --- a/database/migrations/2018_12_24_170946_create_virtual_order_cards_tables.php +++ b/database/migrations/2018_12_24_170946_create_virtual_order_cards_tables.php @@ -1,18 +1,13 @@ 'VD卡关联基础套餐订单', - 'virtual_order_renewal_cards' => 'VD卡关联基础续费订单', - 'virtual_order_renewal_package_cards' => 'VD卡关联续费包订单', - 'virtual_order_flows_package_cards' => 'VD卡关联加油包订单', - ]; - /** * Run the migrations. * @@ -20,27 +15,12 @@ class CreateVirtualOrderCardsTables extends Migration */ public function up() { - foreach ($this->tables as $table_name => $table_comment) { - if (Schema::hasTable($table_name)) { - continue; - } - - Schema::create($table_name, function (Blueprint $table) use ($table_comment) { - $table->increments('id')->comment('关联表ID'); - $table->bigInteger('sim')->unsigned()->default(0)->comment('SIM卡号'); - $table->integer('order_id')->unsigned()->default(0)->comment('订单ID'); - $table->integer('company_id')->unsigned()->default(0)->comment('企业ID'); - $table->integer('package_id')->unsigned()->default(0)->comment('套餐ID'); - $table->integer('counts')->unsigned()->default(1)->comment('数量'); - $table->timestamp('service_start_at')->nullable()->comment('服务开始时间'); - $table->timestamp('service_end_at')->nullable()->comment('服务结束时间'); - $table->timestamps(); - $table->softDeletes(); - - $table->unique(['order_id', 'sim', 'deleted_at']); - $table->comment($table_comment); - }); + if (Schema::hasTable('virtual_order_cards_partition')) { + return; } + + DB::unprepared(File::get(__DIR__ . '/create_virtual_order_cards_table.pgsql')); + DB::unprepared(File::get(__DIR__ . '/functions.pgsql')); } /** @@ -50,8 +30,6 @@ class CreateVirtualOrderCardsTables extends Migration */ public function down() { - foreach ($this->tables as $table_name => $table_comment) { - Schema::dropIfExists($table_name); - } + Schema::dropIfExists('virtual_order_cards_partition'); } } diff --git a/database/migrations/create_virtual_order_cards_table.pgsql b/database/migrations/create_virtual_order_cards_table.pgsql new file mode 100644 index 00000000..5c37325f --- /dev/null +++ b/database/migrations/create_virtual_order_cards_table.pgsql @@ -0,0 +1,76 @@ +CREATE SEQUENCE IF NOT EXISTS "virtual_order_cards_partition_id_seq" + INCREMENT 1 + MINVALUE 1 + MAXVALUE 2147483647 START 1 + CACHE 1; + +CREATE TABLE "virtual_order_cards_partition" ( + "id" int4 NOT NULL DEFAULT nextval('virtual_order_cards_partition_id_seq'::regclass), + "type" int2 NOT NULL DEFAULT 0, + "sim" int8 NOT NULL DEFAULT 0, + "order_id" int4 NOT NULL DEFAULT 0, + "company_id" int4 NOT NULL DEFAULT 0, + "package_id" int4 NOT NULL DEFAULT 0, + "counts" int4 NOT NULL DEFAULT 1, + "service_start_at" timestamp(0), + "service_end_at" timestamp(0), + "created_at" timestamp(0), + "updated_at" timestamp(0), + "deleted_at" timestamp(0)) +PARTITION BY + LIST ( + "type" +); + +ALTER SEQUENCE "virtual_order_cards_partition_id_seq" OWNED BY "virtual_order_cards_partition"."id"; + +COMMENT ON COLUMN "virtual_order_cards_partition"."id" IS '关联表ID'; + +COMMENT ON COLUMN "virtual_order_cards_partition"."sim" IS 'SIM卡号'; + +COMMENT ON COLUMN "virtual_order_cards_partition"."order_id" IS '订单ID'; + +COMMENT ON COLUMN "virtual_order_cards_partition"."company_id" IS '企业ID'; + +COMMENT ON COLUMN "virtual_order_cards_partition"."package_id" IS '套餐ID'; + +COMMENT ON COLUMN "virtual_order_cards_partition"."counts" IS '数量'; + +COMMENT ON COLUMN "virtual_order_cards_partition"."service_start_at" IS '服务开始时间'; + +COMMENT ON COLUMN "virtual_order_cards_partition"."service_end_at" IS '服务结束时间'; + +COMMENT ON TABLE "virtual_order_cards_partition" IS 'VD卡关联套餐订单'; + +CREATE TABLE virtual_order_cards PARTITION OF virtual_order_cards_partition FOR +VALUES + IN ( + 0 +); + +CREATE TABLE virtual_order_renewal_cards PARTITION OF virtual_order_cards_partition FOR +VALUES + IN ( + 1 +); + +CREATE TABLE virtual_order_renewal_package_cards PARTITION OF virtual_order_cards_partition FOR +VALUES + IN ( + 2 +); + +CREATE TABLE virtual_order_flows_package_cards PARTITION OF virtual_order_cards_partition FOR +VALUES + IN ( + 3 +); + +CREATE UNIQUE INDEX "virtual_order_cards_order_id_sim_deleted_at_unique" ON "virtual_order_cards" (order_id, sim, COALESCE(deleted_at, '1970-01-01 08:00:00'::timestamp)); + +CREATE UNIQUE INDEX "virtual_order_renewal_cards_order_id_sim_deleted_at_unique" ON "virtual_order_cards" (order_id, sim, COALESCE(deleted_at, '1970-01-01 08:00:00'::timestamp)); + +CREATE UNIQUE INDEX "virtual_order_renewal_package_cards_order_id_sim_deleted_at_unique" ON "virtual_order_cards" (order_id, sim, COALESCE(deleted_at, '1970-01-01 08:00:00'::timestamp)); + +CREATE UNIQUE INDEX "virtual_order_flows_package_cards_order_id_sim_deleted_at_unique" ON "virtual_order_cards" (order_id, sim, COALESCE(deleted_at, '1970-01-01 08:00:00'::timestamp)); + diff --git a/database/migrations/create_virtual_order_cards_trigger.pgsql b/database/migrations/create_virtual_order_cards_trigger.pgsql new file mode 100644 index 00000000..58fd7c86 --- /dev/null +++ b/database/migrations/create_virtual_order_cards_trigger.pgsql @@ -0,0 +1,164 @@ +CREATE OR REPLACE FUNCTION FIX_TIMELINES (sim INT8, activated_at TIMESTAMP without TIME zone) + RETURNS BOOLEAN +AS $$ +DECLARE + query TEXT; + order_row RECORD; + temp_service_start_at TIMESTAMP; + temp_service_end_at TIMESTAMP; + next_timestamp TIMESTAMP; +BEGIN + RAISE NOTICE '% - %', sim, activated_at; + IF activated_at IS NULL THEN + UPDATE + vd.virtual_order_cards_partition + SET + service_start_at = NULL, + service_end_at = NULL + WHERE + virtual_order_cards_partition.sim = FIX_TIMELINES.sim; + ELSE + query := 'SELECT + virtual_order_cards_partition.*, + virtual_packages.service_months, + virtual_packages.effect_months, + virtual_packages.delay_months + FROM + vd.virtual_order_cards_partition + JOIN vd.virtual_packages ON virtual_order_cards_partition.package_id = virtual_packages."id" + WHERE + virtual_order_cards_partition.sim = $1 + ORDER BY + "type" ASC, + created_at ASC'; + FOR order_row IN EXECUTE query + USING sim LOOP + -- 服务时间 + CASE (order_row. "type") + WHEN 0 THEN + temp_service_start_at := TO_CHAR(activated_at, 'YYYY-MM-01 00:00:00'); + temp_service_end_at := temp_service_start_at + (order_row.service_months || ' month')::INTERVAL + (order_row.delay_months || ' month')::INTERVAL - '1 second'::INTERVAL; + WHEN 1, + 2 THEN + IF (next_timestamp > order_row.created_at) THEN + temp_service_start_at := TO_CHAR(next_timestamp, 'YYYY-MM-01 00:00:00'); + ELSE + temp_service_start_at := TO_CHAR(order_row.created_at, 'YYYY-MM-01 00:00:00'); + END IF; + temp_service_end_at := temp_service_start_at + order_row.counts * (order_row.service_months || ' month')::INTERVAL + (order_row.delay_months || ' month')::INTERVAL - '1 second'::INTERVAL; + ELSE + -- 先购买了加油包后再激活的 + IF (order_row.created_at < activated_at) THEN + IF (order_row.created_at < TO_CHAR(activated_at - '1 month'::INTERVAL, 'YYYY-MM-01 00:00:00')::TIMESTAMP) THEN + -- 购买时间小于一个月的,直接生效 + temp_service_start_at := TO_CHAR(activated_at, 'YYYY-MM-01 00:00:00'); + ELSE + -- 延时生效 + temp_service_start_at := TO_CHAR(activated_at + (order_row.effect_months || ' month')::INTERVAL, + 'YYYY-MM-01 00:00:00'); + END IF; + ELSE + -- 延时生效 + temp_service_start_at := TO_CHAR(order_row.created_at + (order_row.effect_months || ' month')::INTERVAL, + 'YYYY-MM-01 00:00:00'); + END IF; + temp_service_end_at := temp_service_start_at + (order_row.service_months || ' month')::INTERVAL + (order_row.delay_months || ' month')::INTERVAL - '1 second'::INTERVAL; + END CASE; + next_timestamp := temp_service_end_at + '1 second'::INTERVAL; + -- 更新数据库 + UPDATE + vd.virtual_order_cards_partition + SET + service_start_at = temp_service_start_at, + service_end_at = temp_service_end_at + WHERE + virtual_order_cards_partition. "id" = order_row. "id"; + END LOOP; + END IF; + RETURN TRUE; + END; +$$ +LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION CARD_TIMELINES () + RETURNS TRIGGER +AS $$ +BEGIN + IF (TG_OP = 'INSERT') THEN + -- 插入数据 + IF (NEW.virtual_activated_at IS NOT NULL) THEN + PERFORM + vd.FIX_TIMELINES (NEW.sim, + NEW.virtual_activated_at); + END IF; + ELSIF (TG_OP = 'UPDATE') THEN + -- 更新数据 + IF (OLD.virtual_activated_at IS NOT NULL) OR (NEW.virtual_activated_at IS NOT NULL) THEN + PERFORM + vd.FIX_TIMELINES (NEW.sim, + NEW.virtual_activated_at); + END IF; + ELSIF (TG_OP = 'DELETE') THEN + -- 删除数据 + PERFORM + vd.FIX_TIMELINES (NEW.sim, + NULL); + END IF; + RETURN NULL; +END; +$$ +LANGUAGE plpgsql; + +DROP TRIGGER IF EXISTS CARD_TIMELINES ON cards; + +CREATE TRIGGER CARD_TIMELINES AFTER INSERT +OR +UPDATE + OR DELETE ON cards FOR EACH ROW EXECUTE PROCEDURE CARD_TIMELINES (); + +CREATE OR REPLACE FUNCTION RENEW_TIMELINES () + RETURNS TRIGGER +AS $$ +DECLARE + order_row RECORD; +BEGIN + RAISE NOTICE '% - %', NEW.sim, NEW.virtual_activated_at; + IF (TG_OP = 'INSERT') THEN + -- 插入数据 + SELECT + NEW.sim, + virtual_activated_at + FROM + vd.cards INTO order_row + WHERE + cards.sim = NEW.sim; + PERFORM + vd.FIX_TIMELINES (order_row.sim, + order_row.virtual_activated_at); + ELSIF (TG_OP = 'DELETE') THEN + SELECT + NEW.sim, + virtual_activated_at + FROM + vd.cards INTO order_row + WHERE + cards.sim = NEW.sim; + PERFORM + vd.FIX_TIMELINES (order_row.sim, + order_row.virtual_activated_at); + END IF; + RETURN NULL; +END; +$$ +LANGUAGE plpgsql; + +DROP TRIGGER IF EXISTS RENEW_TIMELINES ON virtual_order_renewal_cards; + +CREATE TRIGGER RENEW_TIMELINES AFTER INSERT +OR DELETE ON virtual_order_renewal_cards FOR EACH ROW EXECUTE PROCEDURE RENEW_TIMELINES (); + +DROP TRIGGER IF EXISTS RENEW_TIMELINES ON virtual_order_renewal_package_cards; + +CREATE TRIGGER RENEW_TIMELINES AFTER INSERT +OR DELETE ON virtual_order_renewal_package_cards FOR EACH ROW EXECUTE PROCEDURE RENEW_TIMELINES (); + diff --git a/database/migrations/functions.pgsql b/database/migrations/functions.pgsql deleted file mode 100644 index d4c344d7..00000000 --- a/database/migrations/functions.pgsql +++ /dev/null @@ -1,90 +0,0 @@ -CREATE OR REPLACE FUNCTION card_timelines () - RETURNS TRIGGER -AS $$ -DECLARE - temp RECORD; - srow RECORD; -BEGIN - IF (TG_OP = 'INSERT') THEN - IF NEW.virtual_activated_at IS NOT NULL THEN - RAISE NOTICE 'row % inserted', NEW.sim; - SELECT - virtual_order_cards.order_id - virtual_order_cards.created_at, - virtual_packages.service_months, - virtual_packages.name AS package_name INTO srow - FROM - virtual_order_cards - JOIN virtual_packages ON virtual_order_cards.package_id = virtual_packages.id - WHERE - sim = NEW.sim; - IF FOUND THEN - INSERT INTO timelines (sim, package_type, package_name, starttime, endtime) - VALUES (NEW.sim, 0, srow.package_name, NEW.virtual_activated_at, NEW.virtual_activated_at + (srow.service_months || ' month')::interval); - END IF; - END IF; - ELSIF (TG_OP = 'UPDATE') THEN - IF OLD.virtual_activated_at IS NOT NULL OR NEW.virtual_activated_at IS NOT NULL THEN - IF NEW.virtual_activated_at IS NULL THEN - RAISE NOTICE 'NEW virtual_activated_at IS NULL'; - ELSE - RAISE NOTICE 'NEW virtual_activated_at IS NOT NULL'; - END IF; - END IF; - ELSIF (TG_OP = 'DELETE') THEN - END IF; - RETURN NULL; -END; -$$ -LANGUAGE plpgsql; - -CREATE SEQUENCE "order_cards_id_seq" -INCREMENT 1 -MINVALUE 1 -MAXVALUE 2147483647 -START 1 -CACHE 1; - - -CREATE TABLE "order_cards" ( - "id" int4 NOT NULL DEFAULT nextval('order_cards_id_seq'::regclass), - "type" int2 NOT NULL DEFAULT 0, - "sim" int8 NOT NULL DEFAULT '0'::bigint, - "order_id" int4 NOT NULL DEFAULT 0, - "company_id" int4 NOT NULL DEFAULT 0, - "package_id" int4 NOT NULL DEFAULT 0, - "counts" int4 NOT NULL DEFAULT 1, - "created_at" timestamp(0), - "updated_at" timestamp(0), - "deleted_at" timestamp(0), - "service_start_at" timestamp(0), - "service_end_at" timestamp(0), - CONSTRAINT "order_cards_pkey" PRIMARY KEY ("id", "type") -) PARTITION BY LIST (type); -; - -CREATE UNIQUE INDEX "virtual_order_cards_order_id_sim_deleted_at_unique" ON "virtual_order_cards" USING btree ( - "order_id" "pg_catalog"."int4_ops" ASC NULLS LAST, - "sim" "pg_catalog"."int8_ops" ASC NULLS LAST, - COALESCE(deleted_at, '1970-01-01 08:00:00'::timestamp without time zone) "pg_catalog"."timestamp_ops" ASC NULLS LAST -); - -COMMENT ON COLUMN "order_cards"."id" IS '关联表ID'; - -COMMENT ON COLUMN "order_cards"."sim" IS 'SIM卡号'; - -COMMENT ON COLUMN "order_cards"."order_id" IS '订单ID'; - -COMMENT ON COLUMN "order_cards"."company_id" IS '企业ID'; - -COMMENT ON COLUMN "order_cards"."package_id" IS '套餐ID'; - -COMMENT ON COLUMN "order_cards"."counts" IS '数量'; - -COMMENT ON TABLE "order_cards" IS 'VD卡关联基础套餐订单'; - -CREATE TABLE virtual_order_cards PARTITION OF order_cards FOR VALUES IN (0); -CREATE TABLE virtual_order_renewal_cards PARTITION OF order_cards FOR VALUES IN (1); -CREATE TABLE virtual_order_renewal_package_cards PARTITION OF order_cards FOR VALUES IN (2); -CREATE TABLE virtual_order_flows_package_cards PARTITION OF order_cards FOR VALUES IN (3); - diff --git a/frontend/src/components/base/ui-upload-img.vue b/frontend/src/components/base/ui-upload-img.vue index 81a5e8d7..b66edf12 100644 --- a/frontend/src/components/base/ui-upload-img.vue +++ b/frontend/src/components/base/ui-upload-img.vue @@ -4,7 +4,7 @@