好了,的所有的基础知识已经准备完毕了,现在开始制作引导页。这个引导页需要一个HTML文件,JS文件,一个CSS文件。在HBuilderX中根目录下添加“Guid.html”,在JS文件夹添加“myth.js”,在CSS文件夹下添加“myth.css”。

一、myth.js文件

该文件是个插件,对常用的操作进行了封装,本章节主要把该文件的框架搭建出来,随着开发的深入,会不断的完善这个js文件,最后它会成为一个丰富的插件,一遍以后使用。

(一)基本框架

  1. ; //JavaScript 弱语法的特点,如果前面刚好有个函数没有以";"结尾,那么可能会有语法错误
  2. var myth = (function(selector) {
  3. 'use strict';
  4. var _myth = function(selector) {
  5. };
  6. _myth.version = 'myth 1.0';
  7. return _myth;
  8. })(document);

上述代码就是基本的插件代码,前面的分号,可以解决插件与其它js合并时,别的代码可能会产生的错误问题。

“(function(){})()”这个结构表示立即执行第一个小括号内的函数;第二个小括号中的“document”作为参数传递给第一个小括号内的函数。

'use strict';

这行代码表示严格模式,顾名思义,严格模式就是使得 Javascript 在更严格的条件下运行,有助于更规范的开发。如果在语法检测时发现语法问题,则整个代码块失效,并导致一个语法异常。如果在运行期出现了违反严格模式的代码,则抛出执行异常。

二、myth.css文件

  1. @charset "utf-8";
  2. html {
  3. color: #333;
  4. background:#fff;
  5. -webkit-text-size-adjust: 100%;
  6. -ms-text-size-adjust: 100%;
  7. text-rendering: optimizelegibility;
  8. }
  9.  
  10. /* 统一内外边距*/
  11. body, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, textarea,
    p, blockquote, th, td, hr, button, article, aside, details, figcaption, figure, footer,
    header, menu, nav, section {
  12. margin:;
  13. padding:;
  14. }

三、index.html文件

首先在默认文档index.html中,填写代码实现:如果第一次启动将进入启动页“guid.html”,如果第二次启动直接进入程序主界面。其实这里的主界面就是“index.html”,的实现原理是这样的,webAPP启动时,启动页面不需要自动关闭,等待的主界面“index.html”逻辑顺序,数据执行完毕,如果第一次启动在“guid.html”关闭webAPP启动页面,如果不是第一次启动在“index.html”关闭webAPP启动页面。

第一步:“manifest.json”可视化界面关掉“自动关闭启动界面”,如图4-1所示。

图4-1  启动界面设置

