我如何撰写我的过境点

当您进入Postcrossing时 ,您会意识到有多少人会为一个简单的想法而发疯。 正是这种想法引人入胜的简单性成为了为什么我与女士们以及某些交换性和附加功能的优先对象开始进行一次特定交叉的主要原因。


主意


那是2017年1月。 一次,在与我的对话中,有人提到他想实现根据过境原则交换小玩意 (所谓的“友谊手镯”)的想法:用户访问该站点,按下按钮并收到他必须将小玩意发送到的地址,之后他本人就开始从其他用户那里收到小玩意,以作为回应(依此类推)。 希望在不同国家之间进行交流。

然后,我已经有大约5年的Java开发Web应用程序经验,以及一点点PHP的经验。 当他们描述了实现所需的交叉功能所必需的功能时,我想到了在PHP中使用我的旧工作,并在大约两周(或一个月的时间)内完成一个项目。 但是,正如经常发生的那样,我的估计过于乐观。 在用PHP重新读取模板引擎的源代码时,我很害怕自己写的东西 ,我意识到这些古老的大学技术至少需要立即发送良好的优化。

我越是沉浸在旧的PHP源码中,就越意识到我对这种语言和源码状态的了解,即使这个小项目也会伤害我。 因此,我仍然决定使用Spring框架,在使用Java Web的这些年里,Spring框架对我来说是温暖而柔软的青苔。 我最初不想这样做,因为该计划的规模似乎很小。 当然,我错了,因此使用熟悉的Java语言的决定将潜在的痛苦变成了后来的乐趣。

设计方案


由于该想法不是我的想法,因此在设计过程中,我经常猛拉这个想法的作者,以确保我对项目的看法与该想法一致。 在冗长的讨论过程中,我从项目中得到启发,并已开始为用户和管理员介绍各种方便实用的面包。 设计受到了应有的重视:我们讨论了功能的每个细节,绘制了几乎所有页面的布局,保存了描述应用程序和用户功能逻辑的文档。

布局和文档在不断发展,并充斥着细节和新功能。 随后,布局成为其中的一件事,表明我在评估项目的复杂性方面有多么错误。


课程编辑器页面布局演变示例

当然,我自己应该为功能的后续复杂性负责,从而增加了开发时间。 但是,我不想让另一个政府网站出现在Internet上,其中有成千上万个质量较差的网站; 我希望从易用性和外观上使用户满意。 而且,我内部的完美主义根本不允许我使用“隐秘-在生产中使用隐秘”的方法。 因此,我们甚至精心设计了页面布局(您将看到,这对细节的详细说明并没有造成混乱的限制)。


用户个人资料设置页面布局

达到了可选功能之后,我计划单独使用该功能,然后我开始在图形输入板上手动绘制模型。


管理面板中“用户”页面的布局

在设计过程中,我们尝试考虑系统,以便在启动后,我们对站点生命的进一步参与降至最低。 我们确实不想审核用户在网站上发布的内容,甚至不希望雇用主持人。 我们希望社区决定发布哪个课程,哪个小玩意儿不公开,哪个用户禁止淫秽的个人资料或评论。 当然,不可能完全摆脱这种情况,但是最终我们至少设法使自己摆脱了潜在的常规。

在设计阶段的最后,我意识到我们至少要写六个月的作品。 此外,除了交换小玩意的可能性外,我们还决定增加在编织小玩意上写文章的能力(以及以后在一般的针线活上写文章),并由社区本身检查这些文章(后来,此功能比交换系统实施起来更加困难和冗长)。 。 但是总的来说,我喜欢它在纸上的工作方式并研究了模型,因此我开始实施并决定将其结束。

因此,根据我们的想法,该应用程序应具有以下基本功能

-在网站上注册和帐户设置;
-与世界各地的人们交流小玩意;
-编写课程,检查并批准其站点社区;
-带有特定课程和小玩意的页面;
-包含课程和小玩意列表的页面;
-评论课程和小玩意;
-事件通知系统;
-投诉,禁令和配额制度;
-用户之间的聊天;
-网站统计;
-管理员

此外,该网站最初应该面向国际受众 :可以在世界各地进行交流,可以用任何语言编写课程,并且可以以任何语言进行本地化(当然,如果有翻译人员想要这样做,那么稍后我甚至编写了一个小型应用程序,通过该应用程序,您可以方便地将网站翻译成载体语言。

决定创建一个最小的财务投资网站:不购买或订阅第三方服务,不投资广告,雇用翻译和支付SSL证书。 我们只允许自己花一个域名VDS 。 还有一点牙线,但以后会更多。

预计将来会开发该项目,因此我直接进入了实施阶段。 我决定全职工作(是的,非商业项目也会发生这种情况)。

实作


在我的两人团队中,我是唯一的程序员,因此大多数实现叙述都是以我的名义进行的。

我所做的第一件事是绘制数据库模型。 第一次迭代后,我得到了大约30张桌子。 在最终版本中,已经有43个,作为ORM,我选择了Hibernate,因为我的工作经验很小但很愉快。 我选择MySQL作为基础。


数据库模型,从远处看

在开始的时候,我考虑过如何用原始数据填充数据库。 这些数据很多:语言,国家/地区,静态内容,课程类别等等。 我不想存储甚至更多地支持SQL格式的数据,因此我决定编写用于以CSV格式导入和导出数据的系统。 将来我不会后悔,因为这些系统多次加速了开发过程,并使得处理生产数据变得更加方便。 我称系统为Inida (来自“ Initial Data”,尽管这个名称不再非常合适)。

有关Inida的更多信息
这是inida数据的示例:

i Country;isocode;name ;by;Belarus ;gb;United Kingdom ;ru;Russia 

第一行的标题描述了操作(i-插入),数据类型(数据库中实体的名称)和字段。 以分号开头的行就是数据本身。 如果将上述文本(Inida数据)提供给Inida进口商,则三个条目将添加到数据库中(在此示例中为三个国家)。 Inida数据可以具有多个标头,这使您可以一次处理多个数据库实体。

Inida支持以下记录操作:

i-插入 :添加新记录;
u-更新 :更新现有记录(通过键,这些键是标有“ +”号的字段的值);
m-merge :本质上是插入+更新(如果没有具有指定键值的记录,则创建该记录;否则,更新记录);
d-删除 :删除指定键的数据。

Inida还具有以下功能:

  • 通过自定义转换器转换字段值 (例如,将日期从一种格式转换为另一种格式,修饰数据,清理等);
  • 在后续的Inida数据中记录使用这些记录的别名
  • 批处理模式 :更新,合并或删除仅满足部分键的记录(在正常模式下,当您尝试一次更新多个满足相同键的记录时,将引发异常);
  • 替换 (您也可以嵌套 ):一种在C ++中的模拟定义(当长短语多次使用时很有用);
  • 默认值 (在需要为多个记录复制字段的相同值时方便);
  • 支持列表值 (如果字段值是列表集合);
  • 支持对象字段 (一级嵌套)。

还有其他一些不太重要但也有用的功能。

Inida也可以导出数据。 这是通过编写与导入时相同的标头来完成的,只是不指定操作即可:

 Country;isocode;name 

在上面的示例中,出口商将以inida格式卸载所有国家。 可以通过指定上载记录将满足的键值来限制卸载量:

 Country;isocode=ru;name 


该站点的功能之一是在个人资料的地图上显示用户所在的城市。 由于我希望我们的站点在依赖外部服务方面尽可能自给自足,因此,由于这个小功能,我非常困惑,花了大量时间寻找解决方案并开发其他应用程序。

寻求使用卡实现功能
首先,有必要从某个地方获取地图本身,或者更确切地说,从不同细节级别的地球地图中获取地图(以使地图更近)。 搜索使我进入了ESRI映射服务,该服务具有我在公共领域中所需的图块。 但是问题在于它们没有指向磁贴档案的链接(或者我根本找不到它们)。 但是每个图块都可以通过某种格式的URL下载。 我迅速编写了一个应用程序,该应用程序卸载了所需数量的细节级别的图块,并将其放置在适当的文件夹中。 我只有8个级别(0-7),总容量约为138 MB。

其次,有必要以某种方式显示下载的地图。 幸运的是,这个问题的解决方法非常简单:我发现Leaflet JavaScript插件在显示给定URL上的地图图块方面做得很好。

第三,最后,必须从某个地方获取地理位置(坐标和住区名称),最好使用不同的语言。 任务的这一部分是最艰巨和艰巨的,因为我没有立即设法找到不同国家或多或少详尽的定居点清单。 结果,我仍然找到了这样一个列表,但是它的名称只包含一种语言。 我想为每个国家/地区提供机会,以该国家/地区的官方语言(例如,俄语和白俄罗斯语中的白俄罗斯语),事实上的国际语言(不幸的是,英语)和世界语(因为我真的很喜欢这种语言的想法。

结果,出现了另一个子任务:查找并准备每个国家的官方语言列表。 幸运的是,有人已经在我之前收集了这些信息,因此我只需要将其提供给程序,我将在下面的几段中对其进行描述。

本地化社区名称的来源是Nominatim 。 由于我们无法通过单个链接获取本地化名称,因此我必须分两步进行:

  • 使用其名称(使用可访问的语言)和国家/地区请求有关和解的信息; 此信息采用JSON格式;
  • 使用接收到的JSON中“ place_id”字段的值,请求以不同语言(以常规网页的形式)包含有关村庄及其名称的信息的页面。

由于远未成功收到所有HTTP请求的答案(由于各种原因,其中有一个普通的“ Internet连接丢失”),因此我们还必须记录未成功定位本地化的尝试,以便在下一次迭代中再次尝试。 另一个困难是Nominatim被正式禁止使用太多,因此为了不被禁止,我不得不在两次请求之间引入延迟,从而将请求的数量限制在每秒允许的最大数量内。

因此,考虑到上述所有因素,我编写了一个程序,以本地化住所所属的国家/地区的官方语言(以及如上所述的英语和世界语)来处理居民点的本地化。 可以在4个迭代中进行本地化,并且该程序在专门用于此任务的上网本上工作了1.5天,耗时数天。

我自己发明的下一个任务是标志图标的准备。 问题在于国家和语言的标志。 甚至在我下载了免费的大量好的图标存档后 ,每种分辨率的分辨率都很高。 我不得不浏览维基百科并使用photoshop。

寻求标志图标
正如某些人可能猜到的那样,第一个问题是某些国家普遍缺乏旗帜。 事实是,我试图维护ISO 3166-1 alpha-2中所有正式分配的国家/地区代码。 我主要在Wikipedia上找到了我需要的国家/地区的标志,然后在Photoshop中以我需要的分辨率和音量效果对其进行了准备。 我缺少十几个标志,所以我很快解决了任务的这一部分。

带有语言复选框的情况原来更加复杂。 事实是,在许多站点上都说使用该语言的标志不是很合理,因为这通常意味着将语言链接到特定的国家。 例如,英语应该标记什么:美国,英国或澳大利亚? 还是新西兰? 对于西班牙语:墨西哥还是西班牙语? 避免在语言中使用标志的论点对我来说是令人信服的,但是我确实想要视觉上的代表性,因此我仍然决定在我们的网站上使用它们(尽管有些“通过我自己”)。

主要的困难是我只为国家/地区标记。 对于语言,我不能仅仅因为国家/地区的ISO代码和与它们对应的语言的ISO代码(在特定情况下)通常有所不同(例如:BE-白俄罗斯语,BY-白俄罗斯;英国-乌克兰语,UA)而不能使用它们-乌克兰)。 记住我已经有按国家列出的语言列表,因此决定编写一个小程序,根据这些数据将按语言编译国家列表(即,它将输出反向映射)。

编写程序并收到所需的语言列表后,我开始准备带有语言标记的图片(我只是将标记重命名为国家/地区)。 与国家/地区一样,在语言方面,我尝试支持所有ISO-639-1 。 是的,没有足够的语言标记,但这一次短缺的数量是原来的几倍。 很长一段时间以来,我一直在弄清楚在哪个区域使用哪种语言,但是结果是,每个语言都准备了一个相应的(或不,我不知道;至少没有人抱怨)标志。

该网站功能的一部分(可确保由社区本身对其进行监管)已成为投诉和禁令的系统。 用户可能会抱怨个人资料信息(名称,头像,用户信息),评论,提示,邮寄地址和上载的图像。 当收集到足够数量的投诉时,相应功能将被上诉用户阻止。 一周后,将第一把锁取下,随后的每把锁的持续时间延长一倍。 某些锁(例如用户名)是永久性的; 这是仍然需要管理员注意的情况之一。

即使在设计过程中,我也意识到可以在网站上设置机器人。 当然,鉴于网站及其目标受众的普及率较低,这种情况不太可能发生,但是“真诚地”做所有事情的愿望盛行。 为了防止潜在的垃圾邮件,我引入了一种配额机制,该配额机制用于与网站内容生成有关的一种或多种用户操作:评论,编写聊天消息,编写课程,请求地址,注册帐户(均来自一个IP地址,每天总计) )和其他一些。

一个有趣的任务是管理功能之一的实现,即搜索相似的地址。 我在有关Habré的一篇文章中发现了该方法(不幸的是,我找不到该文章,因此我将在下面简要介绍该方法的本质)。 老实说,由于误报的数量相对较多,我对实现这些功能的结果并不满意。

类似地址验证的工作原理
首先,形成邮件签名签名数据库。 在这种情况下,签名是字符列表以及每个字符的出现次数。 这样做是这样的:

0)采用文本形式的邮寄地址;

1)我们从地址(空格,标点符号)中删除了不必要的信息,并将所有字符翻译成相同的大小写;

2)计算剩余文字的签名。

此外,当新用户注册时或现有用户更改其地址之一(常规或音译)时,将对这个新的(或更新的)地址进行上述过程,然后计算签名差异(相应字母数字之间的差异之和)。 如果差异小于某个指定的阈值,则认为地址相似。

当我在应用程序的服务器端努力工作时,我的合著者没有袖手旁观,而是使用Bootstrap库来标记站点,因为他确实希望该站点也可以方便地在移动设备上使用。
我们在这里准备的页面布局非常有用。

设计方案


我不喜欢标记浮动,网站看起来很糟糕并且脚本仅在执行了用户期望的操作后才能正常工作。 即使在开发过程中。 因此,我一直试图保持网站外观的准确性,因此我很高兴使用它,查看此设计中的新功能,并为其创建新页面。 我允许自己花时间舔琐事,甚至知道它们仍然不会进入最终版本。 只是因为该网站正在等待完全重新设计。


