feat(ECR-011): 昵称、首页贴士与档案 Self 唯一/合盘交叉校验
每账号仅一条 self(migration 40902);合盘只选 TA;账号昵称可改;首页穿衣/颜色/养生贴士。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -14,8 +14,8 @@
|
||||
<HomeArchiveStrip @add="goPlus('add')" />
|
||||
<HomeSelfCard
|
||||
:profile-label="profileLabel"
|
||||
:mood="mood"
|
||||
@open-portrait="router.push('/portrait')"
|
||||
:tips="tips"
|
||||
:loading="tipsLoading"
|
||||
@open-profile="router.push('/profile')"
|
||||
/>
|
||||
|
||||
@@ -40,7 +40,8 @@ const {
|
||||
router,
|
||||
profileLabel,
|
||||
plusOpen,
|
||||
mood,
|
||||
tips,
|
||||
tipsLoading,
|
||||
searchHint,
|
||||
gridRow1,
|
||||
gridRow2,
|
||||
|
||||
@@ -7,7 +7,9 @@ const { api } = vi.hoisted(() => ({
|
||||
authMe: vi.fn(),
|
||||
listImageCardScenes: vi.fn(),
|
||||
getImageCardQuota: vi.fn(),
|
||||
listProfiles: vi.fn(),
|
||||
createProfile: vi.fn(),
|
||||
updateProfile: vi.fn(),
|
||||
drawImageCard: vi.fn(),
|
||||
createOrder: vi.fn(),
|
||||
payMock: vi.fn(),
|
||||
@@ -35,6 +37,7 @@ describe('ImageCardPage', () => {
|
||||
})
|
||||
|
||||
it('boots scenes and draws a card', async () => {
|
||||
api.listProfiles.mockResolvedValue({ items: [] })
|
||||
api.createProfile.mockResolvedValue({ id: 'p1' })
|
||||
api.drawImageCard.mockResolvedValue({
|
||||
scene: '情绪整理',
|
||||
|
||||
@@ -64,8 +64,8 @@
|
||||
v-model="nickname"
|
||||
class="inp"
|
||||
type="text"
|
||||
maxlength="32"
|
||||
placeholder="怎么称呼你"
|
||||
maxlength="16"
|
||||
placeholder="不填则自动生成,如心语岛"
|
||||
/>
|
||||
</label>
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import ProfilePage from './ProfilePage.vue'
|
||||
const { api } = vi.hoisted(() => ({
|
||||
api: {
|
||||
authMe: vi.fn(),
|
||||
authUpdateMe: vi.fn(),
|
||||
listProfiles: vi.fn(),
|
||||
updateProfile: vi.fn(),
|
||||
deleteProfile: vi.fn(),
|
||||
@@ -29,13 +30,15 @@ const RouterLinkStub = defineComponent({
|
||||
describe('ProfilePage', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
api.authMe.mockResolvedValue({ id: 'u1' })
|
||||
api.authMe.mockResolvedValue({ id: 'u1', nickname: '心语岛', phone: '138****0000' })
|
||||
})
|
||||
|
||||
it('shows empty state', async () => {
|
||||
api.listProfiles.mockResolvedValue({ items: [] })
|
||||
const w = mount(ProfilePage, { global: { stubs: { RouterLink: RouterLinkStub } } })
|
||||
await flushPromises()
|
||||
expect(w.text()).toContain('账号昵称')
|
||||
expect(w.text()).toContain('心语岛')
|
||||
expect(w.text()).toContain('暂无档案')
|
||||
})
|
||||
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
</p>
|
||||
|
||||
<template v-else>
|
||||
<AccountNicknameCard
|
||||
:nickname="accountNickname"
|
||||
@updated="onNicknameUpdated"
|
||||
/>
|
||||
|
||||
<ProfileEmpty v-if="!items.length" />
|
||||
|
||||
<template v-else>
|
||||
@@ -85,6 +90,7 @@
|
||||
<script setup lang="ts">
|
||||
import BackButton from '../components/BackButton.vue'
|
||||
import PageShell from '../components/PageShell.vue'
|
||||
import AccountNicknameCard from '../components/profile/AccountNicknameCard.vue'
|
||||
import ProfileAddForm from '../components/profile/ProfileAddForm.vue'
|
||||
import ProfileBottomCta from '../components/profile/ProfileBottomCta.vue'
|
||||
import ProfileEditForm from '../components/profile/ProfileEditForm.vue'
|
||||
@@ -95,6 +101,8 @@ import ProfileSelfCard from '../components/profile/ProfileSelfCard.vue'
|
||||
import { useProfilePage } from '../composables/useProfilePage'
|
||||
|
||||
const {
|
||||
accountNickname,
|
||||
onNicknameUpdated,
|
||||
items,
|
||||
loading,
|
||||
error,
|
||||
|
||||
@@ -110,4 +110,20 @@ describe('SynastryPage', () => {
|
||||
await flushPromises()
|
||||
expect(w.text()).toContain('组合次限')
|
||||
})
|
||||
|
||||
it('hides duplicate self from TA pick list', async () => {
|
||||
api.listProfiles.mockResolvedValue({
|
||||
items: [
|
||||
{ id: 'a1', relation: 'self', display_name: '我', birth_date: '1990-05-12' },
|
||||
{ id: 'a2', relation: 'self', display_name: '我', birth_date: '1991-01-01' },
|
||||
{ id: 'b1', relation: 'other', display_name: '伴侣', birth_date: '1992-08-20' },
|
||||
],
|
||||
})
|
||||
const w = mount(SynastryPage)
|
||||
await flushPromises()
|
||||
const chips = w.findAll('.chip-name').map((n) => n.text())
|
||||
expect(chips.filter((t) => t === '我')).toHaveLength(0)
|
||||
expect(chips).toContain('伴侣')
|
||||
expect(chips).toContain('添加档案')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
:nearby="nearby"
|
||||
:adding="adding"
|
||||
:loading="loading"
|
||||
:profiles="profiles"
|
||||
:self-profiles="selfProfiles"
|
||||
:invite-highlight="inviteHighlight"
|
||||
:inviting="inviting"
|
||||
:nearby-loading="nearbyLoading"
|
||||
@@ -107,7 +107,6 @@ const {
|
||||
nearbyHint,
|
||||
invitePath,
|
||||
inviteHighlight,
|
||||
profiles,
|
||||
nearby,
|
||||
profileA,
|
||||
profileB,
|
||||
@@ -126,6 +125,7 @@ const {
|
||||
showQuickAdd,
|
||||
needsSubTab,
|
||||
pickableProfiles,
|
||||
selfProfiles,
|
||||
profileAName,
|
||||
selfInitial,
|
||||
profileInitial,
|
||||
|
||||
Reference in New Issue
Block a user