fix: 增加脚本的 prompt
							parent
							
								
									43493c6542
								
							
						
					
					
						commit
						420aedf83e
					
				| 
						 | 
					@ -40,7 +40,52 @@
 | 
				
			||||||
import CodeMirror from 'cmp-element/components/code-mirror'
 | 
					import CodeMirror from 'cmp-element/components/code-mirror'
 | 
				
			||||||
import { last } from 'lodash-es'
 | 
					import { last } from 'lodash-es'
 | 
				
			||||||
import { getGroup, getScriptBySimple, getScriptDetail } from 'services/task/script'
 | 
					import { getGroup, getScriptBySimple, getScriptDetail } from 'services/task/script'
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 使用管道符'|'作为分隔符,从脚本内容中解析出参数。
 | 
				
			||||||
 | 
					 * @param {string} scriptContent 用户输入的脚本内容,例如 "echo ${{name|请输入姓名}}}"
 | 
				
			||||||
 | 
					 * @returns {Array<{key: string, value: string, prompt: string}>} 解析并去重后的参数数组
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function parseScriptWithPipe(scriptContent) {
 | 
				
			||||||
 | 
					  // 正则表达式解释:
 | 
				
			||||||
 | 
					  // \${{       - 匹配字面量 "${{"
 | 
				
			||||||
 | 
					  // \s* - 匹配0或多个空格
 | 
				
			||||||
 | 
					  // (\w+)       - 捕获组1: key (匹配一个或多个字母、数字、下划线)
 | 
				
			||||||
 | 
					  // \s* - 匹配0或多个空格
 | 
				
			||||||
 | 
					  // (           - 开始一个可选的非捕获组 (?: ... )?
 | 
				
			||||||
 | 
					  //   \|        - 匹配转义后的管道符 '|'
 | 
				
			||||||
 | 
					  //   \s* - 匹配0或多个空格
 | 
				
			||||||
 | 
					  //   (.*?)     - 捕获组2: prompt (非贪婪模式匹配任意字符,直到下一个 "}}" )
 | 
				
			||||||
 | 
					  // )?          - 整个 prompt 部分是可选的
 | 
				
			||||||
 | 
					  // \s* - 匹配0或多个空格
 | 
				
			||||||
 | 
					  // }}          - 匹配字面量 "}}"
 | 
				
			||||||
 | 
					  const regex = /\${{\s*(\w+)\s*(?:\|\s*(.*?))?\s*}}/g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 使用 matchAll 获取所有匹配项的迭代器
 | 
				
			||||||
 | 
					  const matches = scriptContent.matchAll(regex)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 使用 Map 来根据 key 进行去重,确保每个 key 只被解析一次(以第一次出现的为准)
 | 
				
			||||||
 | 
					  const paramsMap = new Map()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for (const match of matches) {
 | 
				
			||||||
 | 
					    // match[1] 是第一个捕获组,即 key
 | 
				
			||||||
 | 
					    const key = match[1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 如果 key 还没有在 map 中,才进行处理
 | 
				
			||||||
 | 
					    if (!paramsMap.has(key)) {
 | 
				
			||||||
 | 
					      // match[2] 是第二个捕获组 (prompt),如果不存在则为 undefined
 | 
				
			||||||
 | 
					      const prompt = match[2] || '' // 使用空字符串作为默认值
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      paramsMap.set(key, {
 | 
				
			||||||
 | 
					        key: key,
 | 
				
			||||||
 | 
					        value: '', // 初始 value 可以和 key 相同,或设为空字符串 ''
 | 
				
			||||||
 | 
					        prompt: prompt.trim() // 去除 prompt 的前后多余空格
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 将 Map 的值转换为数组并返回
 | 
				
			||||||
 | 
					  return Array.from(paramsMap.values())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  components: { CodeMirror },
 | 
					  components: { CodeMirror },
 | 
				
			||||||
  props: {
 | 
					  props: {
 | 
				
			||||||
| 
						 | 
					@ -91,19 +136,15 @@ export default {
 | 
				
			||||||
      const data = await getScriptDetail(this.scriptItem.scriptId)
 | 
					      const data = await getScriptDetail(this.scriptItem.scriptId)
 | 
				
			||||||
      if (data.success) {
 | 
					      if (data.success) {
 | 
				
			||||||
        const { category, content, name: scriptName, filename } = data.data
 | 
					        const { category, content, name: scriptName, filename } = data.data
 | 
				
			||||||
        const reg = new RegExp(/\$\{\{(.+)\}\}/g)
 | 
					        // '${{hostname|请输入hostname}}' =>
 | 
				
			||||||
        const res = content.match(reg)
 | 
					        // [
 | 
				
			||||||
        const params = []
 | 
					        //   {
 | 
				
			||||||
        if (res) {
 | 
					        //     key: 'hostname',
 | 
				
			||||||
          // ['${{hostname}}'] => ['hostname']
 | 
					        //     value: '',
 | 
				
			||||||
          const keys = [...new Set(res.map(item => item.slice(3, item.length - 2)))]
 | 
					        //     prompt: '请输入hostname'
 | 
				
			||||||
          keys.forEach(element => {
 | 
					        //   }
 | 
				
			||||||
            params.push({
 | 
					        // ]
 | 
				
			||||||
              key: element,
 | 
					        const params = parseScriptWithPipe(content)
 | 
				
			||||||
              value: ''
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
          })
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        this.scriptItem.category = category
 | 
					        this.scriptItem.category = category
 | 
				
			||||||
        this.scriptItem.content = content
 | 
					        this.scriptItem.content = content
 | 
				
			||||||
        this.scriptItem.scriptName = scriptName
 | 
					        this.scriptItem.scriptName = scriptName
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,7 @@
 | 
				
			||||||
    <el-row :gutter="10">
 | 
					    <el-row :gutter="10">
 | 
				
			||||||
      <el-col :span="12" v-for="(cell, index) in itemData.params" :key="index">
 | 
					      <el-col :span="12" v-for="(cell, index) in itemData.params" :key="index">
 | 
				
			||||||
        <basic-form-item :label="`${cell.key}:`" show-overflow-tooltip>
 | 
					        <basic-form-item :label="`${cell.key}:`" show-overflow-tooltip>
 | 
				
			||||||
          <el-input v-model="cell.value"></el-input>
 | 
					          <el-input v-model="cell.value" :placeholder="cell.prompt"></el-input>
 | 
				
			||||||
        </basic-form-item>
 | 
					        </basic-form-item>
 | 
				
			||||||
      </el-col>
 | 
					      </el-col>
 | 
				
			||||||
    </el-row>
 | 
					    </el-row>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue