146 lines
3.1 KiB
Vue
146 lines
3.1 KiB
Vue
<script setup lang="ts">
|
|
import { computed } from 'vue'
|
|
import type { DailyInputAccount } from '../../types'
|
|
|
|
interface Props {
|
|
account: DailyInputAccount
|
|
disabled?: boolean
|
|
}
|
|
|
|
const props = defineProps<Props>()
|
|
|
|
const emit = defineEmits<{
|
|
updateLinks: [{ accountId: string; links: string[] }]
|
|
}>()
|
|
|
|
const displayLinks = computed(() => (
|
|
props.account.links.length > 0 ? props.account.links : ['']
|
|
))
|
|
|
|
const filledCount = computed(() => props.account.links.filter((link) => link.trim()).length)
|
|
|
|
function commit(links: string[]) {
|
|
emit('updateLinks', { accountId: props.account.account_id, links })
|
|
}
|
|
|
|
function updateLink(index: number, value: string) {
|
|
const nextLinks = displayLinks.value.slice()
|
|
nextLinks[index] = value
|
|
commit(nextLinks)
|
|
}
|
|
|
|
function addLink() {
|
|
commit([...props.account.links, ''])
|
|
}
|
|
|
|
function removeLink(index: number) {
|
|
const nextLinks = displayLinks.value.slice()
|
|
nextLinks.splice(index, 1)
|
|
commit(nextLinks)
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<article class="account-card">
|
|
<div class="card-head">
|
|
<div>
|
|
<h3 class="card-title">{{ props.account.account_name }}</h3>
|
|
<p class="card-note">已录入 {{ filledCount }} 条链接</p>
|
|
</div>
|
|
<button class="add-button" type="button" :disabled="props.disabled" @click="addLink">
|
|
+ 添加
|
|
</button>
|
|
</div>
|
|
|
|
<div class="link-list hide-scrollbar">
|
|
<div v-for="(link, index) in displayLinks" :key="`${props.account.account_id}-${index}`" class="link-row">
|
|
<input
|
|
class="link-input"
|
|
:disabled="props.disabled"
|
|
:value="link"
|
|
type="url"
|
|
placeholder="粘贴公众号文章链接"
|
|
@input="updateLink(index, ($event.target as HTMLInputElement).value)"
|
|
/>
|
|
<button
|
|
class="remove-button"
|
|
type="button"
|
|
:disabled="props.disabled"
|
|
@click="removeLink(index)"
|
|
>
|
|
删除
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.account-card {
|
|
display: grid;
|
|
grid-template-rows: auto 1fr;
|
|
gap: 14px;
|
|
min-height: 0;
|
|
height: 100%;
|
|
padding: 18px;
|
|
border: 1px solid var(--line-soft);
|
|
border-radius: var(--radius-md);
|
|
background: rgba(255, 249, 241, 0.92);
|
|
}
|
|
|
|
.card-head {
|
|
display: flex;
|
|
align-items: start;
|
|
justify-content: space-between;
|
|
gap: 12px;
|
|
}
|
|
|
|
.card-title {
|
|
margin: 0;
|
|
font-size: 17px;
|
|
color: var(--ink-strong);
|
|
}
|
|
|
|
.card-note {
|
|
margin: 6px 0 0;
|
|
font-size: 12px;
|
|
color: var(--ink-soft);
|
|
}
|
|
|
|
.add-button,
|
|
.remove-button {
|
|
flex: 0 0 auto;
|
|
padding: 8px 12px;
|
|
border-radius: 999px;
|
|
background: rgba(0, 0, 0, 0.05);
|
|
color: var(--ink-main);
|
|
}
|
|
|
|
.link-list {
|
|
display: grid;
|
|
align-content: start;
|
|
gap: 10px;
|
|
min-height: 0;
|
|
overflow: auto;
|
|
}
|
|
|
|
.link-row {
|
|
display: grid;
|
|
grid-template-columns: minmax(0, 1fr) auto;
|
|
gap: 10px;
|
|
}
|
|
|
|
.link-input {
|
|
width: 100%;
|
|
padding: 12px 14px;
|
|
border: 1px solid var(--line-soft);
|
|
border-radius: var(--radius-sm);
|
|
background: rgba(255, 255, 255, 0.75);
|
|
outline: none;
|
|
}
|
|
|
|
.link-input:focus {
|
|
border-color: rgba(143, 90, 45, 0.36);
|
|
}
|
|
</style>
|