Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat:文件类型变量上传的文件支持版本管理 #11467 #11482

Merged
merged 14 commits into from
Mar 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
{
customDesc
? <NamingConventionTip/>
: <div style="white-space: pre-wrap; font-size: 12px; max-width: 500px;">
: <div style="white-space: pre-wrap; overflow-wrap: break-word; font-size: 12px; max-width: 500px;">
{
descMap.length > 1
? descMap.map(item => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,10 @@
/>
</bk-form-item>
</div>
<div class="params-flex-col pt10">
<div
class="params-flex-col pt10"
:style="{ 'flex-direction': !isRepoParam(param.type) && !isFileParam(param.type) ? '' : 'column' }"
>
<bk-form-item
label-width="auto"
class="flex-col-span-1"
Expand Down Expand Up @@ -265,6 +268,7 @@

<bk-form-item
v-else
style="max-width: 100%;"
label-width="auto"
:label="$t(`editPage.${getParamsDefaultValueLabel(param.type)}`)"
:required="isBooleanParam(param.type)"
Expand All @@ -279,6 +283,8 @@
:disabled="disabled"
:value="param.defaultValue"
:handle-change="(name, value) => handleUpdateParam(name, value, index)"
:enable-version-control="param.enableVersionControl"
:random-sub-path="param.randomStringInPath"
/>
</bk-form-item>
</template>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,9 @@
width: 600px;
.parallel-conf-detail-row {
line-height: 32px;
align-items: center;
grid-template-columns: 150px 1fr;
> label {
line-height: 32px;
color: #63656e;
}
> span {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@
:required="valueRequired"
:disabled="disabled"
:value="param.defaultValue"
:enable-version-control="param.enableVersionControl"
:random-sub-path="param.randomStringInPath"
:handle-change="handleChange"
/>
<vuex-textarea
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,36 @@
<vuex-input
class="path-input"
:disabled="disabled"
:handle-change="(name, value) => updatePathFromDirectory(value)"
name="path"
:handle-change="updatePath"
name="directory"
v-validate="{ required: required }"
:data-vv-scope="'pipelineParam'"
:click-unfold="true"
:placeholder="$t('editPage.filePathTips')"
:value="fileDefaultVal.directory"
:value="directory"
:class="{
'is-diff-param': isDiffParam
}"
/>
<span
v-if="enableVersionControl"
:class="['random-generate', randomSubPath ? '' : 'placeholder']"
>
/{{ randomSubPath || $t('editPage.randomlyGenerate') }}/
</span>
<vuex-input
class="file-name"
:disabled="disabled"
:handle-change="(name, value) => updatePathFromFileName(value)"
:handle-change="updatePath"
name="fileName"
v-validate="{ required: required }"
:data-vv-scope="'pipelineParam'"
:click-unfold="true"
:placeholder="$t('editPage.fileNameTips')"
:value="fileDefaultVal.fileName"
:value="fileName"
:class="{
'is-diff-param': isDiffParam
'is-diff-param': isDiffParam,
'border-left-none': !enableVersionControl
}"
/>
</div>
Expand All @@ -50,15 +57,30 @@
<file-upload
name="fileName"
:file-path="value"
@handle-change="(value) => uploadPathFromFileName(value)"
@handle-change="uploadPathFromFileName"
/>
</div>
<div v-if="!flex">
<bk-checkbox
:value="enableVersionControl"
@change="handleEnableVersionControl"
>
{{ $t('editPage.enableVersionControl') }}
</bk-checkbox>
<i
class="bk-icon icon-info-circle"
style="color: #63656e;"
v-bk-tooltips="{ content: $t('editPage.versionControlTip'), placement: 'bottom-start' }"
></i>
</div>
</section>
</template>

<script>
import VuexInput from '@/components/atomFormField/VuexInput'
import FileUpload from '@/components/atomFormField/FileUpload'
import VuexInput from '@/components/atomFormField/VuexInput'
import { randomString } from '@/utils/util'

export default {
components: {
VuexInput,
Expand Down Expand Up @@ -93,47 +115,77 @@
flex: {
type: Boolean,
default: false
},
enableVersionControl: {
type: Boolean,
default: false
},
randomSubPath: {
type: String,
default: ''
}
},
data () {
return {
fileDefaultVal: {
directory: '',
fileName: ''
},
uploadFileName: ''
directory: '',
fileName: ''
}
},
watch: {
uploadFileName (val) {
this.updatePathFromFileName(val)
},
value: {
handler () {
this.splitFilePath()
handler: function (newValue) {
const currentValue = newValue.directory ?? newValue
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

外层已经有处理数据了这里的value就不会是object了

const lastSlashIndex = currentValue?.lastIndexOf('/')

this.fileName = currentValue.slice(lastSlashIndex + 1)

if (this.enableVersionControl && this.randomSubPath) {
const randomStringLastIndex = currentValue.lastIndexOf(`/${this.randomSubPath}`)
this.directory = currentValue.slice(0, randomStringLastIndex)
} else {
this.directory = currentValue.slice(0, lastSlashIndex)
}
},
immediate: true
}
},
methods: {
splitFilePath () {
const lastSlashIndex = this.value.lastIndexOf('/')
this.fileDefaultVal.directory = this.value.substr(0, lastSlashIndex)
this.fileDefaultVal.fileName = this.value.substr(lastSlashIndex + 1)
},
updatePathFromDirectory (value) {
this.fileDefaultVal.directory = value
const val = `${this.fileDefaultVal.directory}/${this.fileDefaultVal.fileName}`
this.handleChange(this.name, val)
},
updatePathFromFileName (value) {
this.fileDefaultVal.fileName = value
const val = `${this.fileDefaultVal.directory}/${this.fileDefaultVal.fileName}`
this.handleChange(this.name, val)
updatePath (name, value, newFile = false) {
this[name] = value
let randomFilePath = this.enableVersionControl ? this.randomSubPath : ''

if (newFile && this.enableVersionControl) {
randomFilePath = randomString(8)
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this[name] = value
let randomFilePath = this.enableVersionControl ? this.randomSubPath : ''


const path = [
this.directory,
...(randomFilePath ? [randomFilePath] : []),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里应该是以this.enableVersionControl为判断条件的

this.fileName
].join('/')

// 执行页面需要传json给后端去改变latestRandomStringInPath的值
const finalValue = this.flex && this.enableVersionControl
? {
directory: path,
latestRandomStringInPath: randomFilePath
}
: path
this.handleChange(this.name, finalValue)

if (!this.flex) {
this.handleChange('randomStringInPath', randomFilePath)
}
},
uploadPathFromFileName (value) {
if (this.fileDefaultVal.fileName) return
this.uploadFileName = value
if (!this.fileName) {
this.fileName = value
}
this.updatePath('fileName', this.fileName, true)
},
handleEnableVersionControl (value) {
this.handleChange('enableVersionControl', value)
this.updatePath('enableVersionControl', value)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里不需要再这么写呀,直接把外层的randomSubPath更新一下就可以

}
}
}
Expand All @@ -143,6 +195,9 @@
.file-param {
width: 100%;
}
.display-flex {
display: flex;
}
.flex-column {
display: flex;
.file-upload {
Expand All @@ -158,15 +213,26 @@
}
}
}
.border-left-none {
border-left: none;
}
.file-input {
width: 100%;
display: flex;
.path-input {
border-radius: 2px 0 0 2px;
}
.random-generate {
font-size: 12px;
color: #737987;
flex-shrink: 0;
padding: 0 10px;
}
.placeholder {
color: #c4c6cc;
}
.file-name {
border-radius: 0 2px 2px 0;
border-left: 0;
}
}
.is-diff-param {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,10 @@
this.$emit('handle-change', file.name)
const formData = new FormData()
setTimeout(async () => {
const path = typeof this.filePath === 'string' ? this.filePath : this.filePath.directory
formData.append('file', file.origin)
formData.append('projectId', this.$route.params.projectId)
formData.append('path', this.filePath)
formData.append('path', path)

const response = await this.$ajax.post(`${this.uploadAcrtifactUrl}`, formData, {
headers: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
:disabled="disabled"
:placeholder="param.placeholder"
:is-diff-param="highlightChangedParam && param.isChanged"
:enable-version-control="param.enableVersionControl"
:random-sub-path="param.latestRandomStringInPath"
/>
</section>
<span
Expand Down Expand Up @@ -163,6 +165,15 @@
}
}
}

if (isFileParam(param.type)) {
// 预览时,重新上传文件,会把文件类型的value变成对象而非字符串,这时要更新随机串回显到页面上
const paramValue = this.paramValues[param.id]
const newRandomString = paramValue?.latestRandomStringInPath
const defaultRandomString = param.latestRandomStringInPath ?? param.randomStringInPath
restParam.latestRandomStringInPath = newRandomString ?? defaultRandomString
restParam.value = typeof paramValue === 'object' ? paramValue?.directory : paramValue
}
return {
...param,
component: this.getParamComponentType(param),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ export const DEFAULT_PARAM = {
defaultValue: '',
defalutValueLabel: 'fileDefaultValueLabel',
defaultValueLabelTips: 'customFileLabelTips',
enableVersionControl: false,
desc: '',
type: CUSTOM_FILE,
typeDesc: 'custom_file',
Expand Down
10 changes: 9 additions & 1 deletion src/frontend/devops-pipeline/src/utils/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
ALL_PIPELINE_VIEW_ID
} from '@/store/constants'
import { v4 as uuidv4 } from 'uuid'
import { isFileParam } from '@/store/modules/atom/paramsConfig'

export function isVNode (node) {
return typeof node === 'object' && Object.prototype.hasOwnProperty.call(node, 'componentOptions')
Expand Down Expand Up @@ -633,7 +634,14 @@ export function getQueryParamString (query) {
export function getParamsValuesMap (params = [], valueKey = 'defaultValue', initValues = {}) {
if (!Array.isArray(params)) return {}
return params.reduce((values, param) => {
if (param.id) {
if (!param.id) return values

if (isFileParam(param.type) && param.enableVersionControl) {
values[param.id] = {
directory: initValues[param.id] ?? param[valueKey],
latestRandomStringInPath: (valueKey === 'defaultValue' ? param.randomStringInPath : param.latestRandomStringInPath) || ''
}
} else {
values[param.id] = initValues[param.id] ?? param[valueKey]
}
return values
Expand Down
9 changes: 6 additions & 3 deletions src/frontend/locale/pipeline/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@
"importPipelineLabel": "Please upload a pipeline JSON/YAML file",
"invalidPipelineJsonOrYaml": "Invalid Pipeline JSON/YAML",
"exportPipelineSuccess": "Export Pipeline Success",
"sizeLimit": "Maximum file size is 100MB. When re-uploading, if the path remains unchanged, there is no need to save the pipeline.",
"sizeLimit": "Upload files up to {0}MB",
"fileUploadSuccess": "Upload Successful",
"empty": "No Data",
"link": "link",
Expand Down Expand Up @@ -1052,7 +1052,7 @@
"codelibConfigs": "Code Repositories Config",
"timerTriggerCodelibTips": "- Git repository: Branch is optional, defaults to the default branch when not specified.\n-SVN repository: Branch is mandatory, must be a first-level subdirectory under the repository root path.",
"timerTriggerBranchTips": "If multiple branches have changes, each branch will trigger once when conditions are met.",
"filePathTips": "Please enter directory, e.g., /a",
"filePathTips": "Please enter the directory where the file is stored, e.g., /a",
"fileNameTips": "File name, leave blank to auto-detect",
"enableDocker": "Enable Docker for Running Build Tasks",
"imagePullPolicy": "Image Pull Policy",
Expand All @@ -1069,7 +1069,10 @@
"lineBreak": "Separate multiple options with line breaks",
"noEnglishCommas": "Each option cannot contain English commas",
"formatSupport": "Similar to the HTML select tag, options support value=name / value formats",
"batchCopy": "One-click Copy"
"batchCopy": "One-click Copy",
"randomlyGenerate": "<Randomly generate>",
"enableVersionControl": "Enable version control",
"versionControlTip": "Once enabled, uploading files will automatically generate versioned paths within the directory to prevent overwriting files with the same name."
},
"storeMap": {
"textarea": "Textarea",
Expand Down
Loading