这是重新设计开始之前网站的外观

在考虑网站最终版本的外观时,我考虑了以下因素和我自己的愿望:

  1. 设计应符合场地主题(小玩意,针线活);
  2. 设计应营造出温暖的灯管气氛;
  3. 设计应使网站易于理解且易于使用。

我什至没有考虑过网站设计方法的选择,因为它对我来说是明确的:拟态。 以上各项使我更加相信自己选择的正确性。 我完全理解这种方法的工作量,但是我准备花时间在它上面,因为我希望获得令人愉悦的效果。 而且,多年在Photoshop中的经验使此过程更容易且压力较小。

为什么我讨厌现代设计
由于我不喜欢现代平面设计,因此也决定使用拟变形设计。 对我个人而言,拟态设计是视觉清晰度和代表性方面的参考。 Guitar Rig 5中的乐器设计, FL StudioKontakt的许多插件,《 炉石战记》游戏的用户界面外观-所有这些都使我发狂,并使与应用程序或游戏的通信变得非常愉快。 这样的设计毫无疑问地涉及哪个接口元素以及如何使用它。

当前的趋势使应用程序和站点完全相同且面目全非。 如果早期的Web设计人员试图赋予网站个性,那么现在每隔一个网站看起来都过于刻板:

  • 巨大的图片甚至视频作为背景;
  • 用大字体写的抽象口号;
  • 固定标题过宽;
  • 巨大的全屏页脚(有时甚至更多);
  • 用细字体写的文本,甚至在白色背景上是灰色的;
  • 页面上的马大小的缩进;
  • 尖叫和完全不兼容的颜色;
  • 页面的样式为“向下滚动,不了解此处宣传的服务的含义”。

当然, 每个人的亲人

  • 一个弹出窗口,其中包含有关cookie的信息;
  • 弹出窗口,其中包含有关用户协议更改的信息;
  • 一个要求订阅的弹出窗口(以及浏览器本身中的另一个类似弹出窗口);
  • 每两段文字显示黄色的整块广告。

现代网站充斥着肮脏的把戏,将无用的侵入性内容直接弹出用户的脸庞。 而且,所有这些内容都令人讨厌,以致于有时很难找到所需的部分。 当访问这些站点时, 手指本能地按Ctrl + W,我立即想逃避它们,不再回头。

