Эх сурвалжийг харах

0605 验证码和注册接口

Qing 11 сар өмнө
parent
commit
dd77f6c46e

+ 367 - 0
novel-demo/json/test.json

@@ -0,0 +1,367 @@
+{
+  "code": "00000",
+  "message": "一切 ok",
+  "data": [
+    {
+      "id": "1431630596354977799",
+      "categoryId": "8",
+      "categoryName": "出版频道",
+      "picUrl": "/images/2023/12/10/d6ca7bcb0a46f21fbe09.jpg",
+      "bookName": "长夜难明",
+      "authorName": "111",
+      "bookDesc": "该小说讲述了江阳、朱伟等人为了替侯贵平沉冤昭雪,十年来受到重重阻碍但不断收集案件相关证据,最终设局引发社会关注的故事。作者以弱势儿童群体的生存境遇为切口,用“性侵未成年少女”案件将矛头直指偏远地区法治落后的问题,反映出其对寻求司法公正和维护社会秩序的强烈期盼,折射出一个作家的社会责任感\n",
+      "wordCount": "155951",
+      "lastChapterName": "Table of Contents",
+      "lastChapterUpdateTime": "02/19 16:34"
+    },
+    {
+      "id": "1431630596354977804",
+      "categoryId": "1",
+      "categoryName": "玄幻奇幻",
+      "picUrl": "/image/2024/02/19/023e4fbbb1b5c3566cf368687d607270.jpeg",
+      "bookName": "测试测试测试测试",
+      "authorName": "1111",
+      "bookDesc": "测试测试测试测试测试测试测试测试",
+      "wordCount": "105",
+      "lastChapterName": "第一章",
+      "lastChapterUpdateTime": "02/19 16:29"
+    },
+    {
+      "id": "1431630596354977794",
+      "categoryId": "8",
+      "categoryName": "出版频道",
+      "picUrl": "/images/2023/11/28/5ed4f3590a05942f.jpg",
+      "bookName": "人类简史",
+      "authorName": "111",
+      "bookDesc": "人类简史:从动物到上帝(图文精编版) (开放历史系列)",
+      "wordCount": "289466",
+      "lastChapterName": "参考数据",
+      "lastChapterUpdateTime": "11/29 20:47"
+    },
+    {
+      "id": "1431630596354977796",
+      "categoryId": "8",
+      "categoryName": "出版频道",
+      "picUrl": "/images/default.gif",
+      "bookName": "福尔摩斯探案全集",
+      "authorName": "111",
+      "bookDesc": "《福尔摩斯探案集》是英国作家阿瑟·柯南·道尔创作的系列推理小说,其中第一部中篇《血字的研究》完成于1886年,隔年与其它作品合集出版于《比顿圣诞年刊》。\n该作品主人公是夏洛克·福尔摩斯(Sherlock Holmes,又译作歇洛克·福尔摩斯),全书共有四部中篇及五十六部短篇《福尔摩斯探案集》构思精巧,情节曲折离奇,推理逻辑性严密,语言洗练通俗,形象易懂,深受广大读者喜爱。",
+      "wordCount": "1470530",
+      "lastChapterName": "译后记",
+      "lastChapterUpdateTime": "12/02 21:14"
+    },
+    {
+      "id": "1431630596354977795",
+      "categoryId": "8",
+      "categoryName": "出版频道",
+      "picUrl": "/images/2023/11/28/500deca455f2d464.jpg",
+      "bookName": "三体",
+      "authorName": "111",
+      "bookDesc": "《三体》(别名“地球往事”三部曲)是刘慈欣所著长篇科幻小说,讲述了地球人类文明和三体文明的信息交流、生死搏杀以及两个文明在宇宙中的兴衰历程。2015年8月,《三体小说》荣获第73届雨果奖最佳长篇小说奖 。",
+      "wordCount": "1015768",
+      "lastChapterName": "未知",
+      "lastChapterUpdateTime": "11/29 21:49"
+    },
+    {
+      "id": "1334335471568912384",
+      "categoryId": "2",
+      "categoryName": "武侠仙侠",
+      "picUrl": "/images/2023/11/30/4dea93dfc7ded4e9.jpg",
+      "bookName": "我辈的江湖",
+      "authorName": "钟无涯",
+      "bookDesc": "    下载客户端,查看完整作品简介。",
+      "wordCount": "449886",
+      "lastChapterName": "第七十九章 青山遮不住,毕竟东流去 药王谷之战12",
+      "lastChapterUpdateTime": "12/13 10:42"
+    },
+    {
+      "id": "1337759637059973121",
+      "categoryId": "4",
+      "categoryName": "历史军事",
+      "picUrl": "/images/2023/11/30/1cfaa56c4e32bbef.jpg",
+      "bookName": "檀香刑",
+      "authorName": "莫言",
+      "bookDesc": "  《檀香刑》是莫言潜心五年完成的一部长篇力作。在这部神品妙构的小说中,莫言以1900年德国人在山东修建胶济铁路、袁世凯镇压山东义和团运动、八国联军攻陷北京、慈禧仓皇出逃为历史背景,用摇曳多姿的笔触,大悲大喜的激情,高瞻深睿的思想,活龙活现的讲述了发生在\"高密东北乡\"的一场可歌可泣的兵荒马乱的运动,一桩骇人听闻的酷刑,一段惊心动魄的爱情。",
+      "wordCount": "315410",
+      "lastChapterName": "第一章 眉娘浪语",
+      "lastChapterUpdateTime": "12/12 21:33"
+    },
+    {
+      "id": "1337759773395824640",
+      "categoryId": "4",
+      "categoryName": "历史军事",
+      "picUrl": "/images/2023/11/30/eb0bb43a326e8709.jpg",
+      "bookName": "从今天开始做藩王",
+      "authorName": "背着家的蜗牛",
+      "bookDesc": "  一闭眼,一睁眼。赵煦发现自己成了一名皇子。美人妖娆,封地很远,国家很乱。而他只想守着自己的封土逍遥自在。只是若有敌人敢来犯,只让他有来无回,心胆寒……",
+      "wordCount": "388176",
+      "lastChapterName": "第一百二十二章 狐狸尾巴",
+      "lastChapterUpdateTime": "12/14 18:16"
+    },
+    {
+      "id": "1337762752513486849",
+      "categoryId": "4",
+      "categoryName": "历史军事",
+      "picUrl": "/images/2023/11/30/21f70da85b30e400.jpg",
+      "bookName": "明朝那些事儿7: 大结局",
+      "authorName": "当年明月",
+      "bookDesc": "  《明朝那些事儿7:大结局》是对这样一段历史进行了分析梳理,引人思索:明朝最后一位皇帝,自来有许多传说。关于崇祯究竟是一个昏庸无能的皇帝,还是一个力图奋起的人,一直众说纷纭。不管怎么说,这是一个残酷的时代,也是一个精彩的时代。在这一时期,北方的后金势力崛起,经过努尔哈赤的经营,势力急剧壮大。努尔哈赤死后,皇太极即位。袁崇焕就在这一时期迈上了历史的舞台。本文作者告诉我们,袁崇焕这个民族英雄,在历史上不过是个二流角色。",
+      "wordCount": "256585",
+      "lastChapterName": "后记",
+      "lastChapterUpdateTime": "12/12 21:26"
+    },
+    {
+      "id": "1337872061003993088",
+      "categoryId": "4",
+      "categoryName": "历史军事",
+      "picUrl": "/images/2023/11/30/21f70da85b30e400.jpg",
+      "bookName": "酒楼",
+      "authorName": "许春樵",
+      "bookDesc": "  天德酒楼传到了齐家三兄弟一代,却被老大一人独占。老三齐立言不愿接受兄长的施舍,也不堪老大的精神虐待,在造汽车的白日梦幻灭后,从最底层做起,历经穷困潦倒和各种打击,终于创办了自己的酒楼,吞并了老大的酒楼。成功后的齐立言却变了,由诚笃奋发的创业者变成了狡诈贪心的资本野心家……",
+      "wordCount": "268359",
+      "lastChapterName": "第63章 第二十三章 2",
+      "lastChapterUpdateTime": "12/13 05:27"
+    },
+    {
+      "id": "1337872316667793408",
+      "categoryId": "4",
+      "categoryName": "历史军事",
+      "picUrl": "/images/2023/11/30/21f70da85b30e400.jpg",
+      "bookName": "大唐太子李建成",
+      "authorName": "龙耳东",
+      "bookDesc": "  小说根据宋朝范祖禹、明末清初王夫之,近代章太炎、陈寅恪、郭沫若以及当今世界知名史学家牛致功、胡戟、胡如雷等人的历史研究成果,拨开历史迷雾,还原历史真相。通过李建成短暂而悲剧的人生,告诉您一个波澜壮阔的时代发生的一些惊心动魄的事件,无不令您感慨万千,气荡回肠,掩卷深思,受益良多……",
+      "wordCount": "383470",
+      "lastChapterName": "第86章 野火烧不尽 3",
+      "lastChapterUpdateTime": "12/13 04:49"
+    },
+    {
+      "id": "1337872488235798528",
+      "categoryId": "4",
+      "categoryName": "历史军事",
+      "picUrl": "/images/2023/11/30/21f70da85b30e400.jpg",
+      "bookName": "我的唐山",
+      "authorName": "林那北",
+      "bookDesc": "  本书是第一部史诗性再现唐山过台湾历史的长篇巨作。宏大的视野,观照恢弘历史中的纵横捭阖,细致的笔触,抚摸往昔岁月里的爱恨情仇。小说通过一对貌合神离的兄弟和两个性情迥异的女子之间爱恨情仇、波澜起伏的人生悲欢展现整个唐山过台湾斑驳、丰饶而跌宕的历史画卷……",
+      "wordCount": "271529",
+      "lastChapterName": "第54章 后记:蚯蚓般穿过那段历史",
+      "lastChapterUpdateTime": "12/13 04:24"
+    },
+    {
+      "id": "1337872597996539904",
+      "categoryId": "4",
+      "categoryName": "历史军事",
+      "picUrl": "/images/2023/11/30/19c9400b07944a99.jpg",
+      "bookName": "火蓝刀锋",
+      "authorName": "冯骥",
+      "bookDesc": "  一次危险的水下救援,将爱吹牛的草根渔民蒋小鱼阴差阳错地进了以残酷训练而著称的“兽营”,在这里,他遇到了一批绝世天才:能在丛林中徒手搏狼的野孩子张冲,全国大学生游泳冠军鲁炎,打遍兽营无敌手的“兽王”巴郎,在海盗窝里艰辛成长的“战神”向羽,草原上的神枪女猎人乌云格日乐等人。",
+      "wordCount": "338816",
+      "lastChapterName": "第112章",
+      "lastChapterUpdateTime": "12/13 04:12"
+    },
+    {
+      "id": "1337872898115768320",
+      "categoryId": "4",
+      "categoryName": "历史军事",
+      "picUrl": "/images/default.gif",
+      "bookName": "出手",
+      "authorName": "陈建波",
+      "bookDesc": "  民国时期,陈仓城,随着陈仓守将党玉昆的覆灭,缙绅名流孙伯啸突然成为各方势力关注的焦点——相传党玉昆曾交他保管一大批藏宝。孙府周围频频上演各种明争暗斗的好戏,共产党、国民党、土匪、日本人、美国人等多方势力互相交错。迷雾重重之中,各方势力一一出手,鹿死谁手?谁能得手?",
+      "wordCount": "325229",
+      "lastChapterName": "第63章 最后一搏 7",
+      "lastChapterUpdateTime": "12/13 02:25"
+    },
+    {
+      "id": "1337873148071120896",
+      "categoryId": "5",
+      "categoryName": "科幻灵异",
+      "picUrl": "/images/2023/11/30/1cfaa56c4e32bbef.jpg",
+      "bookName": "污点",
+      "authorName": "武和平",
+      "bookDesc": "  小说作者既是行动者,又是书写者,还是思想者。他一手用枪,一手用笔,集战士与诗人于一身。他把经验的亲历与人性的剖析结合在一起。他的长篇小说充满正义的激情、直观社会的勇气和法的尊严。小说讲述了一个文物失窃案如何历尽千辛终被破获的故事。其中有动人的爱情故事和感人至深的亲情……",
+      "wordCount": "305586",
+      "lastChapterName": "第70章 后记",
+      "lastChapterUpdateTime": "12/13 05:14"
+    },
+    {
+      "id": "1337874646456864768",
+      "categoryId": "5",
+      "categoryName": "科幻灵异",
+      "picUrl": "/images/default.gif",
+      "bookName": "黑白道3:渗透",
+      "authorName": "朱维坚",
+      "bookDesc": "  洪水中接连出现一男一女两具尸体,李斌良和战友们经缜密侦查,确认二人都是本市应届高中毕业生。为查明真相,他的足迹随着作家的笔迹奔走于各个校园之间,由此他涉足到一个从未涉及过的领域——教育……",
+      "wordCount": "316340",
+      "lastChapterName": "第63章 尾声",
+      "lastChapterUpdateTime": "12/13 04:37"
+    },
+    {
+      "id": "1337874812798767104",
+      "categoryId": "5",
+      "categoryName": "科幻灵异",
+      "picUrl": "/images/default.gif",
+      "bookName": "噬魂",
+      "authorName": "通吃小墨墨",
+      "bookDesc": "  这个世界绝对没有绝对的事情,也没有不可能的事。一把充满灵性的枪,一个有着特殊异能的警察,一个能走在人间和冥界的IT人士。一件件无法用现代科学去解释的事件。是世间的恶灵,还是人的心魔?凶手是谁?说不定,他就在看着你……",
+      "wordCount": "268278",
+      "lastChapterName": "第58章 第四十六章 大结局 3",
+      "lastChapterUpdateTime": "12/13 03:59"
+    },
+    {
+      "id": "1337874951365988352",
+      "categoryId": "4",
+      "categoryName": "历史军事",
+      "picUrl": "/images/default.gif",
+      "bookName": "远征·流在缅北的血",
+      "authorName": "金满",
+      "bookDesc": "  远征军第一次入缅作战大溃败,狙击手岳昆仑为追寻大部队孤身进入野人山。在地狱般的野人山中岳昆仑历经生死,与一群战友结下生死情谊。在印度兰姆伽基地整训后岳昆仑跟随部队踏上反攻缅甸的征程,与为兄报仇的天才狙击手藤原冷野不期而遇。",
+      "wordCount": "287517",
+      "lastChapterName": "第70章 2",
+      "lastChapterUpdateTime": "12/13 02:13"
+    },
+    {
+      "id": "1337875255574663168",
+      "categoryId": "1",
+      "categoryName": "玄幻奇幻",
+      "picUrl": "/images/default.gif",
+      "bookName": "洪荒修圣",
+      "authorName": "轩影九变",
+      "bookDesc": "  在他第一次练功的时候,产生的能量波动和天地灵气达到了共振,产生了一个黑洞,将云谣一下子吸了进去。而到的哪个时候,竟然是盘古还没有开天的洪荒时代。那时机遇不断,危险不断的时代。且看现代人云谣怎样玩转圣人,玩转洪荒……",
+      "wordCount": "346840",
+      "lastChapterName": "第一百一十二章 云谣得道 元神合一",
+      "lastChapterUpdateTime": "12/13 04:43"
+    },
+    {
+      "id": "1337876581629038592",
+      "categoryId": "5",
+      "categoryName": "科幻灵异",
+      "picUrl": "/images/2023/11/30/21f70da85b30e400.jpg",
+      "bookName": "诸天",
+      "authorName": "目自翕张",
+      "bookDesc": "  骆天明本是个农民工,穿越后的身份也和农民工类似,成了挑担子的沙悟净。好在天无绝人之路,他还有个穿越者的标配——系统。只是这个系统也是平民版的,简陋的让人无法直视。骆天明就依靠这个系统,穿越各个位面,见识各种各样的人和事,不断的炼心炼体,一步步走上巅峰!",
+      "wordCount": "428829",
+      "lastChapterName": "162 ?落入陷阱",
+      "lastChapterUpdateTime": "12/14 18:31"
+    },
+    {
+      "id": "1337879143543476224",
+      "categoryId": "5",
+      "categoryName": "科幻灵异",
+      "picUrl": "/images/2023/11/30/07ba573fa7d5eb40.jpg",
+      "bookName": "最后一个道士3",
+      "authorName": "夏忆",
+      "bookDesc": "  查文斌,凌正阳二十七代传人,茅山天正道掌门,一个因救人触犯了天罚的道士,一个源自生活的人物原型。将带领我们走进一个未知的全新的道家世界,重新打开属于传说中的真实腹地。青衣人,忘川渡人,棺中人,为何都与他有着一致的面孔?师傅、父母、儿女为何一个个都会离他而去?卓雄和大山的身世,血色的纹身究竟象征着什么?一切之前的所有谜团将会在《最后一个道士3》全部揭晓!",
+      "wordCount": "287111",
+      "lastChapterName": "第二十章 灭差",
+      "lastChapterUpdateTime": "12/13 02:00"
+    },
+    {
+      "id": "1337879206630002688",
+      "categoryId": "5",
+      "categoryName": "科幻灵异",
+      "picUrl": "/images/2023/11/30/07ba573fa7d5eb40.jpg",
+      "bookName": "最后一个道士2",
+      "authorName": "夏忆",
+      "bookDesc": "  查文斌——茅山派祖印持有者,正天道最后一代掌教传人。他救人于阴阳之间,却引火烧身,遭天罚阴遣;仗侠肝义胆与一身道术,救活人于阴阳罅隙,渡死人于无间鬼道!身披鱼鳞的远古氐人,复活的神秘君王,真正的扶桑神树······",
+      "wordCount": "381916",
+      "lastChapterName": "番外 桥",
+      "lastChapterUpdateTime": "12/13 01:54"
+    },
+    {
+      "id": "1337882606201475072",
+      "categoryId": "5",
+      "categoryName": "科幻灵异",
+      "picUrl": "/images/2023/11/30/5624b582Nbc01af5b.jpg",
+      "bookName": "尸语者",
+      "authorName": "法医秦明",
+      "bookDesc": "  20个挑战心理极限的重口味案发现场,20份公安厅从未公开的法医禁忌档案。残忍、变态、惊悚、刺激、真实、震撼!尸语者,与死者朝夕相处的神秘职业,即将剖开震撼人心的亡灵之声!高速公路上抛下9袋尸块,被割下的膀胱里居然藏有冰碴,2000辆飞驰而过的车里,谁才是真正的凶手?垃圾场里被捆绑的女尸,全身器官都已经蜡化,要如何下手,才能验出她死亡的真相?电话打到一半,话筒里却传来沉闷的挣扎声,潜伏在校园当中的魅影,真的吞噬了那些女孩?资深法医老秦亲自捉刀,首度披露惊悚案发细节,创下悬疑小说从未到达的震撼尺度!荒山残尸、灭门惨案、校园禁地、公路游魂、水上浮骸、天外飞尸……每一案都让你无法入睡!",
+      "wordCount": "264167",
+      "lastChapterName": "第二十案 午夜凶铃",
+      "lastChapterUpdateTime": "12/13 01:29"
+    },
+    {
+      "id": "1337884719262470144",
+      "categoryId": "5",
+      "categoryName": "科幻灵异",
+      "picUrl": "/images/2023/11/30/5624b582Nbc01af5b.jpg",
+      "bookName": "古董局中局",
+      "authorName": "马伯庸",
+      "bookDesc": "  这是一部关于古董鉴定、收藏、造假、设局的百科全书式小说。字画、青铜、金石、瓷器每一件古董背后,都是深厚的历史积淀和文化传承;而每一件仿冒品背后,都是机关算尽的机巧和匪夷所思的圈套。古董造假、字画仿冒,古已有之。东晋时,康昕仿冒王羲之的书法真迹,连他儿子王献之也辨认不出来;宋朝皇帝宋徽宗喜欢造假,仿制了一大批商代的青铜兵器,摆在宫廷里,乐此不疲。在古董斑驳的纹理中,承载着一个民族的文化,一个时代的风貌,它的价值,不是金钱可以衡量的,但可怜的人类却只会用金钱去衡量它。",
+      "wordCount": "270312",
+      "lastChapterName": "尾 声",
+      "lastChapterUpdateTime": "12/13 01:17"
+    },
+    {
+      "id": "1337949399824781312",
+      "categoryId": "5",
+      "categoryName": "科幻灵异",
+      "picUrl": "/images/2023/11/30/21f70da85b30e400.jpg",
+      "bookName": "港综1986",
+      "authorName": "龙升云霄",
+      "bookDesc": "  五十年代,咏春叶问大战西洋拳王,咏春拳在港岛遍地开花。六十年,五亿探长雷洛一手遮天,组建金钱帝国。七十年,各大公司群雄并起,角逐王者宝座。八十年,群魔乱舞,你方唱罢我登场,弄潮儿各领风骚。说英雄谁是英雄,重生者吕泽仰望天空,立誓要谱写属于自己的传奇。",
+      "wordCount": "254724",
+      "lastChapterName": "第七十七章:大D成残废了",
+      "lastChapterUpdateTime": "12/29 21:45"
+    },
+    {
+      "id": "1337957605418520576",
+      "categoryId": "2",
+      "categoryName": "武侠仙侠",
+      "picUrl": "/images/2023/11/30/5624b582Nbc01af5b.jpg",
+      "bookName": "金丹传",
+      "authorName": "淮南居士",
+      "bookDesc": "  瑶池浪、多宝、后羿,他们三个一路为了追杀王子魔,三个上级武者,三个疯狂的上级武者,用他们变态的功力,摧毁了整个悬空城,彻底的打碎了悬空城,悬空城从此以后成为了传说。",
+      "wordCount": "276525",
+      "lastChapterName": "第56章 世界大战 3",
+      "lastChapterUpdateTime": "12/13 10:17"
+    },
+    {
+      "id": "1337958745514233856",
+      "categoryId": "2",
+      "categoryName": "武侠仙侠",
+      "picUrl": "/images/2023/11/30/21f70da85b30e400.jpg",
+      "bookName": "大虞天行",
+      "authorName": "叁拾伍",
+      "bookDesc": "  负责降妖除魔的大虞天行府的督丁赵山河醒来后惊骇发现自己竟是被只怨灵害死的。这职业如此危险他正惶恐,忽然察觉到自己识海竟有个书架,吸纳足够的情绪值,就能开启亮起的书本掌握本领。比如美食杂志能让他学会烧菜获得好评,反馈更多的情绪值。比如历代大家附录里的诗词能够提升灵符质地,甚至具现名将强军帮他杀敌。而他每学习一本,书籍还会自动更新其他的新书出来。这厮顿时振奋,于是天下妖魔就此倒了血霉。PS:我叫赵山河,我在大虞很红,因为我是个挂哔。",
+      "wordCount": "357237",
+      "lastChapterName": "2谁敢一战",
+      "lastChapterUpdateTime": "12/14 18:30"
+    },
+    {
+      "id": "1337960531323047936",
+      "categoryId": "3",
+      "categoryName": "都市言情",
+      "picUrl": "/images/2023/11/30/21f70da85b30e400.jpg",
+      "bookName": "废品收购站",
+      "authorName": "鬼谷仙师",
+      "bookDesc": "  物品:雄鹰展翅图!介绍:唐府遗弃之物,唐寅闲暇所作……完整度:20%修复需消耗财富值:50W。——陈牧羽,一个普普通通收破烂的,本以为一生注定平凡,没想到脑海里莫名其妙的飘来一座万界废品收购站,从此,世界变得不同了起来……",
+      "wordCount": "386692",
+      "lastChapterName": "第一百三十一章 妹子,你好漂亮!【第三更】",
+      "lastChapterUpdateTime": "12/14 17:56"
+    },
+    {
+      "id": "1337961040297644032",
+      "categoryId": "3",
+      "categoryName": "都市言情",
+      "picUrl": "/images/2023/11/30/5624b582Nbc01af5b.jpg",
+      "bookName": "帝王之武修都市",
+      "authorName": "奇玄子",
+      "bookDesc": "  一个纵横商界的奇葩人物,意外邂逅一块奇异石头,从此攻城略地崔营拔寨,钱财滚滚美女缠身,成就都市逍遥帝王!",
+      "wordCount": "358157",
+      "lastChapterName": "第81章 帝王,游戏人间",
+      "lastChapterUpdateTime": "12/13 10:24"
+    },
+    {
+      "id": "1337968514828390400",
+      "categoryId": "5",
+      "categoryName": "科幻灵异",
+      "picUrl": "/images/2023/11/30/5624b582Nbc01af5b.jpg",
+      "bookName": "极品记者斗僵尸",
+      "authorName": "浪子月生",
+      "bookDesc": "  \"一个胯下有巨物的记者在调查一桩变态的凶杀案时,意外邂逅一名村姑美少妇。从此记者神魂颠倒,千方百计想把少妇泡到手骗上床。不幸的是,每次都是失败而终。正当记者通过不懈努力,一步步接近成功时,一场山村里的僵尸玩过界,正在悄然上演……于是记者展开了一边泡少妇一边斗僵尸的奇异之旅。随着他在两方都一步步接近成功时,最终的僵尸之祖旱魃逐渐在山村中复苏……\"",
+      "wordCount": "371402",
+      "lastChapterName": "第102章 大结局 2",
+      "lastChapterUpdateTime": "12/13 11:01"
+    }
+  ],
+  "ok": true
+}

