jscdn.ink/dist/views/request.vue

383 lines
9.1 KiB
Vue
Raw Normal View History

2023-02-09 19:07:54 +08:00
<template>
<main class="packages">
<div class="toolbar">
<wc-input
v-model="filter"
placeholder="请输入开源库的名字"
@submit="search"
/>
2023-05-26 00:13:20 +08:00
2023-05-25 17:30:41 +08:00
<wc-switch v-model="onlyShowWaited" @change="search"
2023-02-09 19:07:54 +08:00
>只显示待审核</wc-switch
>
<wc-link type="info" @click="openDialog">
没找到你想的库?点击申请收录
</wc-link>
</div>
2023-05-25 17:30:41 +08:00
2023-02-09 19:07:54 +08:00
<wc-table class="list" :thead="thead">
<wc-tr v-for="it of list" :key="it.id">
2023-03-09 19:27:42 +08:00
<wc-td align="center">
<router-link :to="'/?name=' + it.id">{{ it.id }}</router-link>
</wc-td>
2023-02-09 19:07:54 +08:00
<wc-td align="center">{{ it.author }}</wc-td>
2023-02-12 22:35:30 +08:00
<wc-td align="center">{{ it.latest || '-' }}</wc-td>
<wc-td align="center">{{ it.latest ? it.sync_date : '-' }}</wc-td>
2023-02-09 19:07:54 +08:00
<wc-td align="center">{{ $store.stats[it.stat] }}</wc-td>
2023-02-12 22:35:30 +08:00
<wc-td>{{ it.remark || '-' }}</wc-td>
2023-02-10 17:03:51 +08:00
<wc-td align="center">
2023-02-10 18:26:10 +08:00
<wc-link
2023-03-09 19:42:22 +08:00
v-if="it.stat === 2"
:disabled="loading"
2023-02-10 18:31:08 +08:00
@click="handlePackgae('sync', it.id)"
2023-02-10 18:26:10 +08:00
type="info"
2023-02-10 17:03:51 +08:00
>更新</wc-link
>
<wc-link
2023-02-12 22:35:30 +08:00
v-if="$store.user.admin && it.stat !== 2"
2023-02-10 17:03:51 +08:00
@click="handlePackgae('accept', it.id)"
type="info"
2023-02-09 19:07:54 +08:00
>通过</wc-link
>
2023-02-10 17:03:51 +08:00
<wc-link
2023-03-09 19:42:22 +08:00
v-if="$store.user.admin && it.stat !== 0"
2023-02-10 17:03:51 +08:00
@click="handlePackgae('reject', it.id)"
type="warning"
2023-02-09 19:07:54 +08:00
>拒绝</wc-link
>
2023-02-10 17:03:51 +08:00
<wc-link
2023-03-09 19:42:22 +08:00
v-if="$store.user.admin && it.stat !== 0"
2023-02-10 17:03:51 +08:00
@click="handlePackgae('delete', it.id)"
type="danger"
2023-02-09 19:07:54 +08:00
>删除</wc-link
>
</wc-td>
</wc-tr>
</wc-table>
<wc-pager
class="pager"
2023-04-21 10:53:54 +08:00
layout="prev,pages,next,info"
2023-02-09 19:07:54 +08:00
red
2023-05-26 00:13:20 +08:00
@page-changed="pageChanged"
2023-02-09 19:07:54 +08:00
:total="total"
:page="page"
/>
</main>
<wc-layer ref="form" mask mask-close>
<div class="request-form">
<header class="title">申请收录开源库</header>
<content class="content">
<section class="field">
<span class="label">开源库名称:</span>
<wc-input v-model="lib.name" @input="autoUpdateInfo" />
</section>
<section class="field">
<span class="label">作者:</span>
<span class="value">{{ lib.author }}</span>
</section>
<section class="field">
<span class="label">简介:</span>
<span class="value">{{ lib.description }}</span>
</section>
<section class="field">
<span class="label">最新版本:</span>
<span class="value">{{ lib.latest }}</span>
</section>
<section class="field center">
<wc-button
type="danger"
:disabled="disabled"
:loading="loading"
@click="submit"
>提交申请</wc-button
>
</section>
</content>
</div>
</wc-layer>
</template>
2022-12-29 19:05:15 +08:00
<script>
2023-02-12 22:35:30 +08:00
import '//jscdn.ink/@bytedo/wcui/1.0.12/table/index.js'
2023-02-08 19:09:58 +08:00
import fetch from '@/lib/fetch.js'
2022-12-29 19:05:15 +08:00
export default {
data() {
return {
2023-02-08 19:09:58 +08:00
content: '这是关于我们页面',
2023-02-09 19:07:54 +08:00
list: [],
thead: JSON.stringify([
'开源库',
'作者',
2023-02-12 22:35:30 +08:00
'最后同步版本',
2023-02-09 19:07:54 +08:00
'最后同步日期',
'收录状态',
2023-02-10 17:03:51 +08:00
'备注',
'操作'
2023-02-09 19:07:54 +08:00
]),
page: 1,
total: 0,
filter: '',
onlyShowWaited: false,
loading: false,
disabled: true,
lib: {
name: '',
author: '-',
description: '-',
latest: '-'
}
2022-12-29 19:05:15 +08:00
}
},
mounted() {
this.$store.searchShow = false
2023-02-08 19:09:58 +08:00
2023-02-09 19:07:54 +08:00
this.fetchList()
},
methods: {
fetchList() {
fetch('/package/list').then(r => {
2023-02-10 17:03:51 +08:00
this.$list = r.data.map(
it => ((it.sync_date = new Date(it.sync_date).format('Y/m/d')), it)
)
2023-03-09 19:27:42 +08:00
this.fetchPage()
this.total = this.$list.length
2023-02-09 19:07:54 +08:00
})
},
2023-03-09 19:27:42 +08:00
fetchPage() {
let start = (this.page - 1) * 20
let end = start + 20
this.list = this.$list
.filter(it => (this.onlyShowWaited ? it.stat === 1 : true))
.slice(start, end)
},
pageChanged(ev) {
2023-05-26 00:13:20 +08:00
this.page = ev.data
console.log('<><><>', this.page)
2023-03-09 19:27:42 +08:00
this.fetchPage()
},
2023-02-09 19:07:54 +08:00
search() {
let filter = this.filter.trim()
let onlyShowWaited = this.onlyShowWaited
if (filter) {
this.list = this.$list.filter(
it =>
it.id.indexOf(filter) > -1 &&
(onlyShowWaited ? it.stat === 1 : true)
)
} else {
this.list = this.$list.filter(it =>
onlyShowWaited ? it.stat === 1 : true
)
}
this.total = this.list.length
},
openDialog() {
2023-02-10 17:03:51 +08:00
if (this.$store.user.id) {
this.$refs.form.show()
} else {
layer.confirm('你还没有登录, 请先登录之后, 再申请').then(_ => {
localStorage.setItem('login_callback_path', this.$route.path)
this.$router.push('/login')
})
}
2023-02-09 19:07:54 +08:00
},
resetForm(force) {
force && (this.lib.name = '')
this.lib.author = '-'
this.lib.description = '-'
this.lib.latest = '-'
this.disabled = true
},
autoUpdateInfo() {
let name = this.lib.name.trim()
clearTimeout(this.$timer)
if (name) {
if (name.startsWith('@') && name.indexOf('/') === -1) {
return
}
this.$timer = setTimeout(_ => {
this.getPackageInfo(name)
}, 800)
}
},
getPackageInfo(name) {
return fetch('https://registry.npmmirror.com/' + name)
.then(r => {
let author = r.author
? r.author.name
: r.maintainers
? r.maintainers[0].name
: 'unknow'
this.lib.author = author
2023-02-12 22:35:30 +08:00
this.lib.description = r.description || r.homepage
2023-02-09 19:07:54 +08:00
this.lib.latest = r['dist-tags'].latest
this.disabled = false
return {
author,
2023-02-12 22:35:30 +08:00
description: this.lib.description,
2023-02-09 19:07:54 +08:00
latest: r['dist-tags'].latest
}
})
.catch(_ => {
this.resetForm()
layer.toast(
`开源库【${name}】在npm上找不到, 请确认名称是否正确`,
'error'
)
})
},
uploadPackge(body) {
fetch('/package/upload', { method: 'post', body })
.then(r => {
layer.toast('提交成功,等待审核', 'success')
this.resetForm(true)
this.fetchList()
this.$refs.form.close()
})
.catch(e => {
layer.toast(e.msg, 'error')
})
},
submit() {
let name = this.lib.name.trim()
if (name) {
if (name.startsWith('@') && name.indexOf('/') === -1) {
return
}
this.loading = true
this.getPackageInfo(name)
.then(({ author, description, latest }) => {
//
this.uploadPackge({ name, author, description, latest })
})
.finally(_ => (this.loading = false))
} else {
layer.toast(`请填写正确的名称`, 'warning')
}
},
handlePackgae(act, id) {
2023-02-10 17:03:51 +08:00
if (act !== 'sync' && !this.$store.user.admin) {
return layer.alert('别闹, 老实等管理员通过~~')
}
2023-02-10 18:26:10 +08:00
let req
if (act === 'reject' || act === 'delete') {
req = layer.prompt('请输入理由').then(remark => {
return fetch(`/package/${act}/${encodeURIComponent(id)}`, {
method: 'PUT',
body: { remark }
})
})
} else if (act === 'accept') {
2023-02-12 22:35:30 +08:00
req = layer.prompt('请输入文件目录', 'dist').then(dist => {
2023-02-10 18:26:10 +08:00
return fetch(`/package/${act}/${encodeURIComponent(id)}`, {
method: 'PUT',
body: { dist }
})
})
} else {
req = fetch(`/package/${act}/${encodeURIComponent(id)}`, {
method: 'PUT'
})
}
2023-02-12 22:35:30 +08:00
this.loading = true
2023-02-10 18:26:10 +08:00
req
2023-02-09 19:07:54 +08:00
.then(r => {
layer.toast('操作成功', 'success')
this.fetchList()
})
.catch(r => {
2023-02-10 18:26:10 +08:00
r && layer.toast(r.msg, 'error')
2023-02-09 19:07:54 +08:00
})
2023-02-12 22:35:30 +08:00
.finally(_ => (this.loading = false))
2023-02-09 19:07:54 +08:00
}
2022-12-29 19:05:15 +08:00
}
}
</script>
2023-02-09 19:07:54 +08:00
<style lang="scss" scoped>
.packages {
display: flex;
flex-direction: column;
align-items: center;
padding-top: 16px;
.toolbar,
.list {
width: 1024px;
}
.toolbar {
display: flex;
justify-content: space-between;
align-items: center;
margin: 16px 0;
wc-input {
width: 480px;
}
wc-link {
height: 20px;
}
}
.pager {
margin-top: 16px;
}
}
.request-form {
width: 640px;
2023-04-21 10:53:54 +08:00
background: #fff;
2023-02-09 19:07:54 +08:00
.title {
display: flex;
align-items: center;
height: 48px;
padding: 0 16px;
font-size: 20px;
color: var(--color-grey-3);
}
.content {
padding: 16px 16px 32px;
.field {
display: flex;
align-items: center;
margin-top: 12px;
&.center {
margin-top: 16px;
justify-content: center;
}
.label {
width: 120px;
}
wc-input,
.value {
flex: 1;
}
}
}
}
</style>