整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

3个编写JavaScript高质量代码的技巧,让你不

3个编写JavaScript高质量代码的技巧,让你不再996

文首发自「慕课网」,想了解更多IT干货内容,程序员圈内热闻,欢迎关注!

前段时间有一个叫做“人类高质量男性”的视频火了,相信很多同学都刷到过。所以今天给大家分享下,什么叫做“人类高质量代码”,哈哈,开个玩笑。

其实分享的都是一些自己平时总结的小技巧,算是抛砖引玉吧,希望能给大家带来一些启发和帮助。

如何编写出高质量的 JavaScript 代码?我个人认为,如果要编写出高质量的 JavaScript 代码,可以从以下三个方面去考虑。

分别是:易阅读的代码、高性能的代码、健壮性的代码。下面我将分别对这三个方面进行阐述。

易阅读的代码

首先说一下,代码是写给自己或团队成员看的,良好的阅读方式是编写高质量代码的前提条件。这里总结了四点具体操作方式分享给大家。

第一点:统一代码格式

不要一会这样写,一会那样写,尽量统一写法,下面举例。

// bad
function foo(x,y) {
  return {
    sum : x + y
  };
}
function bar(m, n){
  let ret=m*n
  return ret;
}
// good
function foo(x, y) {    //  适当的空格隔开,一般符号前不添加空格,符号后添加空格
  return {
    sum: x + y,         //  拖尾逗号是合法的,简化了对象和数组添加或删除元素
  }                     //  省略结束分号,当然需要知道如何规避风险
}
function bar(m, n) {
  let ret=m * n
  return ret
}

人为去约定代码格式,是很不方便的,所以可以借助一些工具进行自动格式转换。

第二点:去除魔术数字

魔术数字(magic number)是程式设计中所谓的直接写在程式码里的具体数值(如“10”“123”等以数字直接写出的值)。虽然程式作者写的时候自己能了解数值的意义,但对其他程式员而言,甚至作者本人经过一段时间后,都会很难理解这个数值的用途。

// bad
setTimeout(blastOff, 86400000)
document.onkeydown=function (ev) {
  if (ev.keyCode===13) {
    // todos
  }
}
// good
const MILLISECONDS_IN_A_DAY=86400000
const ENTER_KEY=13
setTimeout(blastOff, MILLISECONDS_IN_A_DAY)
document.onkeydown=function (ev) {
  if (ev.keyCode===ENTER_KEY) {
    // todos
  }
}

当然还有魔术字符串也是像上面一样去处理,上面代码中的常量命名推荐采用下划线命名的方式,其他如变量、函数等推荐用驼峰进行命名。

其实减少this的使用频率也是一样的道理,当代码中充斥着大量this的时候,我们往往很难知道它是谁,需要花费很多时间进行阅读。

// bad
class Foo {
    foo() {
        this.number=100
        this.el.onclick=function () {
            this.className="active"
        }
    }
}
// good
class Foo {
    foo() {
        let context=this
        context.number=100
        context.el.onclick=function () {
            let el=this
            el.className="active"
        }
    }
}

第三点:单一功能原则

无论是编写模块、类、还是函数都应该让他们各自都只有单一的功能,不要让他们做过多的事情,这样阅读起来会非常简单,扩展起来也会非常灵活。

// bad
function copy(obj, deep) {
  if (deep) {
    // 深拷贝
  } else {
    // 浅拷贝
  }
}
// good
function copy(obj) {
  // 浅拷贝
}
function deepCopy(obj) {
  // 深拷贝
}

第四点:减少嵌套层级

多层级的嵌套,如:条件嵌套、循环嵌套、回调嵌套等,对于代码阅读是非常不利的,所以应尽量减少嵌套的层级。

像解决条件嵌套的问题,一般可采用卫语句(guard clause)的方式提前返回,从而减少嵌套。

// bad
function foo() {
  let result
  if (isDead) {
    result=deadAmount()
  } else {
    if (isRet) {
      result=retAmount()
    } else {
      result=normalAmount()
    }
  }
  return result
}
// good
function foo() {
  if (isDead) {
    return deadAmount()
  }
  if (isRet) {
    return retAmount()
  }
  return normalAmount()
}

除了卫语句外,通过还可以采用短路运算、条件运算符等进行条件语句的改写。

// bad
function foo() {
    if (isOk) {
        todo()
    }
    let grade
    if (isAdmin) {
        grade=1
    } else {
        grade=0
    }
}
// good
function foo() {
    isOk && todo()                   // 短路运算
    let grade=isAdmin ? 1 : 0      // 条件运算符
}

像解决回调嵌套的问题,一般可采用“async/await”方式进行改写。

// bad
let fs=require("fs")
function init() {
  fs.mkdir(root, (err)=> {
    fs.mkdir(path.join(root, "public", "stylesheets"), (err)=> {
      fs.writeFile(
        path.join(root, "public", "stylesheets", "style.css"),
        "",
        function (err) {}
      )
    })
  })
}
init()
// good
let fs=require("fs").promises
async function init() {
  await fs.mkdir(root)
  await fs.mkdir(path.join(root, "public", "stylesheets"))
  await fs.writeFile(path.join(root, "public", "stylesheets", "style.css"), "")
}
init()

除了以上介绍的四点建议外,还有很多可以改善阅读体验的点,如:有效的注释、避免不同类型的比较、避免生涩的语法等等。

高性能的代码

在软件开发中,代码的性能高低会直接影响到产品的用户体验,所以高质量的代码必然是高性能的。这里总结了四点具体操作方式分享给大家。

提示:测试JavaScript平均耗时,可使用console.time()方法、JSBench.Me工具、performance工具等。

第一点:优化算法

递归是一种常见的算法,下面是用递归实现的“求阶乘”的操作。

// bad
function foo(n) {
  if (n===1) {
    return 1
  }
  return n * foo(n - 1)
}
foo(100)   // 平均耗时:0.47ms
// good
function foo(n, result=1) {
  if (n===1) {
    return result
  }
  return foo(n - 1, n * result)    // 这里尾调用优化
}
foo(100)   // 平均耗时:0.09ms

“尾调用”是一种可以重用栈帧的内存管理优化机制,即外部函数的返回值是一个内部函数的返回值。

第二点:使用内置方法

很多功能都可以采用JavaScript内置方法来解决,往往内置方法的底层实现是最优的,并且内置方法可在解释器中提前执行,所以执行效率非常高。