+ 12 - 0
novel-demo/pom.xml

@@ -85,6 +85,18 @@
             <version>2.0.2</version>
         </dependency>
 
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.8.27</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.data</groupId>
+            <artifactId>spring-data-commons</artifactId>
+            <version>3.3.0</version>
+        </dependency>
+
+
     </dependencies>
 
     <build>

+ 50 - 0
novel-demo/src/main/java/com/sf/controller/UserInfoController.java

@@ -0,0 +1,50 @@
+package com.sf.controller;
+
+import com.sf.dto.RestResp;
+import com.sf.dto.req.UserRegisterReqDto;
+import com.sf.dto.resp.ImgVerifyCodeRespDto;
+import com.sf.dto.resp.UserRegisterRespDto;
+import com.sf.service.IUserInfoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.stereotype.Controller;
+
+import java.io.IOException;
+
+/**
+ * <p>
+ * 用户信息 前端控制器
+ * </p>
+ *
+ * @author baomidou
+ * @since 2024-06-05
+ */
+@RestController
+//@RequestMapping("/userInfo")
+public class UserInfoController {
+
+    @Autowired
+    private IUserInfoService userInfoService;
+
+    @GetMapping("/api/front/resource/img_verify_code")
+    public RestResp<ImgVerifyCodeRespDto> getImgVerifyCode() throws IOException {
+        ImgVerifyCodeRespDto imgVerifyCodeRespDto = userInfoService.getImgVerifyCode();
+        return RestResp.ok(imgVerifyCodeRespDto);
+    }
+
+    @PostMapping("/api/front/user/register")
+    public RestResp<UserRegisterRespDto> register(@RequestBody UserRegisterReqDto userRegisterReqDto) {
+        UserRegisterRespDto respDto = userInfoService.register(userRegisterReqDto);
+        if (respDto.getType() == 1) {
+            // 返回错误的信息
+            return RestResp.fail("00001","验证码错误!");
+        }
+
+        if (respDto.getType() == 2) {
+            // 返回错误的信息
+            return RestResp.fail("00002","用户名重复了!");
+        }
+
+        return RestResp.ok(respDto);
+    }
+}

