| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- <!--
- * @since: 2024-12-30
- * BasicInfo.vue
- -->
- <template>
- <CardLayout title="基础配置" :isShowWraning="false" :mandatory="false">
- <el-form
- ref="ruleFormRef"
- style="max-width: 600px"
- label-width="auto"
- :model="ruleForm"
- :rules="formRules"
- :label-position="labelPosition"
- class="el-form-outer"
- >
- <el-form-item label="消息样式: " prop="messageType">
- <el-radio-group v-model="ruleForm.messageType" :disabled="isDisabled">
- <el-radio :value="item.value" v-for="item in messageTypeOptions" :key="item.value"
- >{{ item.label }}
- </el-radio>
- </el-radio-group>
- </el-form-item>
- <el-form-item label="消息标题: " prop="title">
- <el-input
- v-model="ruleForm.title"
- placeholder="请输入20字以内的消息标题"
- maxlength="20"
- show-word-limit
- :disabled="isDisabled"
- />
- </el-form-item>
- <el-form-item
- label="Banner图片: "
- prop="bannerUrl"
- v-if="ruleForm.messageType === MessageTypeEnum.BANNER"
- >
- <img v-if="ruleForm.bannerUrl" :src="ruleForm.bannerUrl" class="avatar" />
- <el-upload
- v-else
- class="avatar-uploader"
- :action="actionUrl"
- :headers="getHeaders()"
- :data="{ bizType: 'PROBLEM_REPORT' }"
- :show-file-list="false"
- :on-success="handleAvatarSuccess"
- :before-upload="beforeAvatarUpload"
- >
- <el-icon class="avatar-uploader-icon"><Plus /></el-icon>
- </el-upload>
- </el-form-item>
- <el-form-item label="推送渠道: " prop="pushChannel">
- <el-checkbox-group v-model="ruleForm.pushChannel">
- <el-checkbox
- v-for="item in pushChannelName"
- :key="item.value"
- :value="item.value"
- :label="item.label"
- :disabled="isDisabled"
- />
- </el-checkbox-group>
- </el-form-item>
- <el-form-item label="失效时间: " prop="expirationTime">
- <el-date-picker
- v-model="ruleForm.expirationTime"
- type="datetime"
- placeholder="请选择失效时间"
- format="YYYY/MM/DD hh:mm:ss"
- value-format="YYYY-MM-DD hh:mm:ss"
- :disabled="isDisabled"
- />
- </el-form-item>
- <PushObject
- ref="childFromRef"
- :recipientType="ruleForm.recipientType"
- :userGroupList="ruleForm.userGroupList"
- :customUserList="ruleForm.customUserList"
- :disabled="isDisabled"
- />
- </el-form>
- </CardLayout>
- </template>
- <script setup lang="ts">
- import { ref, watch, computed, unref } from 'vue';
- import type { FormInstance, FormProps, FormRules, UploadProps } from 'element-plus';
- import { ElMessage } from 'element-plus';
- import { Plus } from '@element-plus/icons-vue';
- import PushObject from '../../components/PushObject.vue';
- import CardLayout from './CardLayout.vue';
- import { RuleFormView, MessageTypeEnum, RuleFormAdd } from '../type';
- import { messageTypeOptions, pushChannelName } from '../../constant';
- import urlJoin from 'url-join';
- import { useGlobSetting } from '@/hooks/setting';
- import { getHeaders } from '@/utils/http/axios';
- const { urlPrefix } = useGlobSetting();
- interface Props {
- dataSoure: RuleFormView;
- isDisabled: boolean;
- }
- const props = defineProps<Props>();
- const labelPosition = ref<FormProps['labelPosition']>('left');
- const childFromRef = ref<InstanceType<typeof PushObject>>();
- const actionUrl = computed(() => {
- return urlJoin(urlPrefix!, `/issue/uploadPicture`);
- });
- /**
- * 表单相关操作
- */
- type Rule = Omit<RuleFormView, 'introduction' | 'contentType' | 'content' | 'contentUrl' | 'operator'>;
- const formRules: FormRules<Rule> = {
- messageType: [{ required: true, trigger: 'change', message: '请选择消息样式' }],
- title: [{ required: true, trigger: 'change', message: '请输入消息标题' }],
- pushChannel: [{ required: true, trigger: 'change', message: '请选择推送渠道' }],
- recipientType: [{ required: true, trigger: 'change', message: '请选择推送对象' }],
- bannerUrl: [{ required: true, trigger: 'change', message: '请选择banner图片' }],
- };
- const ruleForm = ref<Rule>({
- messageType: MessageTypeEnum.BANNER,
- title: '',
- bannerUrl:'',
- pushChannel: [],
- expirationTime: '',
- recipientType: 1, // 默认全员
- userGroupList:[],
- customUserList: [],
- });
- watch(
- () => props.dataSoure,
- (value) => {
- if (value) {
- ruleForm.value = { ...value };
- }
- },
- {
- immediate: true,
- deep: true,
- },
- );
- const ruleFormRef = ref<FormInstance>();
- const isValidate = ref<boolean>();
- const validate = async () => {
- if (!ruleFormRef.value) return;
- try {
- const isSuccess = await ruleFormRef.value.validate();
- if (isSuccess) {
- const childValue = childFromRef.value!.getChildValue();
- childFromRef.value!.submitForm().then((res) => {
- isValidate.value = res;
- });
- const basicInfo = { ...unref(ruleForm) } as RuleFormAdd;
- if (childValue) {
- basicInfo.recipientType = childValue.recipientType!;
- basicInfo.userGroupList = childValue.userGroupList!;
- basicInfo.customUserList = childValue.customUserList!;
- }
- return basicInfo;
- }
- } catch (error) {
- ElMessage.error('请完善信息填写');
- throw error;
- }
- };
- const handleAvatarSuccess: UploadProps['onSuccess'] = (response) => {
- // 注意,这里 response 是 没有被拦截处理
- ruleForm.value.bannerUrl = response.data.url;
- console.log(ruleForm.value);
- };
- const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
- if (!['image/jpeg', 'image/png'].includes(rawFile.type)) {
- ElMessage.error('Avatar picture must be JPG format!');
- return false;
- } else if (rawFile.size / 1024 / 1024 > 5) {
- ElMessage.error('Avatar picture size can not exceed 2MB!');
- return false;
- }
- return true;
- };
- defineExpose({ validate });
- </script>
- <style scoped lang="scss">
- .avatar-uploader .avatar {
- width: 58px;
- height: 58px;
- display: block;
- }
- .avatar-uploader .el-upload {
- border: 1px dashed var(--el-border-color);
- border-radius: 6px;
- cursor: pointer;
- position: relative;
- overflow: hidden;
- transition: var(--el-transition-duration-fast);
- }
- .avatar-uploader .el-upload:hover {
- border-color: var(--el-color-primary);
- }
- .el-icon.avatar-uploader-icon {
- font-size: 28px;
- color: #8c939d;
- width: 58px;
- height: 58px;
- text-align: center;
- }
- </style>
|