178 lines
4.3 KiB
Vue
178 lines
4.3 KiB
Vue
<template>
|
||
<a-drawer
|
||
placement="right"
|
||
width="760"
|
||
:visible="visible"
|
||
title="成长档案"
|
||
:body-style="{ paddingBottom: '88px' }"
|
||
@update:visible="updateVisible"
|
||
>
|
||
<div class="archive-header">
|
||
<div class="archive-title">{{ props.data?.name || '未命名团员' }}</div>
|
||
<div class="archive-subtitle">
|
||
手机:{{ props.data?.phone || '-' }} | 入团年月:{{ props.data?.joinMonth || '-' }}
|
||
</div>
|
||
</div>
|
||
<div class="archive-card">
|
||
<div
|
||
v-for="(item, index) in growthArchives"
|
||
:key="`archive-${index}`"
|
||
class="archive-item"
|
||
>
|
||
<a-form layout="vertical">
|
||
<a-form-item label="时间">
|
||
<a-date-picker
|
||
v-model:value="item.archiveTime"
|
||
value-format="YYYY-MM-DD"
|
||
style="width: 100%"
|
||
placeholder="请选择时间"
|
||
/>
|
||
</a-form-item>
|
||
<a-form-item label="内容">
|
||
<a-textarea
|
||
v-model:value="item.content"
|
||
:rows="5"
|
||
placeholder="请输入成长档案内容"
|
||
/>
|
||
</a-form-item>
|
||
</a-form>
|
||
<a class="remove-link" @click="removeArchive(index)">删除</a>
|
||
</div>
|
||
<a-button block @click="addArchive">新增成长档案</a-button>
|
||
</div>
|
||
<div class="drawer-footer">
|
||
<a-space>
|
||
<a-button @click="updateVisible(false)">取消</a-button>
|
||
<a-button type="primary" :loading="loading" @click="save">保存</a-button>
|
||
</a-space>
|
||
</div>
|
||
</a-drawer>
|
||
</template>
|
||
|
||
<script lang="ts" setup>
|
||
import { ref, watch } from 'vue';
|
||
import { message } from 'ant-design-vue';
|
||
import { updateTyglGrowthArchives } from '@/api/gxmu/tygl-form';
|
||
import type { TyglForm, TyglGrowthArchive } from '@/api/gxmu/tygl-form/model';
|
||
|
||
const emit = defineEmits<{
|
||
(e: 'done'): void;
|
||
(e: 'update:visible', visible: boolean): void;
|
||
}>();
|
||
|
||
const props = defineProps<{
|
||
visible: boolean;
|
||
data?: TyglForm | null;
|
||
}>();
|
||
|
||
const loading = ref(false);
|
||
const growthArchives = ref<TyglGrowthArchive[]>([]);
|
||
|
||
const createArchive = (): TyglGrowthArchive => ({
|
||
content: '',
|
||
archiveTime: ''
|
||
});
|
||
|
||
watch(
|
||
() => props.visible,
|
||
(visible) => {
|
||
if (visible) {
|
||
growthArchives.value = (props.data?.growthArchives || []).map((item) => ({
|
||
content: item.content || '',
|
||
archiveTime: item.archiveTime || ''
|
||
}));
|
||
} else {
|
||
growthArchives.value = [];
|
||
}
|
||
},
|
||
{ immediate: true }
|
||
);
|
||
|
||
const updateVisible = (value: boolean) => {
|
||
emit('update:visible', value);
|
||
};
|
||
|
||
const addArchive = () => {
|
||
growthArchives.value.push(createArchive());
|
||
};
|
||
|
||
const removeArchive = (index: number) => {
|
||
growthArchives.value.splice(index, 1);
|
||
};
|
||
|
||
const save = () => {
|
||
if (!props.data?.id) {
|
||
message.error('请先保存团员基础信息');
|
||
return;
|
||
}
|
||
loading.value = true;
|
||
updateTyglGrowthArchives(props.data.id, {
|
||
growthArchives: growthArchives.value.filter(
|
||
(item) => (item.content || '').trim() || (item.archiveTime || '').trim()
|
||
)
|
||
})
|
||
.then((msg) => {
|
||
loading.value = false;
|
||
message.success(msg);
|
||
updateVisible(false);
|
||
emit('done');
|
||
})
|
||
.catch((e) => {
|
||
loading.value = false;
|
||
message.error(e.message);
|
||
});
|
||
};
|
||
</script>
|
||
|
||
<style lang="less" scoped>
|
||
.archive-header {
|
||
margin-bottom: 16px;
|
||
padding: 16px;
|
||
border-radius: 8px;
|
||
background: linear-gradient(135deg, #f7fbff 0%, #edf5ff 100%);
|
||
}
|
||
|
||
.archive-title {
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.archive-subtitle {
|
||
margin-top: 8px;
|
||
color: rgba(0, 0, 0, 0.65);
|
||
}
|
||
|
||
.archive-card {
|
||
padding: 16px;
|
||
border: 1px solid #f0f0f0;
|
||
border-radius: 8px;
|
||
background: #fff;
|
||
}
|
||
|
||
.archive-item {
|
||
position: relative;
|
||
margin-bottom: 16px;
|
||
padding: 16px;
|
||
border-radius: 8px;
|
||
background: #fafafa;
|
||
}
|
||
|
||
.remove-link {
|
||
position: absolute;
|
||
top: 16px;
|
||
right: 16px;
|
||
color: #ff4d4f;
|
||
}
|
||
|
||
.drawer-footer {
|
||
position: absolute;
|
||
right: 0;
|
||
bottom: 0;
|
||
width: 100%;
|
||
border-top: 1px solid #f0f0f0;
|
||
padding: 12px 16px;
|
||
background: #fff;
|
||
text-align: right;
|
||
}
|
||
</style>
|