+ 9 - 0
novel-demo/src/main/java/com/sf/dto/RestResp.java

@@ -17,10 +17,19 @@ public class RestResp<T> {
         this.data = data;
     }
 
+    private RestResp(String code, String message){
+        this.code = code;
+        this.message = message;
+    }
+
     // 用静态方法返回对象
     // 泛型方法
     public static <T> RestResp<T> ok(T data){
         return new RestResp<T>(data);
     }
 
+    // 增加一个返回错误的方法
+    public static <T> RestResp<T> fail(String code, String message){
+        return new RestResp<T>(code, message);
+    }
 }

+ 39 - 0
novel-demo/src/main/java/com/sf/dto/req/UserRegisterReqDto.java

@@ -0,0 +1,39 @@
+package com.sf.dto.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Pattern;
+import lombok.Data;
+
+/**
+ * 用户注册 请求DTO
+ *
+ * @author xiongxiaoyang
+ * @date 2022/5/16
+ */
+@Data
+public class UserRegisterReqDto {
+
+    @Schema(description = "手机号", required = true)
+    @NotBlank(message="手机号不能为空!")
+    @Pattern(regexp="^1[3|4|5|6|7|8|9][0-9]{9}$",message="手机号格式不正确!")
+    private String username;
+
+    @Schema(description = "密码", required = true)
+    @NotBlank(message="密码不能为空!")
+    private String password;
+
+    @Schema(description = "验证码", required = true)
+    @NotBlank(message="验证码不能为空!")
+    @Pattern(regexp="^\\d{4}$",message="验证码格式不正确!")
+    private String velCode;
+
+    /**
+     * 请求会话标识,用来标识图形验证码属于哪个会话
+     * */
+    @Schema(description = "sessionId", required = true)
+    @NotBlank
+//    @Length(min = 32,max = 32)
+    private String sessionId;
+
+}

