Files
cjfx/frontend/src/components/dashboard/AccountInputCard.vue

146 lines
3.1 KiB
Vue
Raw Normal View History

2026-03-20 22:59:54 +08:00
<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>