system-phone 3.1.92 → 3.1.94

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,87 @@
1
+ # list of languages for which language servers are started; choose from:
2
+ # al bash clojure cpp csharp csharp_omnisharp
3
+ # dart elixir elm erlang fortran fsharp
4
+ # go groovy haskell java julia kotlin
5
+ # lua markdown nix pascal perl php
6
+ # powershell python python_jedi r rego ruby
7
+ # ruby_solargraph rust scala swift terraform toml
8
+ # typescript typescript_vts yaml zig
9
+ # Note:
10
+ # - For C, use cpp
11
+ # - For JavaScript, use typescript
12
+ # - For Free Pascal / Lazarus, use pascal
13
+ # Special requirements:
14
+ # - csharp: Requires the presence of a .sln file in the project folder.
15
+ # - pascal: Requires Free Pascal Compiler (fpc) and optionally Lazarus.
16
+ # When using multiple languages, the first language server that supports a given file will be used for that file.
17
+ # The first language is the default language and the respective language server will be used as a fallback.
18
+ # Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored.
19
+ languages:
20
+ - vue
21
+
22
+ # the encoding used by text files in the project
23
+ # For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings
24
+ encoding: "utf-8"
25
+
26
+ # whether to use the project's gitignore file to ignore files
27
+ # Added on 2025-04-07
28
+ ignore_all_files_in_gitignore: true
29
+
30
+ # list of additional paths to ignore
31
+ # same syntax as gitignore, so you can use * and **
32
+ # Was previously called `ignored_dirs`, please update your config if you are using that.
33
+ # Added (renamed) on 2025-04-07
34
+ ignored_paths: []
35
+
36
+ # whether the project is in read-only mode
37
+ # If set to true, all editing tools will be disabled and attempts to use them will result in an error
38
+ # Added on 2025-04-18
39
+ read_only: false
40
+
41
+ # list of tool names to exclude. We recommend not excluding any tools, see the readme for more details.
42
+ # Below is the complete list of tools for convenience.
43
+ # To make sure you have the latest list of tools, and to view their descriptions,
44
+ # execute `uv run scripts/print_tool_overview.py`.
45
+ #
46
+ # * `activate_project`: Activates a project by name.
47
+ # * `check_onboarding_performed`: Checks whether project onboarding was already performed.
48
+ # * `create_text_file`: Creates/overwrites a file in the project directory.
49
+ # * `delete_lines`: Deletes a range of lines within a file.
50
+ # * `delete_memory`: Deletes a memory from Serena's project-specific memory store.
51
+ # * `execute_shell_command`: Executes a shell command.
52
+ # * `find_referencing_code_snippets`: Finds code snippets in which the symbol at the given location is referenced.
53
+ # * `find_referencing_symbols`: Finds symbols that reference the symbol at the given location (optionally filtered by type).
54
+ # * `find_symbol`: Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type).
55
+ # * `get_current_config`: Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes.
56
+ # * `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file.
57
+ # * `initial_instructions`: Gets the initial instructions for the current project.
58
+ # Should only be used in settings where the system prompt cannot be set,
59
+ # e.g. in clients you have no control over, like Claude Desktop.
60
+ # * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol.
61
+ # * `insert_at_line`: Inserts content at a given line in a file.
62
+ # * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol.
63
+ # * `list_dir`: Lists files and directories in the given directory (optionally with recursion).
64
+ # * `list_memories`: Lists memories in Serena's project-specific memory store.
65
+ # * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building).
66
+ # * `prepare_for_new_conversation`: Provides instructions for preparing for a new conversation (in order to continue with the necessary context).
67
+ # * `read_file`: Reads a file within the project directory.
68
+ # * `read_memory`: Reads the memory with the given name from Serena's project-specific memory store.
69
+ # * `remove_project`: Removes a project from the Serena configuration.
70
+ # * `replace_lines`: Replaces a range of lines within a file with new content.
71
+ # * `replace_symbol_body`: Replaces the full definition of a symbol.
72
+ # * `restart_language_server`: Restarts the language server, may be necessary when edits not through Serena happen.
73
+ # * `search_for_pattern`: Performs a search for a pattern in the project.
74
+ # * `summarize_changes`: Provides instructions for summarizing the changes made to the codebase.
75
+ # * `switch_modes`: Activates modes by providing a list of their names
76
+ # * `think_about_collected_information`: Thinking tool for pondering the completeness of collected information.
77
+ # * `think_about_task_adherence`: Thinking tool for determining whether the agent is still on track with the current task.
78
+ # * `think_about_whether_you_are_done`: Thinking tool for determining whether the task is truly completed.
79
+ # * `write_memory`: Writes a named memory (for future reference) to Serena's project-specific memory store.
80
+ excluded_tools: []
81
+
82
+ # initial prompt for the project. It will always be given to the LLM upon activating the project
83
+ # (contrary to the memories, which are loaded on demand).
84
+ initial_prompt: ""
85
+
86
+ project_name: "SystemPhone"
87
+ included_optional_tools: []
@@ -11,12 +11,6 @@ var compiler = webpack(config)
11
11
  // Define HTTP proxies to your custom API backend