+ 28 - 0
novel-demo/src/main/java/com/sf/dto/resp/ImgVerifyCodeRespDto.java

@@ -0,0 +1,28 @@
+package com.sf.dto.resp;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * 图像验证码 响应DTO
+ * @author xiongxiaoyang
+ * @date 2022/5/18
+ */
+@Data
+@Builder
+public class ImgVerifyCodeRespDto {
+
+    /**
+     * 当前会话ID,用于标识改图形验证码属于哪个会话
+     * */
+    @Schema(description = "sessionId")
+    private String sessionId;
+
+    /**
+     * Base64 编码的验证码图片
+     * */
+    @Schema(description = "Base64 编码的验证码图片")
+    private String img;
+
+}

+ 28 - 0
novel-demo/src/main/java/com/sf/dto/resp/UserRegisterRespDto.java

@@ -0,0 +1,28 @@
+package com.sf.dto.resp;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 用户注册 响应DTO
+ * @author xiongxiaoyang
+ * @date 2022/5/17
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class UserRegisterRespDto {
+
+    @Schema(description = "用户ID")
+    private Long uid;
+
+    @Schema(description = "用户token")
+    private String token;
+
+    // 增加一个字段 来识别处理的类型 比如正确的是0  错误是的 1 2 3等
+    private Integer type;
+}

