В процессе участия в разработке различных бизнесов приложений большинство из них столкнется с необходимостью гибкого управления фоновым управлением теми или иными функциями/интерфейсами/данными.Клиент меняется в соответствии с изменениями конфигурации, и эти потребности могут быть решены без выдача версий.Общее функциональное требование состоит в том, чтобы предоставить фоновую функцию, которая может настраивать и управлять продуктом/работой детской обуви, а затем выводить его клиенту для логики/рендеринга через интерфейс сервера.Здесь мы разделяем относительно общий решение для этого сценария.
история проекта
Текущий проект для нужд этой конфигурации, каждый раз требующий от разработчиков переделывать фоновую форму, а затем изменять интерфейс конфигурации для выходной конфигурации, потому что функции разработки должны быть дома давным-давно, я не знал, зачем быть так и делай, проблемы сейчас не простые в обслуживании и расширении, а так же дублирование затрат на разработку
Организуйте свои потребности
- История управления конфигурацией
- Поддержка контроля версий
- Поддерживаемые типы клиентов (Android/IOS/все)
- Формы настраиваются
- Настройте выходной интерфейс
- Инкрементная поставка
- Гарантированная высокая доступность, высокая стабильность, высокая производительность
- клиент
- Интерфейс предоставляет данные конфигурации для кэширования
техническое образование
- Фон управления: php server + jquery + bootstrap
- Проект интерфейса: php сервер
технический процесс
-
Выбор передовой технологии:
- vuejs
- element ui
-
Основной вопрос, как настроить сгенерированную форму в фоновом режиме (настраивается разработчиком)?
Первоначальный план состоит в том, чтобы сгенерировать форму пользовательского интерфейса элемента, настроив JSON формы.После некоторых исследований я также нашел библиотеку js, которая может сгенерировать форму пользовательского интерфейса элемента, настроив JSON.Это также большая проблема, поэтому устарело. Я попытаюсь реализовать это позже. Функция этой формы конфигурации реализована относительно простым способом через компонент vuejs + element ui, который может поддерживать основные потребности. Подробности см. В коде (простой и грубый)
- Инкрементная доставка данных интерфейса, а также время привлечения клиентов и стратегия кэширования
При каждом запуске клиент получает конфигурацию, кэширует [данные конфигурации], добавляет в кэш новые конфигурации и заменяет существующие.
Когда интерфейс выводит [данные конфигурации], заголовок ответа [отметка времени] = с отметкой времени сервера текущего запроса
Клиент получает данные и кэширует [данные конфигурации] и [метку времени]
В заголовке следующего запроса клиента будет [timestamp] = кешированная метка времени, первый запрос можно не указывать
Когда сервер получает запрос, он получает [отметку времени] клиента и при фильтрации конфигурации проверяет, что время последнего обновления >= [отметка времени] для вывода [данных конфигурации]
- Гарантия высокой доступности, высокой стабильности, высокой производительности, отказоустойчивости
Настроить данные для многоуровневого кэширования, кэш первого уровня [redis], кэш второго уровня [память сервера] (php apcu)
Интерфейс преимущественно получен из [памяти сервера].Если он не существует из [redis] и синхронизируется с [памятью сервера], он не существует из [mysql] и синхронизируется с [redis].После обычного фонового редактирования он будет быть синхронизированы с Redis, [память сервера] ] временно кэшируется (3 с), чтобы обеспечить его быструю доставку в случае высокого параллелизма. Недостаток заключается в том, что при изменении данных они будут обновляться с задержкой N/s.
Когда клиент получает конфигурацию кэша, если нет конфигурации по умолчанию, клиент не может получить механизм отказоустойчивости конфигурации в крайних случаях, чтобы обеспечить нормальную работу функции.
решение
Интерфейс списка управления конфигурацией:
Конфигурация добавляет и формирует интерфейс конфигурации JSON (действие разработчика):
Настройте интерфейс формы данных (детская обувь товар/операция):
Фронтенд-фреймворки/библиотеки:
- vuejs
- element uiГолодный интерфейс
- jsoneditorкомпонент редактирования json
- VueQuillEditorкомпонент форматированного текста vuejs
Основное содержание кода выглядит следующим образом:
Дизайн стола:
-- 配置中心表
CREATE TABLE `config_center` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`title` varchar(100) NOT NULL DEFAULT '' COMMENT '标题',
`code` varchar(60) NOT NULL DEFAULT '' COMMENT '标识',
`platform` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0=所有,1=IOS,2=安卓',
`template` tinyint(4) NOT NULL DEFAULT '1' COMMENT '模板标识',
`form_json` text NOT NULL COMMENT '表单JSON',
`form_data` text NOT NULL COMMENT '表单数据',
`description` varchar(255) NOT NULL DEFAULT '' COMMENT '描述',
`app_version` varchar(15) NOT NULL DEFAULT '' COMMENT 'app版本',
`app_version_compare` varchar(10) NOT NULL DEFAULT '' COMMENT 'app版本比较符号',
`operator` varchar(20) NOT NULL DEFAULT '' COMMENT '编辑人',
`create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
`status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '状态,1=有效,-1=删除',
PRIMARY KEY (`id`),
KEY `index_code` (`code`),
KEY `index_update_at_platform` (`update_at`,`platform`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Конфигурация формы Содержимое JOSN:
[
{
el: "input",
type: "textarea",
name: "名字",
field: "name",
value: "6666",
rule: [
{
required: true,
message: "请输入活动名称",
trigger: "blur"
}
]
},
{
el: "input-number",
type: "",
name: "数字",
field: "number",
value: 1,
min:1,
max:1000,
rule: [
{
required: true,
message: "数字",
trigger: "blur"
}
]
},
{
el: "input",
type: "text",
name: "描述",
field: "desc",
value: "",
rule: [
{
required: true,
message: "请输入活动名称",
trigger: "blur"
}
]
},
{
el: "editor",
type: "",
name: "富文本",
field: "editor",
value: "",
rule: [
{
required: true,
message: "请输入内容",
trigger: "blur"
}
]
},
{
el: "date",
type: "datetimerange",
name: "日期范围",
field: "datetime",
value: ["2019-01-01 10:00:00", "2019-03-01 08:00:00"],
rule: [
{
required: true,
message: "必须",
trigger: "blur"
}
]
},
{
el: "switch",
type: "",
name: "开关",
field: "open",
value: false,
rule: [
{
required: true,
message: "必须",
trigger: "blur"
}
]
},
{
el: "date",
type: "datetime",
name: "活动时间",
field: "datet",
value: "2019-01-01"
},
{
el: "slider",
type: "",
name: "范围",
field: "fw",
value: 0,
max: 500
},
{
el: "color",
type: "",
name: "颜色",
field: "color",
value: ""
},
{
el: "radio",
type: "",
name: "类型",
field: "type",
value: 0,
options: [
{
label: "类型1",
value: 1
},
{
label: "类型2",
value: 2
},
{
label: "类型3",
value: 3
}
]
},
{
el: "select",
type: "",
name: "食品",
field: "foods",
value: "黄金糕",
options: [
{
value: 1,
label: "黄金糕"
},
{
value: 2,
label: "双皮奶"
},
{
value: 3,
label: "蚵仔煎"
},
{
value: 4,
label: "龙须面"
},
{
value: 5,
label: "北京烤鸭"
}
]
},
{
el: "checkbox",
type: "",
name: "城市",
field: "city",
value: [0],
options: [
{
value: 1,
label: "上海"
},
{
value: 2,
label: "深圳"
},
{
value: 3,
label: "北京"
}
]
}
];
основной код шаблона формы vuejs + element ui (простой и грубый)
<el-form size="small" :rules="rules" ref="form" :model="form" label-width="80px">
<el-form-item v-for="(item,index) in formData" :key="item.key" :label="item.name" :prop="item.field">
<!--input 输入框-->
<el-input v-if="item.el==='input'" :type="item.type" style="width:400px" v-model="form[item.field]"></el-input>
<!--input 数字输入框-->
<el-input-number v-if="item.el==='input-number'" :min="item.min" :max="item.max" v-model="form[item.field]"></el-input-number>
<!--datetime 时间-->
<el-date-picker v-if="item.el==='date'" :type="item.type" v-model="form[item.field]" placeholder="选择日期时间">
</el-date-picker>
<!--switch 开关-->
<el-switch v-if="item.el==='switch'" v-model="form[item.field]" active-text="" inactive-text="">
</el-switch>
<!--滑块-->
<el-slider v-if="item.el==='slider'" v-model="form[item.field]" :max="item.max?item.max:100"></el-slider>
<!--颜色选择-->
<el-color-picker v-if="item.el==='color'" v-model="form[item.field]"></el-color-picker>
<!--单选-->
<el-radio v-if="item.el==='radio'" v-for="(option,index) in item.options" :key="option.key" v-model="form[item.field]" :label="option.value">
{{ option.label }}
</el-radio>
<!--多选-->
<el-checkbox-group v-if="item.el==='checkbox'" v-model="form[item.field]">
<el-checkbox v-for="(option,index) in item.options" :key="option.value" :label="option.value">
{{ option.label }}
</el-checkbox>
</el-checkbox-group>
<!--选择器-->
<el-select v-if="item.el==='select'" v-model="form[item.field]" placeholder="请选择">
<el-option v-for="option in item.options" :key="option.value" :label="option.label" :value="option.value">
</el-option>
</el-select>
<!-- 富文本-->
<quill-editor v-if="item.el==='editor'" v-model="form[item.field]"></quill-editor>
</el-form-item>
</el-form>
js-код:
//富文本组件
Vue.use(VueQuillEditor);
$vm = new Vue({
el: "#app",
data: {
template: "1",
form: {},
rules: {},
formData: {},
},
methods: {
useTemplate: function () {
switch (this.template) {
case "1": {
var formJson = [];
if (this.config['form_json']) {
formJson = this.config['form_json'];
} else if (templateOneJson) {
formJson = templateOneJson;
}
editorJson(formJson);
this.createForm(formJson);
return
}
}
},
//预览
review: function () {
var jsonData = editor.get();
this.createForm(jsonData);
},
//根据配置的JSON,解析出构造表单需要的Vue数据
getData: function (json) {
var data = {
//表单数据
form: {},
//表单验证规则
rules: {},
//表单控件配置
formData: {}
};
//构造数据
for (var index in json) {
var item = json[index];
data.form[item.field] = item.value;
if (item.rule) data.rules[item.field] = item.rule;
}
data.formData = json;
return data;
},
//创建表单Vue对象
formVue: function (data) {
Vue.set($vm, "form", data.form);
Vue.set($vm, "rules", data.rules);
Vue.set($vm, "formData", data.formData);
// $vm.$forceUpdate();
},
//根据配置JSON生成Form表单
createForm: function (json) {
var data = this.getData(json);
console.log(data);
this.formVue(data);
}
}
});
Поскольку интерфейсная часть основана на технической базе исходного проекта, в ней используется самый примитивный метод введения ссылок, и в нем не участвуют фронтенд-студенты. фронт и бэк, а потом упаковать на основе компонентов, было бы лучше.Хорошо сохранить детскую обувь заднего конца и подумать об этом.Это немного низко, и его можно использовать, но это не влияет на основные идеи реализации и может быть использовано для справки.
Суммировать
Когда вы разрабатываете требования к продукту, помимо решения насущных проблем, задумывались ли вы о многих подобных проблемах до или в будущем? Расширение вашего решения от решения одной проблемы до решения класса проблем - очень важная способность и часто разделительная линия между новичками и старшими техническими специалистами.
Впервые опубликовано на Github🌈 Большой разговор о веб-разработке, добро пожаловать Звезда 🥰