对我来说,另一个引人注目的例子是Microsoft Office的设计,它从庞大的版本(2010版)更改为扁平的版本(2013版)。 许多元素开始看起来相同(例如,输入字段和按钮),这极大地阻碍了它们的视觉感知,因为现在大脑必须更加努力地工作才能理解哪个元素在哪里。 在体积设计的情况下,可以轻松地区分元素,这使得专注于工作成为可能,而不是在数十个相同元素中找到合适的用户界面元素。

我真的不希望我们正在开发的项目看起来像绝大多数现代站点,并且在首次调用和使用过程中都令人厌恶。 我使用的是从事针线活的人的真实桌面的图像,而不是抽象的平面和无边界的块。 为了使网站设计看起来像真实世界,我花了很多时间来寻找合适的图像。

此外,很多照片是由我们亲自拍摄或扫描的,然后在Photoshop中进行处理。


Kumihimo和珠

以下是一些已在设计中使用的实际对象示例:

  • 摆在我周围的礼物缎带充当了听众的角色;
  • 菜单是从我的笔记本上撕下来的一张纸(原来在盒子里);
  • 页面内容前面的标题是用于阅读电子书的封面的元素;
  • 弹出窗口和页脚中的补丁-牛仔背包的元素;
  • 弹出按钮-短裤按钮;
  • 主页上的徽标-写意图;
  • 在页脚前面和右侧页面上可以看到的所有小玩意和许多珠子也来自真实世界(一些小玩意是在项目开发期间编织的)。


主页


页脚

更多截图

用户个人资料页面


课程列表页面


语言弹出

最耗时的工作之一是准备要与border-image CSS属性一起使用的图像。 整个困难是图片的某些部分在重复时看起来应该是无缝的。 这就像绘制重复的(无缝的)纹理一样,只是难度更大。 大部分时间都花在了用于弹出窗口设计的图片上(以及页脚中的补丁),因为“拉伸”该图片的元素的大小可以在垂直和水平方向自由改变。

可能是,与设计相比,我们比其他任何东西都更加困惑。 此外,他们非常困惑,以至于许多环境元素(例如珠子和珠子)和一些图标都在Blender中建模和渲染(某些东西甚至在Substance Painter中被纹理化)。 是的,由于图标大小约为32x32像素,我们感到非常困惑。


渲染结果

如何创建设计元素

建模珠(用作环境元素)


建模珠(用作环境元素)


按钮建模(用作环境元素)


密钥建模(用作“管理员”图标)


铅笔建模(用作按钮上的“编辑课程”图标)


在物质画家中纹理化珠

, . , . JIRA , , . , . , . , , .


267 -

, () , Bootstrap, . , , . , .


, , — , — , , . , , - . — , .

«fenker» («»), . , , -. : Fenkexchange, Friendship Pigeon, Flossy Hearts, Silky Hearts,…. , . ( ) (: -). - — FriendBird.

VDS, Debian Linux VirtualBox, . Linux ( ) , , « », Windows ( - 2D 3D ); - Apache Linux . , Linux - , , . , .

Linux
, , — . , , , . , -, , , , . — , , - - Linux. , Windows , . , .

: MariaDB. URL' . MariaDB , MySQL Oracle, . , MySQL Oracle.

. , . - , , . , , -.

SSL-. , , , . ( Let's Encrypt) . , , Tomcat'. , , , . , , - ( fullchain- ( private key) pkcs12, JKS (Java Key Store), Tomcat'). , , , .

, «» — , . , , « », , .

- Linux , VDS, - , . , , . , , - . - , . , , .


25 2018 , , . , -. .

- , , , . — . ; , . , , .

. , - , , . , , .

:

  • 131 ;
  • 14 ;
  • 15 ( ).

, , , . , . ( 2018.01.25 2018.07.03 ) 29 . , , .

, - . , . . , . .

, . , , ( , , ). , , , . , , , (, , , ). , - .


5 1.5 , :

2018.07.05

, , ; , , . , , , .




, , , , . , - ( ); ( ) ( , VDS ). , , , .

(, CDN ), , . , , . , - , , ; .

Source: https://habr.com/ru/post/zh-CN416883/


All Articles