+ 186 - 0
novel-demo/src/main/java/com/sf/entity/UserInfo.java

@@ -0,0 +1,186 @@
+package com.sf.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 用户信息
+ * </p>
+ *
+ * @author baomidou
+ * @since 2024-06-05
+ */
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@TableName("user_info")
+public class UserInfo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 登录名
+     */
+    private String username;
+
+    /**
+     * 登录密码-加密
+     */
+    private String password;
+
+    /**
+     * 加密盐值
+     */
+    private String salt;
+
+    /**
+     * 昵称
+     */
+    private String nickName;
+
+    /**
+     * 用户头像
+     */
+    private String userPhoto;
+
+    /**
+     * 用户性别;0-男 1-女
+     */
+    private Byte userSex;
+
+    /**
+     * 账户余额
+     */
+    private Long accountBalance;
+
+    /**
+     * 用户状态;0-正常
+     */
+    private Byte status;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getSalt() {
+        return salt;
+    }
+
+    public void setSalt(String salt) {
+        this.salt = salt;
+    }
+
+    public String getNickName() {
+        return nickName;
+    }
+
+    public void setNickName(String nickName) {
+        this.nickName = nickName;
+    }
+
+    public String getUserPhoto() {
+        return userPhoto;
+    }
+
+    public void setUserPhoto(String userPhoto) {
+        this.userPhoto = userPhoto;
+    }
+
+    public Byte getUserSex() {
+        return userSex;
+    }
+
+    public void setUserSex(Byte userSex) {
+        this.userSex = userSex;
+    }
+
+    public Long getAccountBalance() {
+        return accountBalance;
+    }
+
+    public void setAccountBalance(Long accountBalance) {
+        this.accountBalance = accountBalance;
+    }
+
+    public Byte getStatus() {
+        return status;
+    }
+
+    public void setStatus(Byte status) {
+        this.status = status;
+    }
+
+    public LocalDateTime getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(LocalDateTime createTime) {
+        this.createTime = createTime;
+    }
+
+    public LocalDateTime getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(LocalDateTime updateTime) {
+        this.updateTime = updateTime;
+    }
+
+    @Override
+    public String toString() {
+        return "UserInfo{" +
+            "id = " + id +
+            ", username = " + username +
+            ", password = " + password +
+            ", salt = " + salt +
+            ", nickName = " + nickName +
+            ", userPhoto = " + userPhoto +
+            ", userSex = " + userSex +
+            ", accountBalance = " + accountBalance +
+            ", status = " + status +
+            ", createTime = " + createTime +
+            ", updateTime = " + updateTime +
+        "}";
+    }
+}

