問題の本質を簡単に説明すると、管理ページがたくさんある、と管理ジェネレーターは書いています。
仕組み:
| 内容:
|
どこから始まったの
実際、私は常にさまざまなサービスの管理ページを作成する必要がありました。 新しいプロジェクト、新しいサーバー、新しい管理パネル。 ゼロから書かれたものもあれば、コピーされたものもありました。 13番目の管理エリアのどこかで私は気分が悪くなりました。 私は違いを作りたかった。 したがって、統計部門の新しい管理パネルは、98 Windowsのスタイルで設計されました。 さらに、緊急に、「出芽」の方法によって、ライセンス部門の管理者パネルが受信され、その後、新しいゲームポータルの管理者パネルが受信されました。
この時点で、一部のコンポーネントがすべてのプロジェクトで同じであることが明らかになりました。 はい、そしてユースケースも繰り返されます:
- リストを表示する;
- アイテムの作成/編集/削除。
- 1対多または多対多の関係を割り当てます。
次に、テンプレートを使用してメインコードベースを作成するジェネレータを作成しました。 すべての「ウィッシュリスト」を手動で完了する必要があったことは明らかですが、これは大きな前進でした。 さらに3つの管理領域の後、レイアウトだけでなく、できればサーバーAPIとデータベーススキーマを生成する必要があることが明らかになりました。 これはすべてのプロジェクトで必要というわけではありませんでしたが、一瞬の「ひよこひよこと生産」ではそれだけでした。 なぜなら さまざまな管理ブランチがさまざまなバグの修正を受け取りました。夏の終わりまでに、すべての修正を1つのブランチにマージし、ジェネレータを定性的に更新することが非常に良いことが明らかになりました。 それが私が夜と週末に始めたことです。
コピーのスケーラビリティ/ジェネレーターの最初のバージョンの管理パネルの過去のレベル
既製の管理ページと管理ジェネレーターはありますか?
はい 、数千人です。 それらの何が問題なのか:
- 特定の言語またはフレームワークのシャープニング
たとえば、Laravel(PHPフレームワーク)を使用している場合、SleepingOwlを使用できます。 しかし、Javaでバックエンドを使用している場合、PHPがなければ、それをねじ込むことはできません。
- 堅牢性
モノリシックは、前の段落から続きます。 一方では、データベーススキームに応じて、管理パネルを動的に変更する非常にクールなシステムがあります。 一方、この接続を削除することはできません。 レイアウトだけが必要な場合は、痛いでしょう。 また、管理者パネルを認証システムに接続する場合にも問題があります(多くの大規模なオフィスには、1つのコントロールポイントからすべてのユーザーのすべてのシステムへのアクセスを制御する統合認証システムがあります)。
- サイトシャープニング
おそらくadminジェネレーターの半分は、CMSシステムのさまざまなバリエーションを収集します。 それらのいくつかは非常にクールですが、基本的にコンテンツ管理には適していません。 書籍のデータベースを駆動する場合、100冊の書籍をカテゴリに分類するだけで非常に苦痛になります。
- カスタマイズの難しさ
まあ、これは理解できます。 「ユニバーサル管理パネルを作成することはできません。各プロジェクトは個別です」(c)。
管理領域に非常に欠けているもの:
コンテンツ編集モードに切り替えることなく、多対多の関係を作成する機能。 例:100のゲームのリストがあり、それらにすばやくタグを付ける必要があります。 ほとんどの管理者では、「ゲーム編集」を開き、タグを付加して、「ゲームのリスト」に戻る必要があります。
添付、削除、編集をバッチ処理する機能。 例:15個のバナーを選択し、すぐに別のプロモーションチャネルを割り当てます。
ロギングの欠如。 例:コンテンツを見て、誰がいつ、いつ、そして何が具体的に変更されたかをすぐに見つけたい。
ワンクリックでオブジェクトとそのすべてのレコードの複製を作成する機能。 例:すべてのバナーとサイトを含む広告会社のコピーを作成します。
データをExcelにインポート/エクスポートする機能。 例:管理者はExcelでコンテンツと販売を一度確認するか、パートナーに何かのリストを送信する必要があります。
複雑な検索フィルター(プロパティグループ別および例外付き)。 例:「Classics」および「Novels」カテゴリからすべての書籍を選択します。ただし、IDが20、30、65の書籍、および「Bestseller」タグが付いた書籍は除きます。 SQLでは、これをすぐに行いますが、管理フィルターのマネージャーの場合、原則として、これらのトリックは実行できません。
これらの問題を解決することにしました。 実際、コード生成について質問すると、さらに多くのウィッシュリストが存在することは明らかです。 ここでは、データの分析によって引きずられる統計の結論と、データの相互の影響を処理する「ビジネスロジック」を追加するツールなどの両方が必要です。 このトピックは非常に広範囲に渡りますが、私のモチベーションの限界と開発の工数を考慮して、すべてのウィッシュリストは実装しないでください。 少なくとも最低限の基本的な機能は終了したいと思います。
正確に何ができますか?
先を見据えて、ログイン/パスワード: demodemo / qwerty123456と表示のみの権利を設定します (突然誰かが壊れて、デモが事前に役に立たなくなるでしょう)
価格表
簡単なものから始めましょう。 それから一人の男がラジオの卸売部品を売っています。 早急に検索してサイトの価格を撤回する必要があります。 彼には1Cウェアハウスはありません。 申し分なく: https : //goo.gl/OIPQXv
JIRAのパロディ
JavaScriptの伝統により、TODO開発者はシートを書くことになっています。 企業グループのTODOリストを書きましょう。 子会社、部門、部門があったこと。 また、部門内にはすでにタスクがあります。 タスクは従業員に分散しています。 各従業員には、現在のタスクと将来のタスクの順序の2つのシートがあります。 Akhalai-mahalai、完了: https ://goo.gl/6UWqRn(demodemo / qwerty123456)
はい、もちろんです。 ファイルを添付できるように、タスクに関するコメントも必要です。 これは最小限のセットです。 ただし、この管理者は以前のバージョンで生成されており、まだサポートされていません。 新しい-既に修正済み。
CRM
CRMが必要です。 企業、そのオフィス、およびオフィスの周りに散らばっている重要な人々がいるでしょう。 マネージャーと直接やり取りする各主要人物(顧客カードなど)の会社または関係書類の説明を見ることができます。 次に、キーパーソンに関連付けられた「イベント」を作成する機能が必要です(例:電話、手紙、会議)。 そして、個別のリストがあります:今すべきこと、クライアントに期待すること、私たちの関係の株のリスト。 ええと... 7つのオブジェクトだけが弱いです。 異なるタイプの顧客(プライベート、法人など)とプロファイル(キャリア、ツアーオペレーター、ホテルなど)による分離を個別のエンティティとして追加しましょう。 ひよこ、展開済み: https ://goo.gl/OcJU8g(demodemo / qwerty123456)
おそらく、いろんな種類のレポート、請求書、商品の倉庫が必要なのでしょうが、一方では会計と倉庫がどのように機能するか想像することもできません。 これらは、他のビジネスプロセスを持つ他の部門です。
はい、もちろん、自動電話交換、広告プラットフォーム、および電子メールとの統合も必要です。 しかし、これは30分間の「ひよこひよこデモ」ではありません。
JSON入力-NSIエディター出力
一般に、これの本質は命名参照情報(NSI)の編集者です。 プロジェクトがNSIエディターに近ければ近いほど、すぐに使えるようになります。 データの視覚化、分析、およびロジックは、私たち自身によってまだ記述されていません。
それでも、プロトタイプのERPシステムをスケッチできます。 実際、これを実現することは、さらなる行動を起こすきっかけとなりました。 さらに、異なるデモを検索して表示することにより、次のことが明らかになりました。
多くのスタートアップERPシステムは、「chick-chick demo」機能よりも大幅に優れていません。 しかし、コード生成のため、「chick-chick demo」はそれらを大きく上回ることができます。
多くのERPシステムは、多数の構成からのコード生成と展開の同じ原理に基づいて構築されています。 たとえば、「標準」というものがありました。これは、説明から判断すると、DOSでのみこのバイクのように1対1でした。 繰り返しますが、数千人です。
なぜこれが必要なのですか?
Javaで記述し、Angularに常に苦しめられているとします。 ここでは、管理パネルを生成し、正面に登ることはできません。 さて、または別のオプション-アーキテクチャごとに多くのテーブルを作成する必要があります(はい、はい、はい、Java交換はクラスからスキームをロールでき、その逆も可能です-クラスはDBスキームに従って生成できます)が、突然誰もができるわけではありません。 または、Javaで作成せず、ベースでのみ機能するアーキテクトにスキームをロールする必要があります。 または、一般的にはクリーンフロントであり、リレーショナルデータベースをマスターすることはできません。少なくとも、ここには何らかの種類のインデックスとインデックスがあります(データベーススキーマが「非正規化」によってブロックされていることは明らかですが、突然)。 さて、または「ロケット科学」レベルのスタートアップを削減したいという欲求であなたの手が燃えており、プロジェクトインフラストラクチャを作成するために家電製品に従事する欲求はありません。
3つのテーブルからのホームプロジェクトに適しています。 私たちには大きなプロジェクトがあり、まったく別の話です。
いいえ:) 管理パネルのコード生成と構成は、設定から完全にやや少ないため、1000個のオブジェクトのプロジェクトをデプロイできます。 別の質問-なぜですか? 通常、1つのプロジェクトには20を超えるエンティティがあります-痛み(データベースには既に40〜100のテーブルがあります)。 したがって、大規模なプロジェクトはマイクロサービスに分割され、マイクロサービスはすでに約100のテーブルになっています。
さらに、各エンティティだけでなくそのログに対しても、データベースに接続するための個別の設定を設定できます。 したがって、「すぐに使用できる」ログを個別のデータベースに書き込み、1つの管理パネルで異なるデータベースのエンティティを操作できます。
さらに、管理者がコンベア上で組み立てられ、個別のアクセス制御システム(ESIA、OIB、Sonat、 %yours_access_control_system%のファンの皆さん)が存在するという理由だけで、承認は最初は個別のモジュールによって行われました。
それがどのように機能し、どのくらいの重さがあるかについて少し。
最初に、すべてのエンティティとその関係をJSON形式で記述する必要があります。 これは最も難しい段階の1つです。
{ "objects": [ { "id": "distributionChannel", "name": { "logic": "DistributionChannel", "logicSmall": "distributionChannel", "layout": "distribution_channel" }, "properties": { "create": { "name": { "tag": "input", "type": "string", "min": 1, "max": 50 }, "description": { "tag": "textarea", "type": "string", "min": 1, "max": 500 } }, "update": { "name": { "tag": "input", "type": "string", "min": 1, "max": 50 }, "description": { "tag": "textarea", "type": "string", "min": 1, "max": 500 } }, "search": {} }, "visualization": { "main": { "name": { "type": "string", "min": 0, "max": 50 } }, "history": { "name": { "type": "string", "min": 0, "max": 50 } } } }, ...
次に、ノードを実行し、より詳細な構成を作成します
node config
{ "objects": [ { "id": "distributionChannel", "name": { "logic": "DistributionChannel", "logicSmall": "distributionChannel", "layout": "distribution_channel" }, "aside": [ { "id": "create", "title": " DistributionChannel", "buttons": [ { "tag":"popup_button", "icon": "menu", "value":"", "id":"distribution_channel_aside_create_button_popup_menu" }, { "tag":"popup_button", "icon": "search", "value":"", "id":"distribution_channel_aside_create_button_popup_search" } ], "content": [ { "tag":"input", "type":"string", "min":1, "max":50, "id":"distribution_channel_aside_create_name" }, { "tag":"textarea", "type":"string", "min":1, "max":500, "id":"distribution_channel_aside_create_description" }, { "tag":"button", "title":"", "id":"distribution_channel_aside_create_button_create" } ] }
フィールドを並べ替えたり、何かを追加またはカットできます。 次に、コードを生成します(ほとんどの部分には構成ファイルもあります)
node sql node nodejs node admin
(function () { "use strict"; function ToggleStyleContentSearchConfig() { return { common: [ { id: "content__search__processing", className: "hidden" }, { id: "content__search__not_found", className: "hidden" }, { id: "content__search__result", className: "hidden" } ], processing: [ { id: "content__search__processing", className: "loading__icon search_status__loading" } ], notFound: [ { id: "content__search__not_found", className: "search_status__message" } ], result: [ { id: "content__search__result", className: "search__container__result" } ] }; } module.exports = ToggleStyleContentSearchConfig; })();
ファイルの準備ができたら、生成されたSQLを実行します(データベースにスキーマを作成します)。 サーバーファイルを別のフォルダーにコピーします。 展開。 統計を収集するために残っています
gulp gulp easy
統計は1つのHTMLファイルに収集され、サーバーにアップロードする必要があります。 すべてうまくいった場合は、静的データを圧縮してみてください(gzipなしで-40%、gzipで-8%)
gulp hard
いくつかの数字:
- データベース (現在はPostgreSQL、MySQLを追加する予定です)
1エンティティ=(1オブジェクトテーブル+ログテーブル)+ n *(多対多通信テーブル+ログテーブル);
1エンティティ=オブジェクトの5つのプロシージャ(作成+編集+削除+検索+ 1つのオブジェクトの取得)+ 4つのログプロシージャ(作成+削除+検索+ 1つのログの取得)+ n *接続のプロシージャ(作成+削除+検索)+ n *リンクのログ(作成+削除+検索);
合計:(2 + n * 2)テーブルと(9 +(n * 3 * 3))プロシージャ。nは多対多の関係の数
- サーバー (現在NodeJS、PHPを追加する予定です)
わずか6ファイル すべてがconfigsで1つのクラスのインスタンスに正常に収まります。
- 顧客 (JSバニラ)
1エンティティ=〜10 HTMLファイル+〜50 JS + n *ファイル(通信用に〜25ファイル、多対多)
合計: 12エンティティのモデルには、約50のテーブル、160のプロシージャ、1000の静的ファイル(HTML + CSS + JS)が含まれます。 アセンブリおよび圧縮後の統計は、約1メガバイト(すべて1つのHTMLファイル)です。 Googleコンパイラの後に〜600kbまで圧縮できる「奇跡のプラグイン」もあり、gzipの後に〜85kbがクライアントに届き、gzipをbrotliに置き換えて、79kbまで押します。 ほとんどのプロジェクトファイル(85%から)は、JSON alaの同じタイプのラッパーです。 したがって、ファイル生成後にプロジェクトを非常に柔軟に構成し、アセンブリで非常に強力に圧縮し、 検索およびフォルダーによる置換を使用してコピー/過去の機能を追加できます 。
自転車の基礎を形成した原則:
レイアウトは、サーバーに接続されていない単一のHTMLファイルです。 それらを接続する唯一のものは、AJAXリクエストとレスポンスの形式です。 バックエンドが必要な場合は、お気軽に交換してください。
バックエンドはデータベースの構造を認識しませんが、保存されたファイルと引数の名前を認識します。 データベーススキーマが必要な場合-独自に作成します。
構成によって記述できるすべてのものは、構成によって記述されなければなりません。 通常、プロジェクトファイルの85%以上を構成します(エンティティが多いほど、割合は高くなります)。
目的のフォルダのコピー/過去を使用して新しい機能を追加できるように、すべてのファイルと構成を分解する必要があります。 何かをコード内で手動で修正する必要があることは明らかですが、これらのポイントが少ないほど良いです。
そうでもない。 この引数は、ビジネスロジックをストレージに保存する場合に適しています-はい。 しかし、ビジネスロジックはありません。 ストレージ全体のポイントは、ロジックを使用せずにレコードを提供、作成、または変更することです。 さて、ロギングはトリガーを介してではなく、対応する手順のサーバーからの要求に応じてのみ行われます。 質問が発生します:「データベースを変更したい場合はどうなりますか?」 格納されたファイルを書き換える必要がありますが、ORMを使用してそれを行っていない場合は、「いいえ。」個人的には、私も知り合いも、プロジェクトが外出先で変わるという事実に遭遇しました。 そして、そのような状況がある場合、「保存されたファイルを生成するための10個のテンプレートをSQL言語の別のサブセットに書き換える」ことが最も小さな問題になるでしょう。
プロジェクトの現在のステータス:
9月に、ほとんどすべてをゼロからやり直さなければなりませんでした。 しかし、検索は改善され、オブジェクトログ、デザインなどが登場しました。
11月、新しいベースを備えた機能と最初の2つのサービスが登場し始めました。 左利きの人のためのモード、位置の変更、接続ログ、バッチ処理など
12月に、サーバー、データベースを書き直し、正面を直立させる必要がありました。 12月末までに安定版を組み立てる時間があると思っていましたが、時間がありませんでした。 ここで、データベースとの通信は、手順、グループ検索、例外付き検索、コメントを追加する機能などによって厳密になりました。
実装者:
- エンティティの作成/編集/削除。
- フィルター、並べ替え、ページネーションを使用した検索。
- 2つのエンティティの単純な接続の作成/編集。
- 位置を設定/変更する機能。
- エンティティの作成/編集ロギング;
- 2つのエンティティ間の単純な接続の作成/編集の記録。
- ログの表示。
- カスタム選択の生成(値のリストは縫い付けられますが、ロードされません);
- エンティティの(多数から多数への)リンクの一括追加/削除。
- フィールドのシンボリックリンクは、その作成をスキップします(データバインディングの場合、例:1つのパートナーフィールド、小さなパネルのすべてのエンティティ)。 referenceElementId;
- エンティティの独立したリストの生成。
- 作業領域のサイズを変更する機能。
- IDオブジェクトのリストを検索します。
- 検索の行数の自動調整。
- 検索結果で検索クエリを強調表示する。
- 「左利き用」表示モード。
- ランダムな場所に検索(作成/編集)を貼り付けます。 例:タスクへのコメント。
軽微なバグ:
- 検索エラー:ref_channel_idをフィルターします。 そのような検索とフィルター+追加のためにLEFT JOINリクエストを生成する必要があります。 検索フォームのフィールド。
- ref_リンク(ロックの例、列のコスト)の検索でオブジェクトの名前の出力を修復します。
- サーバーエラーの詳細を表示します。
- ファイルのクリーニング+新しいプロジェクト構造。 並べ替えの最終アセンブリは、よりクリーンにする必要があります。
- オブジェクトのバッチ割り当ての動作を修正します。
- 画面の検索文字列の数の計算を修正。
- クエリにデータを入力します。
- 上書きする前にファイルをチェックすると、常にコンソールにエラーが書き込まれます(本質的には存在しません)。 迷惑ですが、重要ではありません。
実装されていない機能:
- 位置変更ロギング;
- エンティティにネストされた配列の表示/編集(例:支払い方法ではなく、名前または支払いのリストではなく、送金のリスト);
- エンティティの読み込み順序の決定。
- 関連フィールドの定義(1つの変更時のすべての自動切り替え。たとえば、パートナーまたはプロモーションチャネルの変更);
- その場でファイルをダウンロードします。
- 「リストによる」ファイルのダウンロード。
- 検索結果をCSVにアップロード(エクスポート);
- CSVから結果をダウンロード(インポート);
- コピーは逆/逆ではありません。
- ログによる状態回復を追加します(オブジェクトの状態の詳細を開いたとき)。
- エンティティの一括削除。
- 別のプロジェクトでのポストコンプレッサーの説明と削除。
- 個別のアプリケーションとしての設定用の便利なジェネレータ。
- オブジェクトの履歴のロギングを修正しました。 フィールドis_remove do change_type(0-作成、1-編集、2-削除)
- ローカリゼーション
- 携帯電話/タブレットへの適応。
- 顧客のショーケースを作成します。
- 検索フィルターは、単一の値ではなく配列として(複数の「含む」および「排他的な」サンプル);
- 各タイプの操作の表示画面(メイン/脇)を選択する機能。
- parent_idフィールドを介したサブフォルダー。 フィールドがあります-フォルダーがあり、検索フィルターに変更があります。
- キーボード制御;
- ようこそ画面をやり直します。 プロジェクトエンティティの接続のグラフを表示します(バナー管理パネルのように)。
- SEOテキストを書く;
- ページネーションプラグインをスクロールで接続します。
- サードパーティのプロジェクトの承認システムについて考え直してください。 承認モジュールをやり直します(ドラフトユーザーを削除します)。
サーバーに実装されていない機能:
- データベース内のテーブルに関するコメント。
- 「REST API」を作成するときではなく、「service」オブジェクトのフィールドをチェックします。
- APIメソッドのドキュメントの生成。
- Sonataに接続されていない認証モジュール。
- パートナーのアクセスに関連する、またはユーザーに制限があるDBスキーム。
- PHPサーバーの生成。
大きなプラスは、これが「理論的な開発」ではないということです。 各コンポーネントはすでに古いプロジェクトにあるか、現在のプロジェクトにあります。 したがって、「ウィッシュリスト」のリストとそれらの実装の順序は、搾取の苦痛によって決定されます(まあ、外国の管理ジェネレーターを開発した経験によって) 。
次の月の計画は何ですか:
最後に手順で安定したバージョンを構築します
PHPにロールオーバーする 通常のsharashkaのノード上のサーバーは展開されません。 また、サービスはよりシンプルで安価です。 (大まかに言えば、年間1500ルーブルで、すでに2万件までのレコードの管理パネルを展開できます)
ファイル処理を追加する
すぐにインストールできるスクリプトを作成すると、プロジェクトをデプロイするために1時間半掘り出さなければなりません
(プロジェクト内のすべてのファイルを知っているという事実にもかかわらず)。
UXについて少し
コア機能の作成は非常に退屈です。 退屈したら、バグと機能に切り替えます。 ここにそれらの1つがあります。 右側と左側のインターフェースがあります。 ローカライズを行う人-2つのオプションを収集します(hello badoo)。 +2つのオプションがあります。左利き用と右利き用です。 違いは、インターフェースが完全にミラーリングされておらず、コントロールパネルによってのみミラーリングされていることです。 ロシアの左利きの方は、ミラー化されたコントロールパネルを使用する方が便利ですが、表の情報を左から右に読んでください。 左利きのアラブ人-それどころか、パネルのヨーロッパレイアウトですが、表の列の順序は逆です。
右利きのヨーロッパ人
左利きのアラブ人
左利きのヨーロッパ人
正しいアラブ
異なるプロジェクトでは、ゾーンの「検索結果」と「要素の編集」の異なる比率が必要です。 たとえば、本を編集するための本アプリケーションでは、右側にかなり狭いパネルがあります。 また、ゲームアプリケーションでは、ゲームを中央部分で変更することをお勧めします。 また、プロジェクトで作業する特定のマネージャーの好みにも影響します。 したがって、新しいバージョンでは、「検索」ゾーンと「編集」ゾーンの比率を設定で変更できます。
統計を扱う人は、通常、Excelまたは同様のプログラムで多くの時間を費やします。 約16pxの高さの文字列に使用されます。 ブートストラップでさまざまなCMSサイトおよびWebマズルを使用する人は、32pxの行の高さに慣れています。 したがって、線の高さも設定で作成されます。
スクロールは悪であるという意見があります。 それが起こった理由は、別の記事のトピックです。 私はそれに同意します。 しかし、画面に収まる正確な行数を指定することは不可能です。 すべてのモニターが異なります。 したがって、起動時の管理パネルは、このモニターの現在の設定に最適な行数を計算します。 それらは常に、垂直スクロールを作成せずに、画面にできる限り正確に一致します。
結論として
同僚はどう思いますか?
誰もが本、部品、またはその他の規制および参照情報の目録をウェブの顔で必要としますか?
- それはすでにジャンゴにあった
- githubへのリンクはどこにありますか?
- 実際のプロジェクトでは離陸しません!
- ふw、PHPに書き換え、マイナスを入力してください!!! 11
- チャートはどこにありますか? メインの統計-これがベースです!
- chop configs!=コード生成
- すべてがバグであり、製品は生です
- インターフェースは理解できません!
- なぜ反応しないのですか?
- すでに...
- インストールファイルをダウンロードする場所
- データ分析なしでは必要ありません!
- なぜMongoDBでないのですか?
- LIKEは遅い!
- とドキュメントはどうなりますか?
- テストカバレッジがゼロになるのはなぜですか?
- レイアウトはフレックスボックスではありません、自殺してください!
- 携帯電話用のバージョンはありますか?
- 何でも記事!
- 私のレイアウトが行きました!