下面举例为:获取对象属性和值的复合数组形式。

// bad
let data={
  username: "leo",
  age: 20,
  gender: "male",
}
let result=[]
for (let attr in data) {
  result.push([attr, data[attr]])
}
console.log(result)
// good
let data={
  username: "leo",
  age: 20,
  gender: "male",
}
let result=Object.entries(data)
console.log(result)

第三点:减少作用域链查找

作用域链是作用域规则的实现,通过作用域链的实现,变量在它的作用域内可被访问,函数在它的作用域内可被调用。作用域链是一个只能单向访问的链表,这个链表上的每个节点就是执行上下文的变量对象(代码执行时就是活动对象),单向链表的头部(可被第一个访问的节点)始终都是当前正在被调用执行的函数的变量对象(活动对象),尾部始终是全局活动对象。

概念太复杂的话, 看下面这样一张图。

作用域链这个链表就是 3(头部:bar) -> 2(foo) -> 1(尾部:全局),所以查找变量的时候,应尽量在头部完成获取,这样就可以节省性能,具体对比如下。

// bad
function foo() {
  $("li").click(function () {     // 全局查找一次
    $("li").hide()                // 再次全局查找一次
    $(this).show()
  })
}
// good
function foo() {
  let $li=$("li")               // 减少下面$li的作用域查找层级      
  $li.click(function () {      
    $li.hide()               
    $(this).show()
  })
}

除了减少作用域链查找外,减少对象属性的查找也是一样的道理。

// bad
function isNull(arg) {
  return Object.prototype.toString.call(arg)==="[object Null]"
}
function isFunction(arg) {
  return Object.prototype.toString.call(arg)==="[object Function]"
}
// good
let toString=Object.prototype.toString
function isNull(arg) {
  return toString.call(arg)==="[object Null]"
}
function isFunction(arg) {
  return toString.call(arg)==="[object Function]"
}

第四点:避免做重复的代码

有时候编写程序时,会出现很多重复执行的代码,最好要避免做重复操作。先举一个简单的例子,通过循环找到第一个满足条件元素的索引位置。

// bad
let index=0
for (let i=0, len=li.length; i < len; i++) {
    if (li[i].dataset.switch==="on") {
        index=i
    }
}
// good
let index=0
for (let i=0, len=li.length; i < len; i++) {
    if (li[i].dataset.switch==="on") {
        index=i
        break        // 后面的循环没有意义,属于执行不必要的代码
    }
}

再来看一个计算“斐波那契数列”的案例。

// bad
function foo(n) {
  if (n < 3) {
    return 1
  }
  return foo(n - 1) + foo(n - 2)
}
foo(40)     // 平均耗时:1043ms
// good
let cache={}
function foo(n) {
  if (n < 3) {
    return 1
  }
  if (!cache[n]) {
    cache[n]=foo(n - 1) + foo(n - 2)
  }
  return cache[n]
}
foo(40)    // 平均耗时:0.16ms

这里把递归执行过的结果缓存到数组中,这样接下来重复的代码就可以直接读取缓存中的数据了,从而大幅度提升性能。

画叉号的部分就会走缓存,而不会重复执行计算。

除了以上介绍的四点建议外,还有很多可以改善代码性能的点,如:减少DOM操作、节流处理、事件委托等等。

健壮性的代码

所谓健壮性的代码,就是编写出来的代码,是可扩展、可维护、可测试的代码。这里总结了四点具体操作方式分享给大家。

第一点:使用新语法

很多新语法可弥补之前语法的BUG,让代码更加健壮,应对未来。

// bad
var a=1
isNaN(NaN)              // true
isNaN(undefined)        // true
// good
let a=1
Number.isNaN(NaN)       // true
Number.isNaN(undefined) // false
新语法还可以简化之前的操作,让代码结构更加清晰。
// bad
let user={ name: "james", age: 36 }
function foo() {
  let arg=arguments
  let name=user.name
  let age=user.age
}
// good
let user={ name: "james", age: 36 }
function foo(...arg) {          // 剩余参数
  let { name, age }=user      // 解构赋值
}

第二点:随时可扩展

由于产品需求总是会有新的变更,对软件的可扩展能力提出了很高要求,所以健壮的代码都是可以随时做出调整的代码。

// bad
function foo(animal) {
  if (animal==="dog" || animal==="cat") {
    // todos
  }
}
function bar(name, age) {}
bar("james", 36)
// good
function foo(animal) {
  const animals=["dog", "cat", "hamster", "turtle"]   // 可扩展匹配值
  if (animals.includes(animal)) {
    // todos
  }
}
function bar(options) {}    // 可扩展任意参数
bar({
  gender: "male",
  name: "james",
  age: 36,
})

第三点:避免副作用

当函数产生了除了“接收一个值并返回一个结果”之外的行为时,就产生了副作用。副作用不是说一定是有害的,但是如果在项目中没有节制的引起副作用,代码出错的可能性会非常大。

建议尽量不要去修改全局变量或可变对象,通过参数和return完成需求。让函数成为一种纯函数,这样也可使代码更容易被测试。

// bad
let fruits="Apple Banana"
function splitFruits() {
  fruits=fruits.split(" ")
}
function addItemToCart(cart, item) {
  cart.push({ item, data: Date.now() })
}
// good
let fruits="Apple Banana"
function splitFruits(fruits) {    
  return fruits.split(" ")
}
function addItemToCart(cart, item) {
  return [...cart, { item, data: Date.now() }]
}

第四点:整合逻辑关注点

当项目过于复杂的时候,经常会把各种逻辑混在一起,对后续扩展非常不利,而且还影响对代码的理解。所以尽量把相关的逻辑抽离到一起,进行集中式的管理。像React中的hooks,Vue3中的Composition API都是采用这样的思想。

// bad
export default {
  name: 'App',
  data(){
    return {
      searchHot: [],
      searchSuggest: [],
      searchHistory: [],
    },
    mounted() {
      // todo hot
      
      // todo history
    },
    methods: {
      handleSearchSuggest(){
        // todo suggest
      },
      handleSearchHistory(){
        // todo history
      }
    }
  }
}
// good
export default {
  name: "App",
  setup() {
    let { searchHot }=useSearchHot()
    let { searchSuggest, handleSearchSuggest }=useSearchSuggest()
    let { searchHistory, handleSearchHistory }=useSearchHistory()
    return {
      searchHot,
      searchSuggest,
      searchHistory,
      handleSearchSuggest,
      handleSearchHistory,
    }
  }
}
function useSearchHot() {
  // todo hot
}
function useSearchSuggest() {
  // todo suggest
}
function useSearchHistory() {
  // todo history
}