第二步:myth.js代码补充。

  1. ; //JavaScript 弱语法的特点,如果前面刚好有个函数没有以";"结尾,那么可能会有语法错误
  2. var myth = (function(selector) {
  3. 'use strict';
  4. var _myth = function(selector) {
  5. //如果默认参数不设置,自动赋值document
  6. if (!selector) {
  7. selector = document;
  8. }
  9. //获取selector数据类型,代码后面序号1有详细用法解释
  10. var selectorType = typeof(selector);
  11. //根据selector数据类型,进行同操作,代码后面序号2有详细用法解释
  12. switch (selectorType) {
  13. case 'string'://如果是字符串类型,使用querySelectorAll获取selector对象,结果记录到reObj内
  14. var doms = document.querySelectorAll(selector);//通过该方法查找HMTL中select对象,代码后面序号2有详细用法解释
  15. //reObj是个数据对象目前设置两个属性dom这个是Javascript数据对象,length表示doms对象数量
  16. var reObj = {
  17. dom: doms,
  18. length: doms.length
  19. };
  20. break;
  21. case 'object'://如果是object类型,结果直接记录到reObj内
  22. var reObj = {
  23. dom: [selector],
  24. length: 1
  25. };
  26. break;
  27. default://除了上述两种类型外,返回null对象
  28. return null;
  29. }
  30. reObj.__proto__ = mythExtends;
  31. //__proto__:是一个对象拥有的内置属性,是JS内部使用寻找原型链的属性。可以理解为它是一个指针,
    //用于指向创建它的函数对象的原型对象prototype(即构造函数的prototype),简单理解为“为reObj
    //添加了一些扩展属性,myth(selector)选择对象后,可以进一步执行mythExtends中的方法。
  32. return reObj;
  33. };
    //myth(selector)对象的扩展方法
  34. var mythExtends = {
  35. /* dom 元素遍历 */
  36. each: function(callBack) {
  37. if (!callBack) {
  38. return;
  39. }
  40. for (var i = 0; i < this.length; i++) {
  41. this.dom[i].index = i;
  42. callBack(this.dom[i]);//返回每一个dom对象
  43. }
  44. },
  45. setWidth: function(swidth) {//设置myth(selector)对象宽度
  46. this.dom[0].style.width =swidth;
  47. },
  48. redWidth: function() {//获取myth(selector)对象宽度
  49. return this.dom[0].offsetWidth;
  50. },
  51. setHeight: function(sheight) {//设置myth(selector)对象高度
  52. this.dom[0].style.height =sheight;
  53. },
  54. redHeight: function() {//获取myth(selector)对象高度
  55. return this.dom[0].offsetHeight;
  56. }
  57. }
  58. _myth.version = 'myth 1.0';//设置版本
  59. _myth.plusReady = function(callBack) {//plusready是html5+ API,对这个方法进行了封装,以便调用,代码后面序号3有详细用法解释
  60. document.addEventListener('plusready', function() {
  61. if (callBack) {
  62. callBack();
  63. }
  64. });
  65. };
  66. _myth.readStorage = function(key) {//读取本地数据 代码后面序号4有详细用法解释
  67. return plus.storage.getItem(key)
  68. }
  69. _myth.wirteStorage = function(key, value) {//获取本地数据
  70. plus.storage.setItem(key, value);
  71. }
  72. _myth.open = function(winName, styles, extras) {//打开新界面。
  73. if (!window.plus) {//window.plus不为空,则替换当前网址
  74. location.href = winName;
  75. return;
  76. }
  77. if (!styles) {//窗口样式为空,进行初始设置
  78. styles = {};
  79. }
  80. var w = this.create(winName, styles, extras);//创建新窗口,并显示。
  81. plus.webview.show(w, 'slide-in-right');
  82. return w;
  83. };
  84. _myth.close = function(wId) {//关闭id为“wid”的窗口
  85. if (typeof(wId) == "undefined") {
  86. plus.webview.currentWebview().close();//关闭当前窗口
  87. } else {
  88. var w = plus.webview.getWebviewById(wId);
  89. if (w) {
  90. w.close();
  91. }
  92. }
  93. };
  94. _myth.create = function(winName, styles, extras) {//创建新窗口
  95. if (typeof(styles) == "undefined") {
  96. styles = {};
  97. }
  98. if (typeof(extras) == "undefined") {
  99. extras = {};
  100. }
  101. if (!styles.zindex) {
  102. styles.zindex = 10;
  103. }
  104. var w = plus.webview.getWebviewById(winName);//获取id为“winName”的窗口
  105. if (w) {
  106. return w;
  107. }
  108. w = plus.webview.create(winName, winName, styles, extras);//创建窗口
  109. return w;
  110. };
  111. _myth.winInfo = function() {//获取手机屏幕大小信息
  112. var winInfo = {//窗口基本信息,包括高度,宽度,纵向滚动距离
  113. height: 0,
  114. width: 0,
  115. scrollTop: 0
  116. };
  117. if (window.innerHeight) {//如果获取到浏览器窗口的视口的高度,则赋值给winInfo.height
  118. winInfo.height = window.innerHeight;
  119. } else if ((document.body) && (document.body.clientHeight)) {//获取不到浏览器的窗口的高度,能获取到到body则获取body高度,进行赋值操作。
  120. winInfo.height = document.body.clientHeight;
  121. }
  122. if (window.innerWidth) {//如果获取到浏览器窗口的视口的宽度,,则赋值给winInfo.width
  123. winInfo.width = window.innerWidth;
  124. } else if ((document.body) && (document.body.clientWidth)) {//获取不到浏览器的窗口的高度,能获取到到body则获取body宽度,进行赋值操作。
  125. winInfo.width = document.body.clientWidth;
  126. }
  127. if (document.documentElement && document.documentElement.scrollTop) {//获取纵向滚动距离
  128. winInfo.scrollTop = document.documentElement.scrollTop;
  129. } else if (document.body) {
  130. winInfo.scrollTop = document.body.scrollTop;
  131. }
  132. return winInfo;
  133. };
  134. return _myth;
  135. })(document);

1.Typeof用法详解:

typeof是一个运算符,typeof(表达式)表示对表达式做运算,情况如表4-1所示。

序号

返回值

说明

1

'undefined'

未定义的变量或值

2

'boolean'

布尔类型的变量或值

3

'string'

字符串类型的变量或值

4

'number'

数字类型的变量或值

5

'object'

对象类型的变量或值,或者null(这个是js历史遗留问题,将null作为object类型处理)

6

'function'

函数类型的变量或值

表4-1typeof返回数值类型

2.switch用法详解

switch 语句用于基于不同条件执行不同动作。语法结构如下:

switch(表达式n) {

case 1:

代码块

break;

case 2:

代码块

break;

default:

默认代码块

}

工作原理:首先设置表达式 n(通常是一个变量)。随后表达式的值会与结构中的每个 case 的值做比较。如果存在匹配,则与该 case 关联的代码块会被执行,其它不执行, break直接跳出switch。

3.plusready用法详解

plusready是html5+ API,在webapp开发中,若要使用HTML5+扩展api,必须等plusready事件发生后才能正常使用。

为了保证HTML5扩展API的有效调用,页面加载扩展API完成后会触发此事件。 通常应该在页面开始加载时监听此事件,当此事件触发后,就可以安全的调用HTML5扩展API。 如果应用使用多页面,每个都会收到此事件。

// 监听plusready事件 document.addEventListener("plusready", function(){

// 扩展API加载完毕,现在可以正常调用扩展API

// ...... }, false);

4.Storage用法详解

Storage模块管理应用本地数据存储区,用于应用数据的保存和读取,主要方法如表4-2所示。

序号

方法

说明

举例

1

getLength

获取应用存储区中保存的键值对的个数

plus.storage.getLength();

2

getItem

通过键(key)检索获取应用存储的值。key: ( DOMString ) 必选

plus.storage.getItem(key);

3

setItem

修改或添加键值(key-value)对数据到应用数据存储中。key: ( DOMString ) 必选 存储的键值

value:  DOMString ) 必选

存储的内容

void plus.storage.setItem(key, value);

4

removeItem

通过key值删除键值对存储的数据

void plus.storage.removeItem(key);

5

clear

清除应用所有的键值对存储数据

void plus.storage.clear();

表4-2 Storage用法介绍

第三步:“index.html”代码修改。在默认文档的基础上添加html代码,JavaScript代码完成需要的功能,具体代码如下:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
  6. <title></title>
  7. <link rel="stylesheet" type="text/css" href="css/myth.css"/>
  8. <script src="js/myth.js"></script>
  9. <script type="text/javascript">
  10. myth.plusReady(function() {
  11. var isguid = myth.readStorage('isguid');//获取本地存储key为"isguid"的数值
  12. if (isguid) {//如果存在说明不是第一次启动
  13. myth.closestartpage();//关闭启动页
  14. } else {//不存在,说明不是第一次启动
  15. myth.open('Guid.html', {background: 'transparent'}, {});//跳转到引导页
  16. }
  17. })
  18. </script>
  19. </head>
  20. <body>
  21. 编程之路
  22. </body>
  23. </html>

四、guid.html

本页面实现导航页,共四张图片,向做滑动,切换。最后一张向做滑动进入webApp住界面,单击按钮跳过,进入webApp住界面。最终效果如图4-2所示。

 

图4-2 导航页图片切换效果

第一步:对myth.css文件补充。

  1. /* 设置全屏 */
  2. .fullscreen{
  3. width:100%; height:100%; position: fixed; margin: 0px; top: 0px;left: 0px;
  4. }

  上述代码对页面容器进行全屏设置,position 属性规定元素的定位类型,取值如表4-3所示。

序号

取值

说明

1

absolute

生成绝对定位的元素,相对于 static 定位以外的第一个父元素进行定位。元素的位置通过 "left", "top", "right" 以及 "bottom" 属性进行规定。

2

fixed

生成绝对定位的元素,相对于浏览器窗口进行定位。元素的位置通过"left", "top", "right" 以及 "bottom" 属性进行规定。

3

relative

生成相对定位的元素,相对于其正常位置进行定位。因此,"left:20"会向元素的 LEFT 位置添加 20 像素。

4

static

默认值。没有定位,元素出现在正常的流中(忽略 top, bottom, left, right 或者 z-index 声明)。

5

inherit

规定应该从父元素继承 position 属性的值。

表4-3 CSS元素定位

第二步:guid.html中html代码补充。

  1. <div class="fullscreen">
  2. <!-- 定义一个DIV容器,全屏 -->
  3. <div class="guid-items" id="picbox">
  4. <!-- 定义一个存放图片容器,存放四张图片 -->
  5. <img src="img/Guid1.jpg" id="pic1" /><img src="img/Guid2.jpg" id="pic2" /><img src="img/Guid3.jpg" id="pic3" />
    <img src="img/Guid4.jpg" id="pic4" />
  6. </div>
  7. </div>
  8. <div id="GotuButton" onclick="CloseGuid()">跳过</div>
  9. <!-- 定义一个跳过按钮,单击跳出导航进入webApp主界面 -->

第三步:guid.html中引入myth.css,并补充样式。

  1. <link rel="stylesheet" type="text/css" href="css/myth.css" />
  2. <style type="text/css">
  3. .guid-items {
  4. /* 图片容器样式 */
  5. position: fixed;/* 生成绝对定位的元素,相对于浏览器窗口进行定位 */
  6. height: 100%;/* 容易高度100%,全屏 */
  7. }
  8. .guid-items img {/* 定义容器中的图片属性,所有外边距0,内边距同样为0 */
  9. margin: 0px;
  10. padding: 0px;
  11. }
  12. #GotuButton {/* 定义跳过按钮样式,宽50像素,,, */
  13. width: 50px;/* 宽50像素 */
  14. height: 50px;/* 高50像素 */
  15. position: fixed;/* 相对于浏览器窗口绝对定位 */
  16. z-index:;/* 堆叠顺序为10000,也就是让该按钮要浮于图片上方,可以让用户看到 */
  17. top: 50px;/* 距离上方50像素 */
  18. right: 20px;/* 距离右方20像素,也就是右上角显示 */
  19. background: #FF6600;/* 按钮背景色 */
  20. text-align: center;/* 按钮中文字水平居中对齐 */
  21. border-radius: 50px;/* 圆形按钮设置 */
  22. line-height: 50px;/* 行间距为50像素 */
    color: #FFFFFF;/* 按钮中文字颜色 */ }
    </style>

第四步:guid.html中引入myth.js,并编写JS代码。

  1. <script src="js/myth.js" type="text/javascript" charset="utf-8"></script>
  2. <script type="text/javascript">
  3. var wininfo = myth.winInfo();//获取手机信息
  4. var screenWidth = wininfo.width;//宽度
  5. var guidbox = myth("#picbox");//获取id为"picbox"对象
  6. guidbox.setWidth("400%");//设置id为"picbox"对象宽度400%,也就是4个屏幕的宽度,4张图片正好一排显示
  7. var zguidbox = guidbox.dom[0];//获取javascript对象
  8. myth("#picbox img").each(function(cObj) {//获取id为"picbox"对象下面的所有图片,并循环
  9. myth(cObj).setWidth('25%');//设置每张图片宽度为25%,正好是1个屏幕大小
  10. })
  11. var currentImg = 1;//当前屏幕显示图片序号
  12. var startX, endX;//定义开始手指按住屏幕x轴坐标,和手指离开屏幕x轴坐标
  13. var isPress = false;//判断手指是否按住屏幕
  14. var gundong=0;//手指按住屏幕后,滑动距离
  15. zguidbox.addEventListener("touchstart", function(e) {//监听手指按住屏幕事件
  16. isPress = true;//手指按钮变量设为true
  17. startX = e.touches[0].clientX;//记录手指按住坐标
  18. });
  19. zguidbox.addEventListener("touchmove", function(e) {//监听手指滑动事件
  20. if (isPress) {//判断是否按住住屏幕
  21. endX = e.touches[0].clientX;//记录滑动最后坐标
  22. gundong = startX - endX;//计算滑动距离
  23. if (gundong < 0) return;//滑动距离小于0,说明是向右滑动,不进行任何操作,直接退出
  24. var juli = -1 * (currentImg - 1) * screenWidth - gundong;//向左滑动时,计算图片需要滑动的距离
  25. zguidbox.style.transform = 'translate3d(' + juli + 'px, 0px, 0px)';//图片相应滑动
  26. }
  27. });
  28. zguidbox.addEventListener("touchend", function(e) {//监听手指离开屏幕事件
  29. if (gundong <= 0) return;//如果距离向左滑动,或未滑动直接退出
  30. if (gundong > 0) {//如果向右滑动
  31. var juli = -1 * currentImg * screenWidth;//计算滑动到相应序号图片的距离
  32. zguidbox.style.transform = 'translate3d(' + juli + 'px, 0px, 0px)';//图片滑动到相应图片
  33. zguidbox.style.transition = '300ms';//添加滑动时间,手指离开屏幕后,图片300毫秒,滑动到指定距离
  34. currentImg++;//当前显示图片序号加一
  35. if (currentImg == 5) {//如果是最后一张图片滑过
  36. myth.wirteStorage("isguid", "true");//本地存储key为"isguid"设置为true,说明已经第一次启动程序
  37. myth.close();//退出引导页
  38. }
  39. }
  40. isPress = false;//手指按住屏幕变量设置为false
  41. });
  42. function CloseGuid() {
  43. myth.wirteStorage('isguid',"true");//本地存储key为"isguid"设置为true,说明已经第一次启动程序
  44. myth.close();//退出引导页
  45. var isguid = myth.readStorage('isguid');//获取本地存储key为"isguid"的数值
  46. console.log(isguid);
  47. }
  48. </script>