12
12
  // https://github.com/chimurai/http-proxy-middleware
13
13
  var proxyTable = {
14
- '/rs/logic/getLogin': {
15
- pathRewrite: {
16
- '^/rs/logic/getLogin': '/getLogin'
17
- },
18
- target: 'http://127.0.0.1:8077/'
19
- },
20
14
  // '/rs/weixin': {
21
15
  // target: 'http://121.36.106.17:8400/'
22
16
  // },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "system-phone",
3
- "version": "3.1.92",
3
+ "version": "3.1.94",
4
4
  "description": "手机模块 前端组件",
5
5
  "author": "何宁社 <524395609@qq.com>",
6
6
  "license": "ISC",
@@ -106,6 +106,7 @@
106
106
  import Vue from 'vue'
107
107
  import * as Util from '../Util'
108
108
  import cryptJS from './EncryptUtil'
109
+ import { validateStrongPasswordPhone } from '../plugins/validateStrongPasswordPhone.js'
109
110
  //获取json配置文件
110
111
  let asyncReady = async function (self, url) {
111
112
  // 获取配置信息
@@ -481,10 +482,13 @@ export default {
481
482
  console.log('获取参数结束')
482
483
  this.loaderShow = false
483
484
  // 弱口令验证
484
- if (this.weakPassword && !(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?])(?!.*(123|321|abc|cba))[a-zA-Z\d!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]{8,16}$/.test(this.password))) {
485
- await this.$showMessage('登录系统: 此账户的密码过于简单,请修改密码后重新登陆!!!', ['confirm'])
486
- this.modifyPassword = true
487
- return
485
+ if (this.weakPassword) {
486
+ const pwdResult = validateStrongPasswordPhone(this.password)
487
+ if (!pwdResult.isValid) {
488
+ await this.$showMessage('登录系统: 此账户的密码过于简单,' + (pwdResult.errors[0] || '请修改密码后重新登陆!!!'), ['confirm'])
489
+ this.modifyPassword = true
490
+ return
491
+ }
488
492
  }
489
493
  this.$goto('nav-bottom')
490
494
  },
@@ -3,6 +3,9 @@
3
3
  <!--<span class="glyphicon glyphicon-menu-left">返回</span>-->
4
4
  <!--</div>-->
5
5
  <div class="auto">
6
+ <div v-if="weakPassword" class="password-alert">
7
+ {{ passwordRuleHint }}
8
+ </div>
6
9
  <div class="row app-row">
7
10
  <div class="col-xs-4">
8
11
  <img src="../assets/姓名.png" style="width: 20px;margin-bottom: 5px" alt="">
@@ -29,7 +32,12 @@
29
32
  </div>
30
33
  <div class="col-xs-8">
31
34
  <input type="password" id="newpassword1" class="search_input input-font" v-model="model.password"
32
- :placeholder="weakPassword?'需要包含大小写字母符号数字':'请输入新密码'"/>
35
+ placeholder="请输入新密码"/>
36
+ <div v-if="weakPassword && passwordStrength.visible" class="password-strength">
37
+ <span class="strength-label">密码强度</span>
38
+ <span class="strength-tag" :class="passwordStrength.type">{{ passwordStrength.label }}</span>
39
+ <span class="strength-desc">{{ passwordStrength.desc }}</span>
40
+ </div>
33
41
  </div>
34
42
  </div>
35
43
  <div class="row app-row">
@@ -104,7 +112,7 @@ let asyncCheck = async function (self, url) {
104
112
  }
105
113
  }
