| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 |
- <template>
- <el-container>
- <el-header height="220">
- <h3>仓库认证列表</h3>
- <el-row style="margin-top: 10px">
- <el-button type="success" size="mini" icon="el-icon-plus" @click="handleShowAdd">添加</el-button>
- </el-row>
- </el-header>
- <el-main>
- <el-table
- :data="dataList"
- border
- height="480"
- style="width: 100%"
- >
- <el-table-column
- prop="type"
- label="仓库类型"
- />
- <el-table-column
- prop="name"
- label="认证名字"
- />
- <el-table-column
- prop="authType"
- label="认证类型"
- />
- <el-table-column
- prop="username"
- label="帐号"
- />
- <el-table-column
- prop="password"
- label="密码"
- />
- <el-table-column
- fixed="right"
- label="操作"
- width="120"
- >
- <template slot-scope="scope">
- <el-button
- size="mini"
- type="danger"
- @click="handleEdit(scope.$index, scope.row)"
- >删除</el-button>
- </template>
- </el-table-column>
- </el-table>
- <el-pagination
- background
- :small="screenWidth <= 768"
- layout="prev, pager, next"
- :page-size="pageSize"
- :current-page="currentPage"
- :total="totalSize"
- @current-change="handleCurrentChange"
- @prev-click="handleCurrentChange"
- @next-click="handleCurrentChange"
- />
- </el-main>
- <!-- 添加编译器对话框 -->
- <el-dialog
- title="添加仓库认证"
- append-to-body
- :visible.sync="showAddDialog"
- center
- >
- <div class="compiler-config-steps">
- <el-steps :active="active" finish-status="success" simple style="margin-bottom: 30px">
- <el-step title="基础配置" icon="el-icon-monitor" />
- <el-step title="认证配置" icon="el-icon-edit" />
- </el-steps>
- <el-form ref="form" :model="form" :rules="dynamicRules" label-width="130px">
- <div v-show="active === 0">
- <el-form-item label="认证类型" prop="authType">
- <el-select v-model="form.authType" placeholder="请选择认证类型" style="width: 100%">
- <el-option
- v-for="(item, index) in authTypes"
- :key="index"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="认证名称" prop="name">
- <el-input v-model="form.name" placeholder="例如 git-auth" />
- </el-form-item>
- <el-form-item label="仓库类型" prop="type">
- <el-select v-model="form.type" placeholder="请选择仓库类型" style="width: 100%">
- <el-option
- v-for="(item, index) in repoTypes"
- :key="index"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- </el-form-item>
- </div>
- <div v-show="active === 1">
- <div v-if="form.authType === 'ssh'">
- <el-form-item label="RSA 私钥" prop="rsaPrikey">
- <el-input
- v-model="form.rsaPrikey"
- type="textarea"
- :autosize="{ minRows: 4 }"
- placeholder="请填写 RSA 私钥"
- />
- </el-form-item>
- </div>
- <div v-else-if="form.authType === 'http'">
- <el-form-item label="用户名" prop="username">
- <el-input v-model="form.username" placeholder="请填写用户名" />
- </el-form-item>
- <el-form-item label="密码" prop="password">
- <el-input v-model="form.password" placeholder="请填写密码" />
- </el-form-item>
- </div>
- <div v-else>
- <el-input value="none 认证类型不需要填写任何认证资料" readonly />
- </div>
- </div>
- <el-form-item style="margin-top: 40px">
- <el-button v-if="active > 0" @click="active--">上一步</el-button>
- <el-button v-if="active < 1" type="primary" @click="nextStep">下一步</el-button>
- <el-button v-if="active === 1" type="success" @click="onAddRepoAuth">提交保存</el-button>
- </el-form-item>
- </el-form>
- </div>
- </el-dialog>
- </el-container>
- </template>
- <script>
- import { addRepoAuth, deleteRepoAuth, getRepoAuthList, getRepoTypes } from '@/api/devops'
- export default {
- name: 'RepoAuth',
- data() {
- return {
- queryInfo: {
- scope: null,
- pn: 1
- },
- // 屏幕宽度, 为了控制分页条的大小
- screenWidth: document.body.clientWidth,
- currentPage: 1,
- pageSize: 10,
- totalSize: 0,
- dataList: [],
- // **********************************************************************
- showAddDialog: false,
- active: 0,
- form: {
- authType: 'http',
- name: '',
- type: 'git',
- username: '',
- password: '',
- rsaPrikey: ''
- },
- repoTypes: [],
- authTypes: []
- }
- },
- computed: {
- dynamicRules() {
- const baseRules = {
- type: [{ required: true, message: '请选择仓库类型', trigger: 'blur' }],
- name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
- authType: [{ required: true, message: '请选择认证类型', trigger: 'blur' }]
- }
- // 根据选择的类型增加特定规则
- if (this.form.authType === 'ssh') {
- baseRules.rsaPrikey = [{ required: true, message: 'ssh 认证类型必须填写 RSA 私钥', trigger: 'blur' }]
- } else if (this.form.authType === 'http') {
- baseRules.username = [{ required: true, message: 'http 认证类型必须填写 username', trigger: 'blur' }]
- baseRules.password = [{ required: true, message: 'http 认证类型必须填写 password', trigger: 'blur' }]
- }
- return baseRules
- }
- },
- created() {
- document.title = '仓库认证列表'
- this.getData()
- },
- methods: {
- handleCurrentChange(pageNumber) {
- this.currentPage = pageNumber
- this.getData()
- // 回到顶部
- scrollTo(0, 0)
- },
- getData() {
- this.dataList = []
- getRepoAuthList(this.currentPage).then(resp => {
- if (resp.code === 0) {
- const respData = resp.data
- this.dataList = respData.list
- this.totalSize = respData.totalSize
- } else {
- this.$message.error(resp.msg)
- }
- }).catch(error => {
- this.$message.error(error.message)
- })
- },
- handleShowAdd(index, row) {
- getRepoTypes().then(resp => {
- if (resp.code === 0) {
- this.repoTypes = resp.data.repoTypes
- this.authTypes = resp.data.authTypes
- this.showAddDialog = true
- } else {
- this.$message.error(resp.msg)
- }
- }).catch(error => {
- this.$message.error(error.message)
- })
- },
- onAddRepoAuth1() {
- const formData = new FormData()
- formData.append('type', this.form.type)
- formData.append('name', this.form.name)
- formData.append('authType', this.form.authType)
- formData.append('username', this.form.username)
- formData.append('password', this.form.password)
- addRepoAuth(formData).then(resp => {
- this.$message.info(resp.msg)
- this.getData()
- }).catch(error => {
- this.$message.error(error.message)
- }).finally(() => {
- this.showAddDialog = false
- })
- },
- // 异步校验并跳转
- async nextStep() {
- const stepFields = ['type', 'authType', 'name'] // 第一步需要校验的字段
- try {
- // 关键:将所有字段的校验转为 Promise 数组
- const checkActions = stepFields.map(field => {
- return new Promise((resolve, reject) => {
- this.$refs.form.validateField(field, error => {
- if (error) reject(error)
- else resolve()
- })
- })
- })
- await Promise.all(checkActions)
- this.active++ // 只有全部校验成功才加 1
- } catch (e) {
- this.$message.warning('请检查基础配置是否填写完整')
- }
- },
- onAddRepoAuth() {
- this.$refs.form.validate((valid) => {
- if (valid) {
- // 这里发起 API 请求
- console.log('Final Data:', this.form)
- this.$message.success('仓库认证配置添加成功!')
- // 逻辑处理,如关闭弹窗或跳转列表
- } else {
- return false
- }
- })
- },
- handleEdit(index, row) {
- this.$confirm('确定要删除 ' + row.name + '?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(() => {
- const formData = new FormData()
- formData.append('id', row.id)
- deleteRepoAuth(formData).then(resp => {
- this.$message.info(resp.msg)
- this.getData()
- }).catch(error => {
- this.$message.error(error.message)
- })
- }).catch(() => {
- this.$message({
- type: 'info',
- message: '已取消'
- })
- })
- }
- }
- }
- </script>
- <style scoped>
- .compiler-config-steps {
- max-width: 800px;
- margin: 0 auto;
- padding: 20px;
- background: #fff;
- border-radius: 8px;
- }
- .form-tip {
- font-size: 12px;
- color: #909399;
- line-height: 2;
- }
- /* 使用 ::v-deep 穿透 scoped 限制
- 这是 Vue 2 中兼容性最好的写法,支持 Less/Sass
- */
- ::v-deep .el-textarea__inner {
- font-family: 'Courier New', Courier, monospace;
- background-color: #f8f9fa;
- color: #2c3e50;
- border: 1px solid #dcdfe6;
- }
- /* 鼠标悬停和聚焦时的效果优化 */
- ::v-deep .el-textarea__inner:focus {
- background-color: #fff;
- border-color: #409EFF;
- }
- </style>
|