+ 16 - 0
novel-demo/src/main/java/com/sf/mapper/UserInfoMapper.java

@@ -0,0 +1,16 @@
+package com.sf.mapper;
+
+import com.sf.entity.UserInfo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 用户信息 Mapper 接口
+ * </p>
+ *
+ * @author baomidou
+ * @since 2024-06-05
+ */
+public interface UserInfoMapper extends BaseMapper<UserInfo> {
+
+}

+ 23 - 0
novel-demo/src/main/java/com/sf/service/IUserInfoService.java

@@ -0,0 +1,23 @@
+package com.sf.service;
+
+import com.sf.dto.req.UserRegisterReqDto;
+import com.sf.dto.resp.ImgVerifyCodeRespDto;
+import com.sf.dto.resp.UserRegisterRespDto;
+import com.sf.entity.UserInfo;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 用户信息 服务类
+ * </p>
+ *
+ * @author baomidou
+ * @since 2024-06-05
+ */
+public interface IUserInfoService extends IService<UserInfo> {
+
+    ImgVerifyCodeRespDto getImgVerifyCode();
+
+    // req -> request 请求  resp -> response 响应
+    UserRegisterRespDto register(UserRegisterReqDto userRegisterReqDto);
+}

+ 99 - 0
novel-demo/src/main/java/com/sf/service/impl/UserInfoServiceImpl.java

