diff --git a/src/api/notification/modify.ts b/src/api/notification/modify.ts index d0faa87..135176c 100644 --- a/src/api/notification/modify.ts +++ b/src/api/notification/modify.ts @@ -3,16 +3,15 @@ import type { Response, NotificationInstance } from '@zvms/zvms4-types' import { ElNotification } from 'element-plus' async function modifyNotification(notification: NotificationInstance, id: string) { - console.log(notification) const result = ( await axios(`/notification/${id}`, { method: 'put', - data: notification + data: { notification } }) ).data as Response if (result.status == 'error') { ElNotification({ - title: '修改通知错误(' + result.code + ')', + title: 'Error when modifying notification' + result.code, message: result.message, type: 'error' }) @@ -21,4 +20,43 @@ async function modifyNotification(notification: NotificationInstance, id: string } } -export { modifyNotification as modify } +async function modifyNotificationTitle(id: string, title: string) { + const result = ( + await axios(`/notification/${id}/title`, { + method: 'put', + data: { title } + }) + ).data as Response + if (result.status == 'error') { + ElNotification({ + title: 'Error when modifying notification title' + result.code, + message: result.message, + type: 'error' + }) + } else { + return result.data + } +} + +async function modifyNotificationContent(id: string, content: string) { + const result = ( + await axios(`/notification/${id}/content`, { + method: 'put', + data: { content } + }) + ).data as Response + if (result.status == 'error') { + ElNotification({ + title: 'Error when modifying notification content' + result.code, + message: result.message, + type: 'error' + }) + } else { + return result.data + } +} + +export const modify = { + title: modifyNotificationTitle, + content: modifyNotificationContent +} diff --git a/src/components/activity/ZActivityImpressionManager.vue b/src/components/activity/ZActivityImpressionManager.vue index 8c10219..3a6268e 100644 --- a/src/components/activity/ZActivityImpressionManager.vue +++ b/src/components/activity/ZActivityImpressionManager.vue @@ -11,7 +11,7 @@ import { Plus, User } from '@element-plus/icons-vue' -import { Save } from '@icon-park/vue-next' +import { ImageFiles, Save } from '@icon-park/vue-next' import type { ActivityMember, ActivityInstance, @@ -32,17 +32,19 @@ import { ElFormItem, ElDivider, ElUpload, - ElCarousel, - ElCarouselItem, ElImage, ElEmpty, ElIcon, - ElNotification + ElNotification, + type UploadUserFile, + ElDialog, + ElScrollbar } from 'element-plus' import { useI18n } from 'vue-i18n' import { ZActivityMember, ZActivityDetails, ZActivityStatus } from '@/components' import api from '@/api' import { baseURL } from '@/plugins/axios' +import { useWindowSize } from '@vueuse/core' const props = defineProps<{ activity: ActivityInstance @@ -51,6 +53,7 @@ const props = defineProps<{ const user = useUserStore() const { t } = useI18n() +const { height } = useWindowSize() const emits = defineEmits<{ (e: 'update:modelValue', value: string): void @@ -60,9 +63,10 @@ const emits = defineEmits<{ const { activity, role } = toRefs(props) const impression = ref('') -const myimages = ref([] as string[]) +const myimages = ref([]) const present = ref() - +const preview = ref(false) +const previewUrl = ref('') const activeNames = ref(['1', '2']) const submitable = ref(role.value !== 'class') @@ -118,7 +122,7 @@ interface ImpressionCursor { _id: string duration: number status: MemberActivityStatus - images: string[] + images: UploadUserFile[] } const current = ref({ @@ -137,20 +141,14 @@ async function getMemberActivity(id: string = user._id) { loading.value = true try { present.value = await api.activity.member.read(activity.value._id, id) - console.log('[DEBUG] present') - console.log(present.value) if (!present.value) { throw new Error('No such member') } if (role.value === 'mine') { impression.value = present.value?.impression - var imglist = present.value?.images.map((x) => `${baseURL}image/${x}/data`) ?? [] - for (var i in imglist) { - myimages.value.push(imglist[i]) - current.value.images.push(imglist[i]) - } - console.log('[DEBUG] myimages') - console.log(myimages.value) + let imglist = present.value?.images.map((x) => `${baseURL}image/${x}/data`) ?? [] + myimages.value.push(...imglist.map((image) => ({ name: image, url: image }))) + current.value.images = myimages.value } } catch (e) { ElNotification({ @@ -169,7 +167,8 @@ async function curserTo(index: number) { (await api.activity.member.read(activity.value._id, activity.value.members[index - 1]._id)) ?? activity.value.members[index - 1] const result = await api.user.readOne(present.value._id) - const images = await api.activity.image.read(activity.value._id, present.value._id) + const images = + present.value?.images.map((x) => ({ name: x, url: `${baseURL}image/${x}/data` })) ?? [] console.log('[DEBUG] images') console.log(images) current.value = { @@ -180,7 +179,7 @@ async function curserTo(index: number) { _id: present.value._id, duration: present.value.duration ?? 0, status: present.value.status, - images: images.map((x) => `${baseURL}image/${x}/data`) + images: images } } catch (e) { ElNotification({ @@ -209,39 +208,6 @@ function handleSuccess(resp: Response) { } } -function handlePreview(imageUrl: string) { - window.open(imageUrl, '_blank') -} - -function downloadIamge(imgsrc: string, name: string) { - //下载图片地址和图片名 - var image = new Image() - // 解决跨域 Canvas 污染问题 - image.setAttribute('crossOrigin', 'anonymous') - image.onload = function () { - var canvas = document.createElement('canvas') - canvas.width = image.width - canvas.height = image.height - var context = canvas.getContext('2d') - if (!context) { - throw new Error('Failed to get canvas context') - } - context.drawImage(image, 0, 0, image.width, image.height) - var url = canvas.toDataURL('image/png') //得到图片的base64编码数据 - - var a = document.createElement('a') // 生成一个a元素 - var event = new MouseEvent('click') // 创建一个单击事件 - a.download = name || 'photo' // 设置图片名称 - a.href = url // 将生成的URL设置为a.href属性 - a.dispatchEvent(event) // 触发a的单击事件 - } - image.src = imgsrc -} - -function handleDownload(imageUrl: string) { - downloadIamge(imageUrl, imageUrl.split('/')[5] ?? 'photo') -} - function getUserToken() { return localStorage.getItem('token') } @@ -404,37 +370,45 @@ function getUserToken() { }" :limit="3" :on-success="handleSuccess" - :file-list="myimages.map((image) => ({ name: image, url: image }))" + :on-preview=" + (file) => { + preview = true + previewUrl = file.url ?? '' + } + " + :file-list="myimages" > - - - - - - - + + + + + + + + + diff --git a/src/components/activity/ZActivityList.vue b/src/components/activity/ZActivityList.vue index 8cd3b38..97d2f18 100644 --- a/src/components/activity/ZActivityList.vue +++ b/src/components/activity/ZActivityList.vue @@ -14,7 +14,7 @@ import { import { onMounted, ref, toRefs, watch } from 'vue' import { useUserStore } from '@/stores/user' import dayjs from 'dayjs' -import { Box, Search, PieChart, Refresh, Plus } from '@element-plus/icons-vue' +import { Box, Search, PieChart, Refresh, Plus, EditPen, View } from '@element-plus/icons-vue' import { useWindowSize } from '@vueuse/core' import { useI18n } from 'vue-i18n' import { getActivity } from './getActivity' @@ -26,6 +26,7 @@ import { ZActivityCard } from '@/components' import { useRouter } from 'vue-router' +import { Write } from '@icon-park/vue-next' const { t } = useI18n() const { width, height } = useWindowSize() @@ -293,12 +294,45 @@ watch( /> diff --git a/src/components/form/ZSelectPerson.vue b/src/components/form/ZSelectPerson.vue index bd23303..1421396 100644 --- a/src/components/form/ZSelectPerson.vue +++ b/src/components/form/ZSelectPerson.vue @@ -41,7 +41,6 @@ async function filter(number: string) { load.value = true const digits = number.replace(/[^0-9]/g, '').length const han = extractHanCharacters(number).length - console.log(digits, han) if (filterStart.value && digits <= (filterStart.value ? filterStart.value : 5) && han < 2) { load.value = false return [] diff --git a/src/components/notifications/ZNotificationCard.vue b/src/components/notifications/ZNotificationCard.vue new file mode 100644 index 0000000..1a46e75 --- /dev/null +++ b/src/components/notifications/ZNotificationCard.vue @@ -0,0 +1,139 @@ + + + diff --git a/src/components/notifications/ZNotificationContentDisplayer.vue b/src/components/notifications/ZNotificationContentDisplayer.vue index 12214d5..b15b79d 100644 --- a/src/components/notifications/ZNotificationContentDisplayer.vue +++ b/src/components/notifications/ZNotificationContentDisplayer.vue @@ -7,7 +7,7 @@ const paras = computed(() => props.content.split('\n')) diff --git a/src/components/notifications/ZNotificationForm.vue b/src/components/notifications/ZNotificationForm.vue index e6a0fcd..499a473 100644 --- a/src/components/notifications/ZNotificationForm.vue +++ b/src/components/notifications/ZNotificationForm.vue @@ -13,7 +13,8 @@ import { ElSelect, ElPageHeader, ElCard, - ElButton + ElButton, + ElNotification } from 'element-plus' import type { NotificationInstance } from '@zvms/zvms4-types' import { ArrowLeft, Refresh, ArrowRight } from '@element-plus/icons-vue' @@ -53,6 +54,22 @@ const submit = () => { // router.push('/notifications/creative/' + portNum) return } + if (notification.value.title === '') { + ElNotification({ + type: 'error', + title: t('validation.notification.title.required') + }) + loading.value = false + return + } + if (!notification.value.global && notification.value?.receivers?.length === 0) { + ElNotification({ + type: 'error', + title: t('validation.notification.receivers.required') + }) + loading.value = false + return + } api.notification.create(notification.value) router.push('/notifications') } @@ -92,7 +109,7 @@ const submit = () => { - + { :rules="[ { required: true, message: t('validation.notification.expire.required') }, { - validator: (rule, value, callback) => { + validator: (rule: any, value: any, callback: any) => { try { if (dayjs(value).isBefore(dayjs(notification.time))) { callback(t('validation.notification.expire.future')) @@ -153,10 +170,21 @@ const submit = () => { v-if="!notification.global" :label="t('notification.create.elements.receivers')" required + prop="receivers" :rules="[ { required: notification.global === false, message: t('validation.notification.receivers.required') + }, + { + validator: (rule: any, value: any, callback: any) => { + console.log(typeof value) + if (value.length == 0) { + callback(t('validation.notification.receivers.required')) + } else { + callback() + } + } } ]" > diff --git a/src/components/notifications/ZNotificationList.vue b/src/components/notifications/ZNotificationList.vue index c649c9c..bfd01ce 100644 --- a/src/components/notifications/ZNotificationList.vue +++ b/src/components/notifications/ZNotificationList.vue @@ -1,6 +1,6 @@