五、调试

导航页,到目前为止已经全部编写完毕,下一步这个过程非常重要,就是对代码进行调试。在HBuilderX中调试代码有两种途径,一是真机调试,另一种就是模拟器调试,下面分别学习一下。

(一)真机调试

讲的手机与电脑连接,连接成功后,在HBuilderX状态栏中显示手机已连接上电脑,如图4-3所示。

图4-3 手机连接电脑状态显示

在HBuilderX上方的工具条中点击运行按钮,即可在手机上运行,底部的控制台会有数据显示,如图4-4所示,如果有错误也会在此显示相关数据,根据提示进行修改即可。

图4-4 控制台数据

(二)模拟器调试

我用的是“夜神模拟器”,这个模拟器从网上安装下载即可。然后,在HBuilderX菜单栏中“运行”→“运行到手机或模拟器”→“Android模拟器端口设置”,如图4-5所示。


图4-5 模拟器设置

在端口设置页面设置端口号“62001”即可,如图4-6所示,这样的模拟器调试页设置完毕。同样在在HBuilderX上方的工具条中点击运行按钮,即可在模拟器上运行,调试过程同真机。

图4-6 模拟器端口设置

常用的Android模拟器的端口如表4-4所示:

模拟器名称

连接默认端口

夜神安卓模拟器夜神安卓模拟器

62001

逍遥安卓模拟器逍遥安卓模拟器

21503

BlueStacks(蓝叠安卓模拟器)   雷电安卓模拟

5555

器雷电安卓模拟器

5555

天天安卓模拟器天天安卓模拟器

5037

网易MuMu(安卓模拟器)

7555

安卓模拟器大师安卓模拟器大师

54001

Genymotion

5555

表4-4 常用Android模拟器端口列表

导航页的开发--手机web app开发笔记的更多相关文章

  1. 手机web app开发笔记

    各位朋友好,最近自学开发了一个手机Web APP,“编程之路”,主要功能包括文章的展示,留言,注册登录,音乐播放等.为了记录学习心得,提高自己的编程水平,也许对其他朋友有点启发,特整理开发笔记如下. ...

  2. 微信公众平台开发:Web App开发入门

    WebApp与Native App有何区别呢?Native App:1.开发成本非常大.一般使用的开发语言为JAVA.C++.Objective-C.2.更新体验较差.同时也比较麻烦.每一次发布新的版 ...

  3. Native App开发 与Web App开发(原生与web开发优缺点)

    Native App开发 Native App开发即我们所称的传统APP开发模式(原生APP开发模式),该开发针对IOS.Android等不同的手机操作系统要采用不同的语言和框架进行开发,该模式通常是 ...

  4. manifest.json 解析--手机web app开发笔记(三-2)

    四.SDK配置和模块权限配置 SDK 就是 Software Development Kit 的缩写,中文意思就是“软件开发工具包”,也就是辅助开发某一类软件的相关文档.范例和工具的集合都可以叫做“S ...

  5. 默认文档接卸--手机web app开发笔记(二)

    首先我们启动HBuilderX2.0 ,界面如图2-1所示 图2-1 软件开发界面 单击“文件—新建—项目”,弹出新建项目管理界面,我们在里面进行了项目类型选择“5+APP”.项目名称填写“编程之路” ...

  6. manifest.json 解析--手机web app开发笔记(三-1)

    在HBuilderX生成的文档中,还有一个“manifest.json”,只要是创建“移动App”应用,都会在工程下生成这个文件,一看扩展名就知道他是一个json格式文件,文件文件根据w3c的weba ...

  7. 前端读者 | Web App开发入门

    本文来自互联网 自Iphone和Android这两个牛逼的手机操作系统发布以来,在互联网界从此就多了一个新的名词 - Web App(意为基于WEB形式的应用程序).业界关于Web App与Nativ ...

  8. 移动web app开发必备 - 异步队列 Deferred

    背景 移动web app开发,异步代码是时常的事,比如有常见的异步操作: Ajax(XMLHttpRequest) Image Tag,Script Tag,iframe(原理类似) setTimeo ...

  9. 移动web开发和移动app开发的区分

    1.移动web开发 这部分跟web前端开发差别不大,使用的技术都是html+css+js.区别为手机浏览器是webkit的天下,pc端是IE的天 下.手机网页可以理解成pc网页的缩小版加一些触摸特性. ...

随机推荐

  1. Python学习6——再谈抽象(面对对象编程)

    1.对象魔法 在面对对象编程中,术语对象大致意味着一系列数据(属性)以及一套访问和操作这些数据的方法. 使用对象而非全局变量以及函数的原因有多个,而最重要的好处不过以下几点: 多态:可对不同类型的对象 ...

  2. windows和linux下如何对拍

    对拍是各种计算机考试检查时必备工具,实际上十分强大,只要你的暴力没有写错就没有问题. 对拍的意思:(怎么有点语文课的意思雾) 对:看见'对'就可以知道有两个. 拍:就是把两个程序结果拍在一起,对照(有 ...

  3. python基础——列表(list)

    序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推. Python有6个序列的内置类型,但最常见的是列表和元组. 序列 ...

  4. 第三章 jsp数据交互(二)

    Application:当前服务器(可以包含多个会话):当服务器启动后就会创建一个application对象,被所有用户共享page.request.session.application四个作用域对 ...

  5. 前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

    一.ES6的Set.Map数据结构 Map.Set都是ES6新的数据结构,都是新的内置构造函数,也就是说typeof的结果,多了两个: Set 是不能重复的数组 Map 是可以任何东西当做键的对象 E ...

  6. 中间件增强框架之-CaptureFramework框架

    一.背景 应用服务监控是智能运维系统的重要组成部分.在UAV系统中,中间件增强框架(MOF)探针提供了应用画像及性能数据收集等功能,其中数据收集功能主要采集四类数据:实时数据.画像数据.调用链接数据生 ...

  7. Node.js 环境搭建及简单应用

    Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境.Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型.如果你想创建自己的服务,那么Node.js是一个非 ...

  8. 暴风雨中的 online :.net core 版博客站点遭遇的高并发问题进展

    今天暴风雨袭击了杭州,而昨天暴风雨(高并发问题)席卷了园子,留下一片狼藉. 在前天傍晚,我们进行了 .net core 版博客站点的第二次发布尝试,在发布后通过 kestrel 直接监听取代 ngin ...

  9. Leetcode solution 227: Basic Calculator II

    Problem Statement Implement a basic calculator to evaluate a simple expression string. The expressio ...

  10. sql存储过程中循环批量插入

    前几天有一个需求很头痛,部门是有上下级关系的,在给部门的经理赋予角色和权限的时候,通常我们都会认为假如经理A的部门是1,那么我给了他部门1 的管理权限,那么1的下级部门101,102,103 &quo ...