除了以上介绍的四点建议外,还有很多可以改善代码健壮性的点,如:异常处理、单元测试、使用TS替换JS等等。

最后总结一下,如何编写高质量JavaScript代码:

欢迎关注「慕课网」,发现更多IT圈优质内容,分享干货知识,帮助你成为更好的程序员!

者| 慕课网精英讲师 西门老舅

本文首发自「慕课网」,想了解更多IT干货内容,程序员圈内热闻,欢迎关注!

前段时间有一个叫做“人类高质量男性”的视频火了,相信很多同学都刷到过。所以今天给大家分享下,什么叫做“人类高质量代码”,哈哈,开个玩笑。

其实分享的都是一些自己平时总结的小技巧,算是抛砖引玉吧,希望能给大家带来一些启发和帮助。

如何编写出高质量的 JavaScript 代码?我个人认为,如果要编写出高质量的 JavaScript 代码,可以从以下三个方面去考虑。

分别是:易阅读的代码高性能的代码健壮性的代码。下面我将分别对这三个方面进行阐述。

易阅读的代码

首先说一下,代码是写给自己或团队成员看的,良好的阅读方式是编写高质量代码的前提条件。这里总结了四点具体操作方式分享给大家。

第一点:统一代码格式

不要一会这样写,一会那样写,尽量统一写法,下面举例。

// bad function foo(x,y) { return {     sum : x + y   }; } function bar(m, n){ let ret=m*n   return ret; } // good function foo(x, y) { //  适当的空格隔开,一般符号前不添加空格,符号后添加空格 return {     sum: x + y, //  拖尾逗号是合法的,简化了对象和数组添加或删除元素 } //  省略结束分号,当然需要知道如何规避风险 } function bar(m, n) { let ret=m * n   return ret }

人为去约定代码格式,是很不方便的,所以可以借助一些工具进行自动格式转换,如:prettier 插件(https://prettier.io/)。

第二点:去除魔术数字

魔术数字(magic number)是程式设计中所谓的直接写在程式码里的具体数值(如“10”“123”等以数字直接写出的值)。虽然程式作者写的时候自己能了解数值的意义,但对其他程式员而言,甚至作者本人经过一段时间后,都会很难理解这个数值的用途。

// bad setTimeout(blastOff, 86400000) document.onkeydown=function (ev) { if (ev.keyCode===13) { // todos } } // good const MILLISECONDS_IN_A_DAY=86400000 const ENTER_KEY=13 setTimeout(blastOff, MILLISECONDS_IN_A_DAY) document.onkeydown=function (ev) { if (ev.keyCode===ENTER_KEY) { // todos } }

当然还有魔术字符串也是像上面一样去处理,上面代码中的常量命名推荐采用下划线命名的方式,其他如变量、函数等推荐用驼峰进行命名。

其实减少this的使用频率也是一样的道理,当代码中充斥着大量this的时候,我们往往很难知道它是谁,需要花费很多时间进行阅读。

// bad class Foo { foo() { this.number=100 this.el.onclick=function () { this.className="active" } } } // good class Foo { foo() { let context=this         context.number=100         context.el.onclick=function () { let el=this             el.className="active" } } }

第三点:单一功能原则

无论是编写模块、类、还是函数都应该让他们各自都只有单一的功能,不要让他们做过多的事情,这样阅读起来会非常简单,扩展起来也会非常灵活。

// bad function copy(obj, deep) { if (deep) { // 深拷贝 } else { // 浅拷贝 } } // good function copy(obj) { // 浅拷贝 } function deepCopy(obj) { // 深拷贝 }

第四点:减少嵌套层级

多层级的嵌套,如:条件嵌套、循环嵌套、回调嵌套等,对于代码阅读是非常不利的,所以应尽量减少嵌套的层级。

像解决条件嵌套的问题,一般可采用卫语句(guard clause)的方式提前返回,从而减少嵌套。

// bad function foo() { let result   if (isDead) {     result=deadAmount() } else { if (isRet) {       result=retAmount() } else {       result=normalAmount() } } return result } // good function foo() { if (isDead) { return deadAmount() } if (isRet) { return retAmount() } return normalAmount() }

除了卫语句外,通过还可以采用短路运算、条件运算符等进行条件语句的改写。

// bad function foo() { if (isOk) { todo() } let grade     if (isAdmin) {         grade=1 } else {         grade=0 } } // good function foo() {     isOk && todo() // 短路运算 let grade=isAdmin ? 1 : 0 // 条件运算符 }

像解决回调嵌套的问题,一般可采用“async/await”方式进行改写。

// bad let fs=require("fs") function init() {   fs.mkdir(root, (err)=> {     fs.mkdir(path.join(root, "public", "stylesheets"), (err)=> {       fs.writeFile(         path.join(root, "public", "stylesheets", "style.css"), "", function (err) {} ) }) }) } init() // good let fs=require("fs").promises async function init() { await fs.mkdir(root) await fs.mkdir(path.join(root, "public", "stylesheets")) await fs.writeFile(path.join(root, "public", "stylesheets", "style.css"), "") } init()

除了以上介绍的四点建议外,还有很多可以改善阅读体验的点,如:有效的注释、避免不同类型的比较、避免生涩的语法等等。

高性能的代码

在软件开发中,代码的性能高低会直接影响到产品的用户体验,所以高质量的代码必然是高性能的。这里总结了四点具体操作方式分享给大家。

提示:测试JavaScript平均耗时,可使用console.time()方法、http://JSBench.Me工具、performance工具等。

第一点:优化算法

递归是一种常见的算法,下面是用递归实现的“求阶乘”的操作。

// bad function foo(n) { if (n===1) { return 1 } return n * foo(n - 1) } foo(100) // 平均耗时:0.47ms // good function foo(n, result=1) { if (n===1) { return result   } return foo(n - 1, n * result) // 这里尾调用优化 } foo(100) // 平均耗时:0.09ms

“尾调用”是一种可以重用栈帧的内存管理优化机制,即外部函数的返回值是一个内部函数的返回值。

第二点:使用内置方法

很多功能都可以采用JavaScript内置方法来解决,往往内置方法的底层实现是最优的,并且内置方法可在解释器中提前执行,所以执行效率非常高。

下面举例为:获取对象属性和值的复合数组形式。

// bad let data={   username: "leo",   age: 20,   gender: "male", } let result=[] for (let attr in data) {   result.push([attr, data[attr]]) } console.log(result) // good let data={   username: "leo",   age: 20,   gender: "male", } let result=Object.entries(data) console.log(result)

第三点:减少作用域链查找

作用域链是作用域规则的实现,通过作用域链的实现,变量在它的作用域内可被访问,函数在它的作用域内可被调用。作用域链是一个只能单向访问的链表,这个链表上的每个节点就是执行上下文的变量对象(代码执行时就是活动对象),单向链表的头部(可被第一个访问的节点)始终都是当前正在被调用执行的函数的变量对象(活动对象),尾部始终是全局活动对象。

概念太复杂的话, 看下面这样一张图。

作用域链这个链表就是 3(头部:bar) -> 2(foo) -> 1(尾部:全局),所以查找变量的时候,应尽量在头部完成获取,这样就可以节省性能,具体对比如下。

// bad function foo() { $("li").click(function () { // 全局查找一次 $("li").hide() // 再次全局查找一次 $(this).show() }) } // good function foo() { let $li=$("li") // 减少下面$li的作用域查找层级         $li.click(function () {           $li.hide() $(this).show() }) }

除了减少作用域链查找外,减少对象属性的查找也是一样的道理。

// bad function isNull(arg) { return Object.prototype.toString.call(arg)==="[object Null]" } function isFunction(arg) { return Object.prototype.toString.call(arg)==="[object Function]" } // good let toString=Object.prototype.toString function isNull(arg) { return toString.call(arg)==="[object Null]" } function isFunction(arg) { return toString.call(arg)==="[object Function]" }

第四点:避免做重复的代码

有时候编写程序时,会出现很多重复执行的代码,最好要避免做重复操作。先举一个简单的例子,通过循环找到第一个满足条件元素的索引位置。

// bad let index=0 for (let i=0, len=li.length; i < len; i++) { if (li[i].dataset.switch==="on") {         index=i     } } // good let index=0 for (let i=0, len=li.length; i < len; i++) { if (li[i].dataset.switch==="on") {         index=i         break // 后面的循环没有意义,属于执行不必要的代码 } }

再来看一个计算“斐波那契数列”的案例。

// bad function foo(n) { if (n < 3) { return 1 } return foo(n - 1) + foo(n - 2) } foo(40) // 平均耗时:1043ms // good let cache={} function foo(n) { if (n < 3) { return 1 } if (!cache[n]) {     cache[n]=foo(n - 1) + foo(n - 2) } return cache[n] } foo(40) // 平均耗时:0.16ms

这里把递归执行过的结果缓存到数组中,这样接下来重复的代码就可以直接读取缓存中的数据了,从而大幅度提升性能。


画叉号的部分就会走缓存,而不会重复执行计算。

除了以上介绍的四点建议外,还有很多可以改善代码性能的点,如:减少DOM操作、节流处理、事件委托等等。

健壮性的代码

所谓健壮性的代码,就是编写出来的代码,是可扩展、可维护、可测试的代码。这里总结了四点具体操作方式分享给大家。

第一点:使用新语法

很多新语法可弥补之前语法的BUG,让代码更加健壮,应对未来。

// bad var a=1 isNaN(NaN) // true isNaN(undefined) // true // good let a=1 Number.isNaN(NaN) // true Number.isNaN(undefined) // false

新语法还可以简化之前的操作,让代码结构更加清晰。

// bad let user={ name: "james", age: 36 } function foo() { let arg=arguments   let name=user.name   let age=user.age } // good let user={ name: "james", age: 36 } function foo(...arg) { // 剩余参数 let { name, age }=user      // 解构赋值 }

第二点:随时可扩展

由于产品需求总是会有新的变更,对软件的可扩展能力提出了很高要求,所以健壮的代码都是可以随时做出调整的代码。

// bad function foo(animal) { if (animal==="dog" || animal==="cat") { // todos } } function bar(name, age) {} bar("james", 36) // good function foo(animal) { const animals=["dog", "cat", "hamster", "turtle"] // 可扩展匹配值 if (animals.includes(animal)) { // todos } } function bar(options) {} // 可扩展任意参数 bar({   gender: "male",   name: "james",   age: 36, })

第三点:避免副作用

当函数产生了除了“接收一个值并返回一个结果”之外的行为时,就产生了副作用。副作用不是说一定是有害的,但是如果在项目中没有节制的引起副作用,代码出错的可能性会非常大。

建议尽量不要去修改全局变量或可变对象,通过参数和return完成需求。让函数成为一种纯函数,这样也可使代码更容易被测试。

// bad let fruits="Apple Banana" function splitFruits() {   fruits=fruits.split(" ") } function addItemToCart(cart, item) {   cart.push({ item, data: Date.now() }) } // good let fruits="Apple Banana" function splitFruits(fruits) { return fruits.split(" ") } function addItemToCart(cart, item) { return [...cart, { item, data: Date.now() }] }

第四点:整合逻辑关注点

当项目过于复杂的时候,经常会把各种逻辑混在一起,对后续扩展非常不利,而且还影响对代码的理解。所以尽量把相关的逻辑抽离到一起,进行集中式的管理。像React中的hooks,Vue3中的Composition API都是采用这样的思想。

// bad export default {   name: 'App', data(){ return {       searchHot: [],       searchSuggest: [],       searchHistory: [], }, mounted() { // todo hot // todo history },     methods: { handleSearchSuggest(){ // todo suggest }, handleSearchHistory(){ // todo history } } } } // good export default {   name: "App", setup() { let { searchHot }=useSearchHot() let { searchSuggest, handleSearchSuggest }=useSearchSuggest() let { searchHistory, handleSearchHistory }=useSearchHistory() return {       searchHot,       searchSuggest,       searchHistory,       handleSearchSuggest,       handleSearchHistory, } } } function useSearchHot() { // todo hot } function useSearchSuggest() { // todo suggest } function useSearchHistory() { // todo history }

除了以上介绍的四点建议外,还有很多可以改善代码健壮性的点,如:异常处理、单元测试、使用TS替换JS等等。

最后总结一下,如何编写高质量JavaScript代码:

神秘彩蛋

根据上面介绍的原则,用JavaScrpt语言,编写了一个简单版本的“俄罗斯方块”小游戏,作为神秘彩蛋送给大家。哪里写的不好的地方,还希望大家提出指正。

欢迎关注「慕课网」,发现更多IT圈优质内容,分享干货知识,帮助你成为更好的程序员!

目 录

1.账号注册

2.案时常见问题

3.交费时常见问题

4.系统功能介绍


1.账号注册


1.1律师注册不通过的原因

1.2当事人注册方式有哪些

1.3其他账号问题


1.1律师注册不通过的原因

如果是山东省内律师且执业时间比较早,可以尝试一下使用执业证号作为用户名,身份证号后8位作为密码,直接登陆山东法院电子诉讼服务平台。

如果能登陆成功,系统右上角【设置】或者【个人中心】里更新一下个人资料尤其是联系电话,案件推送短信才能发到您现在的手机上。

如果确实没有诉讼服务平台律师账号,请点击登陆页面【律师注册】按钮去注册一个律师账号。

如果注册律师账号收到短信:审核没有通过。请按照如下提示操作:

第一步 :让律所管理员登录“最高院人民法院律师服务平台http://lsfw.court.gov.cn/lsxxgl/,将您的律师资料维护到最高律师服务平台中。其中【律师姓名】、【性别】、【民族】、【身份证号】、【执业证号】、【执业证取得日期】、【资格证号】、【资格证取得日期】、【执业开始日期】、【手机号码】、【所属律所名称】这几个关键信息必须填写,并上传相关律师资料。

第二步 :最高院律师信息维护完毕之后的12-24小时之后,回到山东法院电子诉讼服务平台律师注册页面https://sd12368.gov.cn/dzssfw/tLsfwLsxxDjOut/add,请同时打开最高院律师服务平台您的个人资料页面,山东法院电子诉讼服务平台律师注册页面。山东注册所有需要填写的信息不要手动录入,直接从最高院里复制出来,粘贴到山东这边,然后提交,即可审核通过。

备注:如果律所管理员对于如何登陆最高院律师服务平台存在疑问,或者没有律所管理员账号密码、密码不正确,请律师事务所负责人联系 010-67553422, 提供【事务所名称】、【事务所执业许可证号】、【律所负责人姓名】、【律师负责人手机号码】、 【律所负责人执业证号】、【省份】等信息统一进行添加。

1.2当事人注册方式有哪些

方式一:诉讼服务平台电脑端注册

点击“当事人注册”,进入当事人用户注册页面。其中*字段是必填信息。

身份证号即为当事人的登录账号。提交注册信息后,电子诉讼服务平台通过身份证号、姓名去最高公民库里校验当事人身份。校验通过则发送短信告知注册信息通过审核,可以登录系统;校验失败则短信通知注册失败,需要核对资料后重新注册。

方式二:山东移动微法院小程序注册

手机微信搜索【山东移动微法院】小程序,在手机端实名认证,人脸识别认证(手机比较老的话采用唇语识别)。

如果您之前从来没使用过山东法院电子诉讼服务平台和山东移动微法院,那么会自动生成账号,并给您发送短信——【您的注册信息通过审核,请用身份证作为用户名进行登录(密码是身份证后8位),祝您生活愉快!】,该账号还可以用来登陆山东法院电子诉讼服务平台。

如果您之前在山东法院电子诉讼服务平台已经有账号,只是第一次使用山东移动微法院,那么微法院认证通过之后,会自动绑定您的诉讼服务平台账号,不会额外再生成账号,并给您发送短信——【您已注册过当事人信息,不要重复注册!祝您生活愉快!身份证号码为370XXXXX】。

当事人注册不通过的原因

如果当事人在诉讼服务平台注册未通过原因:1.身份证件已注销,2.信息变更3.人员特殊身份(涉密)4.注册时名字或身份证号填写错误

解决办法:一般是当事人自己把注册信息填错了,尤其是姓名。核对身份证号和姓名后重新注册一次。

如果当事人在山东移动微法院上实名认证不通过:

解决办法:长按或者拖动微信最上面山东移动微法院小程序,删除小程序,然后关闭掉微信进程。重新打开微信并搜索山东移动微法院,重新认证一次。如果还是不行,那只能在诉讼服务平台上注册了。有些手机、微信就是不支持人脸识别。

微法院人脸认证不通过

微信最上面长按或者拖动山东移动微法院小程序,删除小程序,然后关闭掉微信进程。重新打开微信并搜索山东移动微法院,重新认证一次。如果还是不行,那只能去电脑端注册了。有些手机微信就是不支持(比如一直人脸识别失败或者提示光线太亮),因为人脸识别使用腾讯生物识别高级,进入人脸识别场景后,代码方面就没办法控制了,因为没有修改权限。

1.3其他账号问题

1.法律工作者和实习律师目前只能点击【当事人注册】按钮,使用本人身份信息和手机号注册一个账号,然后在该账号下代理不同当事人的案件。

2.山东法院电子诉讼服务平台如果立保全类的案子,被告的电话一定不要填写!

注册时为什么提示手机号码已存在

出现这种情况,是您的手机号码借给别人注册过。如果确定没有借给别人使用过,那基本说明您在诉讼服务平台已有账号。

可以尝试使用执业证号或者身份证号直接登陆诉讼服务平台。如果提示您“密码错误”,点击登陆页面“立即登录”按钮上方的“忘记密码”,重置一个新的登陆密码即可。

手机号借给别人使用过如何解绑

如果别人注册账号时使用过您的手机号,那么您自己再次注册时就会提示“手机号码已经注册”,常见于法律工作者和律师用自己手机号给当事人注册账号。

解决办法是:登陆使用您手机号的那个人的账号,系统右上角【个人中心】里把手机号更改为那个人自己的手机号,您自己的手机号就释放出来了,就可以注册账号了。

实习律师如何注册

实习律师目前只能点击【当事人注册】按钮,使用本人身份信息和手机号注册一个账号,然后在该账号下代理不同当事人的案件。

注册步骤见:诉讼服务平台电脑端注册

法律工作者如何注册

法律工作者目前只能点击【当事人注册】按钮,使用本人身份信息和手机号注册一个账号,然后在该账号下代理不同当事人的案件。

诉讼服务平台会定期从司法局获取法律工作者信息,更新法律工作者的账号,更新完毕给账号绑定的手机号发送如下短信进行说明:

你好,您在电子诉讼服务平台注册的账号已经由当事人角色更改为法律工作者角色,账号由身份证号改成法律工作者执业证号,密码不变。

注册步骤见:诉讼服务平台电脑端注册

原告是公司该如何注册账号

公司肯定委托了某个人来进行立案,比如律师或者公司员工。如果是律师,那么直接使用律师账号去立案,如果委托了某个公司员工,用此人自己的个人信息注册一个当事人角色的账号,然后立案的时候原告录入公司信息,上传案件材料的时候需要提交委托代理手续,证明您与公司之间的关系,比如劳动合同、公司授权委托书等。

注册步骤见:诉讼服务平台电脑端注册

案件相关通知短信发给谁

诉讼服务平台案件相关通知短信尤其催费短信是发送给该案件立案账号绑定的手机号上。

如果案件是用当事人自己的账号立的,账号绑定的手机号是当事人自己的,那么通知短信就发送给当事人,如果这个案件是律师账号帮当事人立的。律师账号绑定的是律师自己的手机号,那么短信是发到律师手机上。如果立案账号未绑定任何手机号,则案件推送短信不会发送给任何人。

所以当您更换手机号后,请及时在系统右上角“个人信息”里把手机号更改为您在用的手机号。

如何重置登陆密码

点击登陆页面的“忘记密码”,进入密码重置页面:

输入页面信息点击“确定”即可完成密码找回。

如果长时间收不到验证码,那么基本上证明您之前在诉讼服务平台注册的手机号不是您目前在用的手机号,或者从律协、司法厅那边同步过来的律师、法律工作者资料里电话是空的或者是固话。只能提供您的执业证、身份证、本人手持身份证照片,诉讼服务平台后后台给您重置密码。


2、立案时常见问题



2.1立案短信系统发送成功但是立案人收不到

2.2新版老版诉讼服务平台都可以使用吗

2.3哪些案件能网上立案

2.4案件登记号如何获取

2.5民事、行政上诉时为什么原审案件查不到

2.6民事、行政上诉时为什么原审案件前面小圆圈是灰色条,无法选择

2.7民事、行政上诉时为什么当事人是灰色的,无法选择

2.8诉中保全时为什么选不到案件

2.9网上阅卷如何使用

2.10缴费人退费人信息为什么下拉列表是空的

2.11手机端和电脑端案件为什么不同步

2.12材料格式都支持哪些

2.13没有中国大陆身份证号如何立案

2.1立案短信系统发送成功但是立案人收不到

对于回执成功但是短信未收到的情况,运营商的提供的解释如下:

如出现回执成功,但是用户反馈接收不到,基本属于手机终端问题,我们建议:

1.建议用户查看下手机目前接收状态是不是正常(如信号差、不稳定等) 2.长时间不关机,需要关机重启(手机处理程序较多,长期不关机可能会干扰信息处理) 3.双卡双待的手机,将双卡互换尝试一下 4.检查收件箱是否已满,删除一些短信 5.检查手机是否有拦截软件

2.2新版老版诉讼服务平台都可以使用吗

新版诉讼服务平台(https://sd12368.gov.cn/)老版诉讼服务平台(http://lsfwpt.sdcourt.gov.cn:7865/dzssfwl/lawyer/login.jspx)并行使用,都可以进行立案等操作。

2.3哪些案件能网上立案

现在山东法院电子诉讼服务平台能立的案件是:

道交案件。

民事:民商事一审, 民事上诉(民商事一审上诉、民撤上诉), 民事申请再审审查(内网出民申案号), 民事特殊程序(特别程序监督内网对应民特监案字,其余13种特殊程序内网对应民特案字), 管辖异议, 管辖异议上诉。

行政:行政一审, 行政上诉(行政一审上诉、行赔初上诉), 行政申请再审审查(内网出行申案号)。

刑事:刑事自诉。

保全:诉前保全(内网出财保案号)、诉中保全。

执行:首次执行、执行异议、执行复议(首次执行和执复,先进分调裁再到通达海)。

注:外网的申请再审立案,内网审批出民申、行申字号;民再、行再案号的网上立案以及上诉暂时只能线下立案;民撤、行赔初目前只能网上上诉,但不能网上立案。

国家赔偿等赔字号案件、民催、民督暂时不能网上立案。

2.4案件登记号如何获取

诉讼服务平台的案件登记号在原告受理通知书、被告应诉通知书的右上角。

法官可以在云平台相应案件-送达信息-打印文书里找找。?没有登记号找东软工程师查找(在审判系统立案过的就可以查询的到)。

2.5民事、行政上诉时为什么原审案件查不到

管辖异议上诉的所有案件信息都需手动录入。民事和行政上诉,根据案号和登记号可以自动回填原审案件信息,无需手动录入原审信息。

民事、行政上诉时的原审案件是东软公司传给诉讼服务平台的,只推送结案日期在近两年的案件,包括线上立的案件和线下立的案件。

使用当事人信息查询不到案件的时候,再使用案号和登记号查询一下,推荐使用案号和登记号查询。

如果案号、登记号录入无误还是查不到案件,请联系法院核查一下案件在办案系统里是否报结,填写的结案时间是否在近两年内(当前时间往前推两年)。如果结案时间在两年内,但是诉讼服务平台还是查不到案件请联系东软公司处理,诉讼服务平台10分钟后就可以上诉了。

2.6民事、行政上诉时为什么原审案件前面小圆圈是灰色条,无法选择

说明该案件您之前在上诉的过程中退出了立案页面。请到我的案件中找到该案件,点击“编辑”按钮继续您的上诉流程。或者将该案件点击“删除”,然后重新去系统首页“上诉立案申请”下面的具体上诉通道里从头开始您的上诉流程。

2.7民事、行政上诉时为什么当事人是灰色的,无法选择

上诉人是灰色的,说明他已经上诉过该案件,不能重复上诉。案件状态可能是“保存”, 也可能是“已提交”。

上诉人是灰色的,说明他已经上诉过该案件,不能重复上诉。案件状态可能是“保存”, 也可能是“已提交”。

如果案件已经提交了,除非法官审核意见是“审核不通过”,否则您是无法对同一个案件再次上诉的。

2.8诉中保全时为什么选不到案件

立诉中保全案件时,提供了两种查询待保全案件的方式:

1、点击“案件选择”按钮弹出案号查询页面,弹出的案件是当前登陆账号之前在电子诉讼服务平台、一体机、山东移动微法院等线上立的已出案号且已经到交费阶段及交费成功的案件,暂时不包含线下立的案件。

2、鉴于第一种查询方式存在制约:即无法跨账号保全,也不能对线下立的案件进行保全,因为查不到案件。所以提供第二种查询方式:录入案号和登记号进行保全,就突破了账号限制,也可以对线下立的案件进行保全。

2.9网上阅卷如何使用

诉讼服务平台的【网上阅卷(当事人)】挂的是东软的阅卷链接,点击网上阅卷有提示说明、右上角也有帮助文档。

1、“我的相关案件”模块:该模块数据是由系统自动推送的民事一审未结案件的随案卷宗。

2、“卷宗借阅”模块:案件结案后若需查询电子档案的正卷,在此模块进行申请。

3、“卷宗查看”模块:卷宗借阅申请法官审批后在此模块进行电子档案的浏览。

4、详细操作请查看系统右上角的“使用帮助”。

微法院网上阅卷查看的是结案案件的归档卷宗。

2.10缴费人退费人信息为什么下拉列表是空的

可能是您没有录入原告。交费人退费人下拉列表展示的是您填写的原告。如果您已经录入了原告,点击原告当事人后面的“修改”,重新保存一遍您的原告,那么交费人退费人下拉列表就可以选择了。

2.11手机端和电脑端案件为什么不同步

手机端和电脑端案件是同步的。如果不同步,很大可能是立案人账号有两个。A账号立的案子在B账号上查看肯定是查不到的,造成案件不同步的假象。

2.12材料格式都支持哪些

为预防新版勒索病毒,应省院要求,山东法院电子诉讼服务平台上传的案件材料格式,暂时支持图片或者pdf。

2.13没有中国大陆身份证号如何立案

原告是无名氏没有身份证号码、港澳台或者外国人,则无法通过山东法院电子诉讼服务平台的用户注册,因为没法通过中国大陆公民认证。


3、交费时常见问题


3.1案件审核同意了为什么没有交费通道

3.2交费时为什么提示交费人不是原告

3.3审判系统在哪儿查看诉讼费交纳情况



3.1案件审核同意了为什么没有交费通道

案件审核同意之后,立案人账号绑定的手机号会收到短信提醒,告知您提交的立案申请已经通过审核。但此时并不代表着立即交费。只有等法官生成了案号和受理费、上诉费或者申请费之后,您才能在网上交费,到时会收到短信提醒。

如果案件还没有案号和交费通道,,案件状态是“审核通过”,需要等待法官在内网生成案号和交费信息。请耐心等待,或者直接与受理法院直接联系。

3.2交费时为什么提示交费人不是原告

出现这种问题的原因一般是内网法官选择交费人时选成了被告,或者内网更改过原告名字。

3.3审判系统在哪儿查看诉讼费交纳情况

图中红色方框内是查看网上立案交费结果查询按钮,点击即可查询。


4、系统功能介绍



4.1民事一审

4.2行政上诉

4.3执行复议

4.4网上交费

4.5材料递交


4.1民事一审

点击【民事一审】进入信息填写页面:红色星号字段是必填项。按照页面提示从上到下依次录入:受理法院、案由、标的金额、申请人身份;添加原告、被告、第三人;缴费人退费人信息;送达地址确认书;诉讼请求、事实理由;上传案件材料。

* 选择法院:点击进入选择法院页面,支持根据法院名称模糊查询,快速锁定法院;

* 选择申请人身份:下拉列表选择

* 标的金额:只能录入整数或者小数,不能有其他特殊字符

案由:点击之后,进行查询

添加当事人

*原告(申请人):必填添加,且跟诉状保持一致

*被告(被申请人):必填添加,且跟诉状保持一致

第三人:如果涉及第三人,请添加第三人信息,且跟诉状保持一致 原告、被告、第三人,可以点击后面的,可以添加“自然人”、“法人”、“非法人其他组织”。

4.2行政上诉

操作流程跟民事上诉几乎一致,根据页面提示操作即可,不再赘述。

4.3执行复议

操作同执行异议差不多,按照页面提示进行填写即可。

执行依据

*申请受理法院:为执行法院的上级法院

*执行法院:请根据原执行案号选择, 如案号(2020)鲁0102执19号执行法院为历下法院,申请受理法院为济南中院

*原执异案号:录入原先的执异或执字案号

*复议事项:从下拉框里选择

*执行依据文号:录入执行依据文号

其他操作步骤同执行异议差不多,按照页面提示进行填写即可。

4.4网上交费

案件提交之后,等待法官进行审批,如果案件进入待交费阶段,立案人账号绑定的手机收到交费短信。

4.4.1非青岛辖区法院交费

点击系统首页——“网上缴费”,进入待缴费案件列表页面,您所有的待交费案件都会显示在下图列表中。包含法院、订单号、案号、总金额、交费人姓名等信息,也可以根据上方的查询条件快速定位待交费案件。

点击“去缴费”,进入诉讼费预收票据页面。网上交费目前支持微信、支付宝、对公网银、银联支付这4种支付方式(如果您的交费金额>20万,还会额外出现个人网银共5种支付方式)

选择任意一种支付方式,倒计时30秒结束后,点击“去支付”即可。

个人网银

选择“个人网银”,倒计时结束后,点击“去支付”,进入选择银行页面。如果您无法出现下图选择银行的页面,就是该页面被拦截了。点击浏览器右上角的红色叉号或者红色1,允许页面弹出即可。下面是360浏览器和谷歌浏览器网页拦截示例。

目前个人网银只支持四大行、招商、邮政、中信这7家银行。如果7家银行里有些银行前面的小圆圈按钮是灰色的,那您是无法使用该银行的,这是因为咱们当地财政没有在该家银行开通账户,您只能选择那些不是灰色按钮的银行进行支付。

以建设银行为例,点击“确认付款”按钮,进入建行支付页面,支付方式可以扫描二维码在手机端支付,也可以登录网银或者登录账号后交费,如下:

这里是在手机建行APP上扫描二维码支付的,支付后进入银行扣款成功页面,如下:

点击“已完成支付”按钮,进入支付成功页面,如下:

关闭支付成功页面后,回到我的案件列表页面,案件状态由“待交费”变成了“已交费(待入国库)”。“已交费(待入国库)”是一种正常状态,代表着您已经交费成功了,但是这笔账还没跟省财政进行对账操作(一般来说个人网银方式支付的,第二个工作日才与省财政对账)。

微信

1.选择支付方式为“微信”,倒计时结束后,点击“去支付”。

如果您遇到下图字样的提示:交款书已过期,说明您没有在规定时间内交纳诉讼费,省财政提供的交款码过期了,无法网上交费,请联系法院。

2.进入非税代收确认交费信息页面,页面倒计时10秒,确认交费前请认真核对交款信息。倒计时结束后,点击“确认交费”。

3.进入选择选择支付方式页面,目前非税统平台集成了26家银行及微信、支付宝、银联支付第三方支付交款渠道,交款人可根据实际情况选择具体的支付方式。交款人选择“个人账户付款”——“微信”,点击“去支付”。

4.弹出微信二维码页面,使用手机微信首页“扫一扫”,扫描该二维码,手机上会出现确认支付页面。

5.手机微信上支付完毕之后,二维码页面自动刷新,进入“确认支付状态”页面,提示您“你已成功完成交费”。点击“查看详情”,进入支付凭证查看页面,并可以下载凭证。

支付宝

1.选择支付方式为“支付宝”。倒计时结束后,点击“去支付”。

2.进入确认交费信息页面,页面倒计时10秒,确认交费前请认真核对交款信息。倒计时结束后,点击“确认交费”。

3.进入选择选择支付方式页面,目前非税统平台集成了26家银行及微信、支付宝、银联支付第三方支付交款渠道,交款人可根据实际情况选择具体的支付方式。交款人选择“个人账户付款”——“支付宝”,点击“去支付”。

4.弹出支付宝二维码页面,使用手机支付宝APP首页“扫一扫”,扫描该二维码,手机上会出现确认支付页面。

5.手机支付宝上点击“确认并支付”。

6.手机支付宝上支付完毕之后,二维码页面自动刷新,进入“确认支付状态”页面,提示您“你已成功完成交费”。

7.点击“查看详情”,进入支付凭证查看页面,并可以下载凭证。

对公网银

1.选择支付方式为“对公网银”,倒计时结束后,点击“去支付”。进入确认交款信息页面,页面倒计时10秒,确认交费前请认真核对交款信息。倒计时结束后,点击“确认交费”。

2.进入选择选择支付方式页面,目前非税统平台集成了26家银行及微信、支付宝、银联支付第三方支付交款渠道,交款人可根据实际情况选择具体的支付方式。交款人选择选择“公司账户付款”,插入对公网银UK,并勾选“确认您已插入对公网银UsbKey”,然后点击“去支付”。

3.银行对公网银支付流程。因为每家银行的支付方式都不同,此处以光大银行B2B(个人支付)付款为例进行说明。选择光大银行图标,交款人(对公支付的经办人)点击“去支付”按钮,跳转至光大银行网银页面。输入正确的信息后,点击“登录”,进入到光大银行网银页面,如下图:

4.在光大银行网银页面选择“全部功能-电子支付”选择需要录入的订单,点击“支付”,如下图:

5.确认订单信息,再次点击“确定”,完成订单录入。

6.交易已提交,点击“确定”,如下图:

7.交款人(对公支付的复核人),登录到光大银行官网,进入公司网银。选择“交易审核-转账类交易审核-本人审核”,选择需要复核的订单,点击“同意”,如下图:

8.显示交易成功,完成订单复核,如下图:

9.步骤四:查看支付结果

银联支付

1.选择支付方式为“银联支付”。倒计时结束后,点击“去支付”。

2.进入非税代收确认交费信息页面,页面倒计时10秒,确认交费前请认真核对交款信息。倒计时结束后,点击“确认交费”。

3.进入选择选择支付方式页面,目前非税统平台集成了26家银行及微信、支付宝、银联支付第三方支付交款渠道,交款人可根据实际情况选择具体的支付方式。交款人选择“个人账户付款”——“银联支付”,点击“去支付”。

4.进入在线支付页面,“直接付款”只是信用卡和储蓄卡和中银通卡,“登陆付款”可以使用登陆用户名、密码的方式付款。页面对两种付款方式提供了新手操作演示,还有在线客服和帮助中心。

5.支付完毕之后,进入“确认支付状态”页面,提示您“你已成功完成交费”。点击“查看详情”,进入支付凭证查看页面,并可以下载凭证。

帮助中心

在微信、支付宝、对公网银、银联支付过程中遇到问题,请点击以下非税系统帮助链接。https://yaoyao.cebbank.com/LifePaymentSocket/webPc/sdFeiShui/index.html?canal=sdszwpt&code=637934244

点击上面帮助链接或者点击非税代收页面上的“帮助中心”或“联系我们”。

4.4.2青岛辖区法院交费

海事和青岛铁路交费方式按照上面介绍的非青岛辖区法院交费流程,青岛中院及下辖基层院适用下述交费流程!

点击系统首页——“网上缴费”,进入待缴费案件列表页面

点击,进入诉讼费预收票据页面

倒计时结束后,点击创建订单成功,出现下图交费方式选择项。

倒计时结束后,点击创建订单成功,出现下图交费方式选择项。

支付宝

选中支付宝,点击“确认支付”,出现支付宝扫码页面,扫码即可完成支付。

微信

选中微信,点击“确认支付”,出现微信扫码页面,扫码即可完成支付。

中国工商银行

选中中国工商银行,点击“确认支付”,按照页面提示完成支付。

交通银行

选中交通银行,点击“确认支付”,按照页面提示完成支付。

中国建设银行

选中中国建设银行,点击“确认支付”,按照页面提示完成支付。

中国农业银行

选中中国农业银行,点击“确认支付”,按照页面提示完成支付。

中国银行

选中中国银行,点击“确认支付”,按照页面提示完成支付。

4.5材料递交

材料递交是当事人端主动发起的,可以再次提交案件材料。

点击系统首页——“材料补交”,进入案件列表页面。可以通过页面上方的法院等信息进行快速查询和定位案件。

点击“材料递交新增”,进入新增页面,*为必填项。

在申请页面,点击“选择案件”,弹出该账号下的案件列表。点击案件前方的小圆圈,再点击“确定”按钮,选中该案件,即可自动回填所属法院和案号。

然后上传申请材料。

信息填写完毕之后,点击即可将材料推送到内网法院系统等待法官审核,并回到案件列表页面,点击可以查看详情。