106
114
  }
107
- import { validateStrongPasswordPhone } from '../plugins/validateStrongPasswordPhone.js'
115
+ import { validateStrongPasswordPhone, getPasswordStrength, PASSWORD_RULE_HINT } from '../plugins/validateStrongPasswordPhone.js'
108
116
  export default {
109
117
  title: '修改密码',
110
118
  data() {
@@ -117,7 +125,13 @@ export default {
117
125
  password: '',
118
126
  newpassword: ''
119
127
  },
120
- showpass: false
128
+ showpass: false,
129
+ passwordRuleHint: PASSWORD_RULE_HINT
130
+ }
131
+ },
132
+ computed: {
133
+ passwordStrength () {
134
+ return getPasswordStrength(this.model.password)
121
135
  }
122
136
  },
123
137
  props: {
@@ -204,6 +218,51 @@ export default {
204
218
  color: #333333;
205
219
  }
206
220
 
221
+ .password-alert {
222
+ margin: 10px 10px 0;
223
+ padding: 10px 12px;
224
+ border-radius: 6px;
225
+ background: #f5f7fa;
226
+ border: 1px solid #e4e7ed;
227
+ color: #606266;
228
+ font-size: 13px;
229
+ line-height: 1.6;
230
+ }
231
+
232
+ .password-strength {
233
+ margin-top: 8px;
234
+ font-size: 12px;
235
+ line-height: 1.6;
236
+ color: #606266;
237
+ }
238
+
239
+ .password-strength .strength-label {
240
+ margin-right: 6px;
241
+ color: #909399;
242
+ }
243
+
244
+ .password-strength .strength-tag {
245
+ display: inline-block;
246
+ margin-right: 8px;
247
+ padding: 1px 8px;
248
+ border-radius: 3px;
249
+ font-size: 12px;
250
+ }
251
+
252
+ .password-strength .strength-tag.success {
253
+ color: #2e7d32;
254
+ background: #e8f5e9;
255
+ }
256
+
257
+ .password-strength .strength-tag.error {
258
+ color: #c62828;
259
+ background: #ffebee;
260
+ }
261
+
262
+ .password-strength .strength-desc {
263
+ color: #606266;
264
+ }
265
+
207
266
  .app-botton {
208
267
  position: fixed;
209
268
  background: #87b2dd;
@@ -63,6 +63,7 @@
63
63
  import Vue from 'vue'
64
64
  import * as Util from '../../Util'
65
65
  import JSEncrypt from 'jsencrypt'
66
+ import { validateStrongPasswordPhone } from '../../plugins/validateStrongPasswordPhone.js'
66
67
  //获取json配置文件
67
68
  let asyncReady = async function (self, url) {
68
69
  // 获取配置信息
@@ -308,10 +309,13 @@ export default {
308
309
  console.log('获取参数结束')
309
310
  this.loaderShow = false
310
311
  // 弱口令验证
311
- if (this.weakPassword && !(/^(?:(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9])).*$/.test(this.password))) {
312
- await this.$showMessage('登录系统: 此账户的密码过于简单,请修改密码后重新登陆!!!', ['confirm'])
313
- this.modifyPassword = true
314
- return
312
+ if (this.weakPassword) {
313
+ const pwdResult = validateStrongPasswordPhone(this.password)
314
+ if (!pwdResult.isValid) {
315
+ await this.$showMessage('登录系统: 此账户的密码过于简单,' + (pwdResult.errors[0] || '请修改密码后重新登陆!!!'), ['confirm'])
316
+ this.modifyPassword = true
317
+ return
318
+ }
315
319
  }
316
320
  this.$goto('nav-bottom')
317
321
  } catch (e) {
@@ -62,6 +62,7 @@
62
62
  import Vue from 'vue'
63
63
  import * as Util from '../../Util'
64
64
  import JSEncrypt from 'jsencrypt'
65
+ import { validateStrongPasswordPhone } from '../../plugins/validateStrongPasswordPhone.js'
65
66
  //获取json配置文件
66
67
  let asyncReady = async function (self, url) {
67
68
  // 获取配置信息
@@ -321,10 +322,14 @@ export default {
321
322
  console.log('获取参数结束')
322
323
  this.loaderShow = false
323
324
  // 弱口令验证
324
- if (this.weakPassword && !(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?!.*(123|321|abc|cba))[a-zA-Z\d!@#$%^&*()_+-=<>?]{8,16}$/.test(this.password))) {
325
- await this.$showMessage('登录系统: 此账户的密码过于简单,请修改密码后重新登陆!!!', ['confirm'])
326
- this.modifyPassword = true
327
- return
325
+ // 弱口令验证
326
+ if (this.weakPassword) {
327
+ const pwdResult = validateStrongPasswordPhone(this.password)
328
+ if (!pwdResult.isValid) {
329
+ await this.$showMessage('登录系统: 此账户的密码过于简单,' + (pwdResult.errors[0] || '请修改密码后重新登陆!!!'), ['confirm'])
330
+ this.modifyPassword = true
331
+ return
332
+ }
328
333
  }
329
334
  this.$goto('nav-bottom')
330
335
  } catch (e) {
@@ -63,6 +63,7 @@
63
63
  import Vue from 'vue'
64
64
  import * as Util from '../../Util'
65
65
  import JSEncrypt from 'jsencrypt'
66
+ import { validateStrongPasswordPhone } from '../../plugins/validateStrongPasswordPhone.js'
66
67
  //获取json配置文件
67
68
  let asyncReady = async function (self, url) {
68
69
  // 获取配置信息
@@ -337,10 +338,13 @@ export default {
337
338
  console.log('获取参数结束')
338
339
  this.loaderShow = false
339
340
  // 弱口令验证
340
- if (this.weakPassword && !(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?!.*(123|321|abc|cba))[a-zA-Z\d!@#$%^&*()_+-=<>?]{8,16}$/.test(this.password))) {
341
- await this.$showMessage('登录系统: 此账户的密码过于简单,请修改密码后重新登陆!!!', ['confirm'])
342
- this.modifyPassword = true
343
- return
341
+ if (this.weakPassword) {
342
+ const pwdResult = validateStrongPasswordPhone(this.password)
343
+ if (!pwdResult.isValid) {
344
+ await this.$showMessage('登录系统: 此账户的密码过于简单,' + (pwdResult.errors[0] || '请修改密码后重新登陆!!!'), ['confirm'])
345
+ this.modifyPassword = true
346
+ return
347
+ }
344
348
  }
345
349
  this.$goto('nav-bottom')
346
350
  } catch (e) {
@@ -64,6 +64,7 @@
64
64
  import Vue from 'vue'
65
65
  import * as Util from '../../Util'
66
66
  import JSEncrypt from 'jsencrypt'
67
+ import { validateStrongPasswordPhone } from '../../plugins/validateStrongPasswordPhone.js'
67
68
  //获取json配置文件
68
69
  let asyncReady = async function (self, url) {
69
70
  // 获取配置信息
@@ -368,10 +369,13 @@ export default {
368
369
  console.log('获取参数结束')
369
370
  this.loaderShow = false
370
371
  // 弱口令验证
371
- if (this.weakPassword && !(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?!.*(123|321|abc|cba))[a-zA-Z\d!@#$%^&*()_+-=<>?]{8,16}$/.test(this.password))) {
372
- await this.$showMessage('登录系统: 此账户的密码过于简单,请修改密码后重新登陆!!!', ['confirm'])
373
- this.modifyPassword = true
374
- return
372
+ if (this.weakPassword) {
373
+ const pwdResult = validateStrongPasswordPhone(this.password)
374
+ if (!pwdResult.isValid) {
375
+ await this.$showMessage('登录系统: 此账户的密码过于简单,' + (pwdResult.errors[0] || '请修改密码后重新登陆!!!'), ['confirm'])
376
+ this.modifyPassword = true
377
+ return
378
+ }
375
379
  }
376
380
  this.$goto('nav-bottom')
377
381
  },
@@ -63,6 +63,7 @@
63
63
  import Vue from 'vue'
64
64
  import * as Util from '../../Util'
65
65
  import JSEncrypt from 'jsencrypt'
66
+ import { validateStrongPasswordPhone } from '../../plugins/validateStrongPasswordPhone.js'
66
67
  //获取json配置文件
67
68
  let asyncReady = async function (self, url) {
68
69
  try {
@@ -361,10 +362,14 @@ export default {
361
362
  console.log('获取参数结束')
362
363
  this.loaderShow = false
363
364
  // 弱口令验证
364
- if (this.weakPassword && !(/^(?:(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9])).*$/.test(this.password))) {
365
- await this.$showMessage('登录系统: 此账户的密码过于简单,请修改密码后重新登陆!!!', ['confirm'])
366
- this.modifyPassword = true
367
- return
365
+ // 弱口令验证
366
+ if (this.weakPassword) {
367
+ const pwdResult = validateStrongPasswordPhone(this.password)
368
+ if (!pwdResult.isValid) {
369
+ await this.$showMessage('登录系统: 此账户的密码过于简单,' + (pwdResult.errors[0] || '请修改密码后重新登陆!!!'), ['confirm'])
370
+ this.modifyPassword = true
371
+ return
372
+ }
368
373
  }
369
374
  this.$androidUtil.setPreference('current_create_current_address', JSON.stringify({
370
375
  f_address: '',
@@ -63,6 +63,7 @@
63
63
  import Vue from 'vue'
64
64
  import * as Util from '../../Util'
65
65
  import JSEncrypt from 'jsencrypt'
66
+ import { validateStrongPasswordPhone } from '../../plugins/validateStrongPasswordPhone.js'
66
67
  //获取json配置文件
67
68
  let asyncReady = async function (self, url) {
68
69
  try {
@@ -331,10 +332,14 @@ export default {
331
332
  console.log('获取参数结束')
332
333
  this.loaderShow = false
333
334
  // 弱口令验证
334
- if (this.weakPassword && !(/^(?:(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9])).*$/.test(this.password))) {
335
- await this.$showMessage('登录系统: 此账户的密码过于简单,请修改密码后重新登陆!!!', ['confirm'])
336
- this.modifyPassword = true
337
- return
335
+ // 弱口令验证
336
+ if (this.weakPassword) {
337
+ const pwdResult = validateStrongPasswordPhone(this.password)
338
+ if (!pwdResult.isValid) {
339
+ await this.$showMessage('登录系统: 此账户的密码过于简单,' + (pwdResult.errors[0] || '请修改密码后重新登陆!!!'), ['confirm'])
340
+ this.modifyPassword = true
341
+ return
342
+ }
338
343
  }
339
344
  this.$androidUtil.setPreference('current_create_current_address', JSON.stringify({
340
345
  f_address: '',
@@ -1,172 +1,185 @@
1
1
  const REG_STRONG_PWD =
2
- /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?])(?!.*(123|321|abc|cba))[a-zA-Z\d!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]{8,16}$/;
2
+ /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*(),.?":{}|<>~`+=_\\-])[A-Za-z\d!@#$%^&*(),.?":{}|<>~`+=_\\-]{12,16}$/
3
3
 
4
- // 常见密码列表(可以根据需要扩展)
5
4
  const COMMON_PASSWORDS = [
6
- "password",
7
- "password123",
8
- "123456",
9
- "12345678",
10
- "qwerty",
11
- "abc123",
12
- "Password1",
13
- "password1",
14
- "123456789",
15
- "welcome",
16
- "admin",
17
- "letmein",
18
- "monkey",
19
- "dragon",
20
- "master",
21
- "superman",
22
- "qwerty123",
23
- "admin123",
24
- "root",
25
- "pass",
26
- "test",
27
- "guest",
28
- "user",
29
- "000000",
30
- "111111",
31
- "666666",
32
- "888888",
33
- "999999",
34
- "iloveyou",
35
- "welcome123",
36
- "password!",
37
- "Passw0rd!",
38
- "Passw0rd",
39
- "Password!",
40
- "passw0rd",
41
- "P@ssw0rd",
42
- "P@ssword",
43
- "Password@123",
44
- ];
45
-
46
- // 检查连续数字(3个或以上)
47
- const hasConsecutiveNumbers = (password) => {
5
+ 'password',
6
+ 'password123',
7
+ '123456',
8
+ '12345678',
9
+ 'qwerty',
10
+ 'abc123',
11
+ 'Password1',
12
+ 'password1',
13
+ '123456789',
14
+ 'welcome',
15
+ 'admin',
16
+ 'letmein',
17
+ 'monkey',
18
+ 'dragon',
19
+ 'master',
20
+ 'superman',
21
+ 'qwerty123',
22
+ 'admin123',
23
+ 'root',
24
+ 'pass',
25
+ 'test',
26
+ 'guest',
27
+ 'user',
28
+ '000000',
29
+ '111111',
30
+ '666666',
31
+ '888888',
32
+ '999999',
33
+ 'iloveyou',
34
+ 'welcome123',
35
+ 'password!',
36
+ 'Passw0rd!',
37
+ 'Passw0rd',
38
+ 'Password!',
39
+ 'passw0rd',
40
+ 'P@ssw0rd',
41
+ 'P@ssword',
42
+ 'Password@123'
43
+ ]
44
+
45
+ export const PASSWORD_RULE_HINT = '密码长度须为 12-16 位,包含大小写字母、数字与特殊符号。'
46
+
47
+ export const PASSWORD_DEFAULT_ERROR = '新密码必须包含大小写字母、数字和特殊字符,且长度为12-16位'
48
+
49
+ function hasConsecutiveNumbers (password) {
48
50
  for (let i = 0; i <= password.length - 3; i++) {
49
- const substr = password.substring(i, i + 3);
51
+ const substr = password.substring(i, i + 3)
50
52
  if (/^\d{3,}$/.test(substr)) {
51
- // 检查是否为连续数字
52
- const digits = substr.split("").map(Number);
53
- let isConsecutive = true;
53
+ const digits = substr.split('').map(Number)
54
+ let isConsecutive = true
54
55
  for (let j = 1; j < digits.length; j++) {
55
56
  if (digits[j] !== digits[j - 1] + 1) {
56
- isConsecutive = false;
57
- break;
57
+ isConsecutive = false
58
+ break
58
59
  }
59
60
  }
60
- if (isConsecutive) return true;
61
+ if (isConsecutive) return true
61
62
  }
62
63
  }
63
- return false;
64
- };
64
+ return false
65
+ }
65
66
 
66
- // 检查连续字母(3个或以上)
67
- const hasConsecutiveLetters = (password) => {
68
- const lowerPassword = password.toLowerCase();
67
+ function hasConsecutiveLetters (password) {
68
+ const lowerPassword = password.toLowerCase()
69
69
  for (let i = 0; i <= lowerPassword.length - 3; i++) {
70
- const substr = lowerPassword.substring(i, i + 3);
70
+ const substr = lowerPassword.substring(i, i + 3)
71
71
  if (/^[a-z]{3,}$/.test(substr)) {
72
- // 检查是否为连续字母
73
- let isConsecutive = true;
72
+ let isConsecutive = true
74
73
  for (let j = 1; j < substr.length; j++) {
75
74
  if (substr.charCodeAt(j) !== substr.charCodeAt(j - 1) + 1) {
76
- isConsecutive = false;
77
- break;
75
+ isConsecutive = false
76
+ break
78
77
  }
79
78
  }
80
- if (isConsecutive) return true;
79
+ if (isConsecutive) return true
81
80
  }
82
81
  }
83
- return false;
84
- };
85
-
86
- // 检查重复字符(3个或以上相同字符)
87
- const hasRepeatedChars = (password) => {
88
- return /(.)\1{2,}/.test(password);
89
- };
90
-
91
- // 检查键盘连续按键(如 qwerty, asdf 等)
92
- const hasKeyboardPattern = (password) => {
93
- const keyboardRows = ["qwertyuiop", "asdfghjkl", "zxcvbnm", "1234567890"];
94
- const lowerPassword = password.toLowerCase();
82
+ return false
83
+ }
84
+
85
+ function hasRepeatedChars (password) {
86
+ return /(.)\1{2,}/.test(password)
87
+ }
88
+
89
+ function hasKeyboardPattern (password) {
90
+ const keyboardRows = ['qwertyuiop', 'asdfghjkl', 'zxcvbnm', '1234567890']
91
+ const lowerPassword = password.toLowerCase()
92
+
95
93
  for (const row of keyboardRows) {
96
94
  for (let i = 0; i <= row.length - 3; i++) {
97
- const pattern = row.substring(i, i + 3);
95
+ const pattern = row.substring(i, i + 3)
98
96
  if (lowerPassword.includes(pattern)) {
99
- return true;
97
+ return true
100
98
  }
101
99
  }
102
100
  }
103
- return false;
104
- };
105
-
106
- /**
107
- * 密码校验结果对象
108
- * @typedef {Object} PasswordValidationResult
109
- * @property {boolean} isValid
110
- * @property {string[]} errors
111
- */
112
-
113
- /**
114
- * 增强的密码校验函数
115
- * @param {string} password
116
- * @returns {PasswordValidationResult}
117
- */
101
+ return false
102
+ }
103
+
118
104
  export const validateStrongPasswordPhone = (password) => {
119
105
  const result = {
120
106
  isValid: true,
121
- errors: [],
122
- };
107
+ errors: []
108
+ }
109
+
110
+ if (!password) {
111
+ result.isValid = false
112
+ result.errors.push('不能为空')
113
+ return result
114
+ }
123
115
 
124
- // 1. 基本格式校验
125
116
  if (!REG_STRONG_PWD.test(password)) {
126
- result.isValid = false;
127
- result.errors.push(
128
- "密码长度必须为8-16位,且需同时包含大写字母、小写字母、数字和特殊字符"
129
- );
130
- return result;
117
+ result.isValid = false
118
+ result.errors.push('密码长度须为12-16位,且包含大写字母、小写字母、数字和特殊字符')
119
+ return result
131
120
  }
132
121
 
133
- // 2. 检查是否为常见密码
134
- if (
135
- COMMON_PASSWORDS.includes(password) ||
136
- COMMON_PASSWORDS.includes(password.toLowerCase())
137
- ) {
138
- result.isValid = false;
139
- result.errors.push("不能使用常见密码");
140
- return result;
122
+ if (COMMON_PASSWORDS.includes(password) || COMMON_PASSWORDS.includes(password.toLowerCase())) {
123
+ result.isValid = false
124
+ result.errors.push('不能使用常见密码')
125
+ return result
141
126
  }
142
127
 
143
- // 3. 检查连续数字
144
128
  if (hasConsecutiveNumbers(password)) {
145
- result.isValid = false;
146
- result.errors.push("不能包含连续数字");
147
- return result;
129
+ result.isValid = false
130
+ result.errors.push('不能包含连续数字')
131
+ return result
148
132
  }
149
133
 
150
- // 4. 检查连续字母
151
134
  if (hasConsecutiveLetters(password)) {
152
- result.isValid = false;
153
- result.errors.push("不能包含连续字母");
154
- return result;
135
+ result.isValid = false
136
+ result.errors.push('不能包含连续字母')
137
+ return result
155
138
  }
156
139
 
157
- // 5. 检查重复字符
158
140
  if (hasRepeatedChars(password)) {
159
- result.isValid = false;
160
- result.errors.push("不能包含3个或以上相同字符");
161
- return result;
141
+ result.isValid = false
142
+ result.errors.push('不能包含3个或以上相同字符')
143
+ return result
162
144
  }
163
145
 
164
- // 6. 检查键盘模式
165
146
  if (hasKeyboardPattern(password)) {
166
- result.isValid = false;
167
- result.errors.push("不能包含键盘连续按键模式");
168
- return result;
147
+ result.isValid = false
148
+ result.errors.push('不能包含键盘连续按键模式')
149
+ return result
169
150
  }
170
151
 
171
- return result;
172
- };
152
+ return result
153
+ }
154
+
155
+ export function isStrongPassword (password) {
156
+ return validateStrongPasswordPhone(password).isValid
157
+ }
158
+
159
+ export function getPasswordStrength (password) {
160
+ if (!password) {
161
+ return {
162
+ label: '未输入',
163
+ type: 'default',
164
+ desc: '请输入密码以查看强度',
165
+ visible: false
166
+ }
167
+ }
168
+
169
+ const { isValid, errors } = validateStrongPasswordPhone(password)
170
+ if (isValid) {
171
+ return {
172
+ label: '强',
173
+ type: 'success',
174
+ desc: '密码满足复杂度要求',
175
+ visible: true
176
+ }
177
+ }
178
+
179
+ return {
180
+ label: '弱',
181
+ type: 'error',
182
+ desc: errors[0] || '密码不满足安全要求',
183
+ visible: true
184
+ }
185
+ }