@@ -0,0 +1,99 @@
+package com.sf.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.sf.dto.req.UserRegisterReqDto;
+import com.sf.dto.resp.ImgVerifyCodeRespDto;
+import com.sf.dto.resp.UserRegisterRespDto;
+import com.sf.entity.UserInfo;
+import com.sf.mapper.UserInfoMapper;
+import com.sf.service.IUserInfoService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.sf.util.CaptchaUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.util.Pair;
+import org.springframework.stereotype.Service;
+import org.springframework.util.DigestUtils;
+
+import java.nio.charset.StandardCharsets;
+import java.time.LocalDateTime;
+import java.util.HashMap;
+
+/**
+ * <p>
+ * 用户信息 服务实现类
+ * </p>
+ *
+ * @author baomidou
+ * @since 2024-06-05
+ */
+@Service
+public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements IUserInfoService {
+
+    static HashMap<String, String> captcha = new HashMap<String, String>();
+
+    @Autowired
+    private UserInfoMapper userInfoMapper;
+
+
+    @Override
+    public ImgVerifyCodeRespDto getImgVerifyCode() {
+        Pair<String, String> pair = CaptchaUtils.getImageBase64();
+        // 使用sessionId来区分每次生成的不同的验证码
+        String sessionId = IdWorker.get32UUID();
+        // 将这个唯一的sessionId和code码关联 存储在容器中
+        // 将pair(成对的数据)中的第一个数据 和 sessionId存入map中
+        captcha.put(sessionId, pair.getFirst());
+        ImgVerifyCodeRespDto verifyCodeRespDto = ImgVerifyCodeRespDto.builder()
+                .sessionId(sessionId)
+                .img(pair.getSecond())   // 将hutool生成的base数据设置进去
+                .build();
+        return verifyCodeRespDto;
+    }
+
+    @Override
+    public UserRegisterRespDto register(UserRegisterReqDto reqDto) {
+        UserRegisterRespDto respDto = UserRegisterRespDto.builder().build();
+        // 判断验证码是否正确
+        String sessionId = reqDto.getSessionId();
+        // 获取验证码图片的正确结果
+        String resultCode = captcha.get(sessionId);
+        // 如果用户传进来的验证码 不准确  返回验证码错误
+        if (!reqDto.getVelCode().equals(resultCode)) {
+            // 用类型1 代表验证码错误
+            respDto.setType(1);
+            return respDto;
+        }
+
+        // 判断用户名是否被使用
+        // select count(*) from user_info where username = ''
+        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(UserInfo::getUsername, reqDto.getUsername());
+        Long count = userInfoMapper.selectCount(queryWrapper);
+        if (count == 1) {
+            // 用类型2 代表用户名已经存在
+            respDto.setType(2);
+            return respDto;
+        }
+
+        // 存储数据
+        byte[] bytes = reqDto.getPassword().getBytes(StandardCharsets.UTF_8);
+        UserInfo userInfo = UserInfo.builder()
+                .username(reqDto.getUsername())
+                .password(DigestUtils.md5DigestAsHex(bytes))  // 使用spring中的工具类进行加密
+                .nickName(reqDto.getUsername())
+                .salt("0")
+                .accountBalance(0L)
+                .status((byte)0)
+                .createTime(LocalDateTime.now())  // 把当前时间存储进去
+                .updateTime(LocalDateTime.now())
+                .build();
+        userInfoMapper.insert(userInfo);
+
+        respDto.setType(0);
+        // 在存入数据库后 获取生成的id
+        respDto.setUid(userInfo.getId());
+        respDto.setToken("token_" + userInfo.getId());
+        return respDto;
+    }
+}

+ 28 - 0
novel-demo/src/main/java/com/sf/util/CaptchaUtils.java

@@ -0,0 +1,28 @@
+package com.sf.util;
+
+import cn.hutool.captcha.CaptchaUtil;
+import cn.hutool.captcha.LineCaptcha;
+import cn.hutool.captcha.generator.RandomGenerator;
+import org.springframework.data.util.Pair;
+
+public class CaptchaUtils {
+
+    public static Pair<String, String> getImageBase64() {
+        // 随机生成器
+        // 参数对应  生成几位数字的验证码  设置宽高
+        RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4);
+        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(100, 38);
+        lineCaptcha.setGenerator(randomGenerator);
+
+        String code = lineCaptcha.getCode();
+        System.out.println("-----------------");
+        System.out.println(code);
+        // 图片数据 是由base64格式进行传输的
+        String imageBase64 = lineCaptcha.getImageBase64();
+        System.out.println(imageBase64);
+        System.out.println("-----------------");
+
+        Pair<String, String> pair = Pair.of(code, imageBase64);
+        return pair;
+    }
+}

+ 2 - 1
novel-demo/src/main/java/com/sf/util/GeneUtils.java

@@ -22,7 +22,8 @@ public class GeneUtils {
 //        list.add("news_info"); // 新闻列表
 //        list.add("news_content"); // 新闻内容表
 //        list.add("book_category"); // 书籍种类表
-        list.add("home_friend_link"); // 首页友情链接表
+//        list.add("home_friend_link"); // 首页友情链接表
+        list.add("user_info"); // 用户信息表
 
         // 快速生成器
         FastAutoGenerator.create("jdbc:mysql://localhost:3306/novel-cloud?useUnicode=true&characterEncoding=utf-8&allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=Asia/Shanghai",

+ 5 - 0
novel-demo/src/main/resources/mapper/UserInfoMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.sf.mapper.UserInfoMapper">
+
+</mapper>