|
@@ -72,7 +72,7 @@
|
|
</el-form-item>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-col>
|
|
<el-col>
|
|
<el-col>
|
|
- <el-form-item label="公告标识">
|
|
|
|
|
|
+ <el-form-item label="标识">
|
|
<el-checkbox v-model="state.ruleForm.isOpen">是否公开</el-checkbox>
|
|
<el-checkbox v-model="state.ruleForm.isOpen">是否公开</el-checkbox>
|
|
<el-checkbox v-model="state.ruleForm.isBold">是否加粗</el-checkbox>
|
|
<el-checkbox v-model="state.ruleForm.isBold">是否加粗</el-checkbox>
|
|
<el-checkbox v-model="state.ruleForm.isOpenWebsite">网站公开</el-checkbox>
|
|
<el-checkbox v-model="state.ruleForm.isOpenWebsite">网站公开</el-checkbox>
|
|
@@ -80,34 +80,90 @@
|
|
<el-checkbox v-model="state.ruleForm.isWeChat">微信公开</el-checkbox>
|
|
<el-checkbox v-model="state.ruleForm.isWeChat">微信公开</el-checkbox>
|
|
<el-checkbox v-model="state.ruleForm.isTop">是否置顶</el-checkbox>
|
|
<el-checkbox v-model="state.ruleForm.isTop">是否置顶</el-checkbox>
|
|
<el-checkbox v-model="state.ruleForm.isPopup">是否飘窗</el-checkbox>
|
|
<el-checkbox v-model="state.ruleForm.isPopup">是否飘窗</el-checkbox>
|
|
- <el-checkbox v-model="state.ruleForm.isSnapshot">是否随手拍</el-checkbox>
|
|
|
|
- </el-form-item>
|
|
|
|
- </el-col>
|
|
|
|
- <el-col>
|
|
|
|
- <el-form-item label="志愿者类型" prop="safetyTypes" :rules="[{ required: true, message: '请选择志愿者类型', trigger: 'change' }]">
|
|
|
|
- <el-checkbox-group v-model="state.ruleForm.safetyTypes">
|
|
|
|
- <el-checkbox :label="item.dicDataName" :value="item.dicDataValue" v-for="item in safetyTypesOptions" :key="item.dicDataValue" />
|
|
|
|
- </el-checkbox-group>
|
|
|
|
- </el-form-item>
|
|
|
|
- </el-col>
|
|
|
|
- <el-col>
|
|
|
|
- <el-form-item label="公告形式" prop="type" :rules="[{ required: true, message: '请选择公告形式', trigger: 'change' }]">
|
|
|
|
- <el-radio-group v-model="state.ruleForm.type">
|
|
|
|
- <el-radio value="1">消息</el-radio>
|
|
|
|
- <el-radio value="2">视频</el-radio>
|
|
|
|
- </el-radio-group>
|
|
|
|
- </el-form-item>
|
|
|
|
- </el-col>
|
|
|
|
- <el-col>
|
|
|
|
- <el-form-item label="视频地址" prop="videoPath" :rules="[{ required: false, message: '请填写视频地址', trigger: 'blur' }]">
|
|
|
|
- <el-input v-model="state.ruleForm.videoPath" placeholder="请填写视频地址" clearable></el-input>
|
|
|
|
- </el-form-item>
|
|
|
|
- </el-col>
|
|
|
|
- <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
|
|
|
- <el-form-item label="公告内容" prop="content" :rules="[{ required: true, message: '请填写公告内容', trigger: 'blur' }]">
|
|
|
|
- <editor v-model:get-html="state.ruleForm.content" placeholder="请填写公告内容" height="450px" />
|
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-col>
|
|
|
|
+ <!-- 安全卫士 -->
|
|
|
|
+ <template v-if="state.ruleForm.bulletinTypeId === 'aqws'">
|
|
|
|
+ <el-col>
|
|
|
|
+ <el-form-item label="志愿者类型" prop="safetyTypeId" :rules="[{ required: true, message: '请选择志愿者类型', trigger: 'change' }]">
|
|
|
|
+ <el-checkbox-group v-model="state.ruleForm.safetyTypeId">
|
|
|
|
+ <el-checkbox :label="item.dicDataName" :value="item.dicDataValue" v-for="item in safetyTypesOptions" :key="item.dicDataValue" />
|
|
|
|
+ </el-checkbox-group>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col>
|
|
|
|
+ <el-form-item label="形式" prop="shape" :rules="[{ required: true, message: '请选择形式', trigger: 'change' }]">
|
|
|
|
+ <el-radio-group v-model="state.ruleForm.shape" @change="selectType">
|
|
|
|
+ <el-radio :value="0">消息</el-radio>
|
|
|
|
+ <el-radio :value="1">视频</el-radio>
|
|
|
|
+ </el-radio-group>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ </el-col>
|
|
|
|
+ </template>
|
|
|
|
+ <template v-if="state.ruleForm.shape === 0">
|
|
|
|
+ <el-col>
|
|
|
|
+ <el-form-item label="视频地址" prop="videoPath" :rules="[{ required: false, message: '请填写视频地址', trigger: 'blur' }]">
|
|
|
|
+ <el-input v-model="state.ruleForm.videoPath" placeholder="请填写视频地址" clearable></el-input>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
|
|
|
+ <el-form-item label="内容" prop="content" :rules="[{ required: true, message: '请填写内容', trigger: 'blur' }]">
|
|
|
|
+ <editor v-model:get-html="state.ruleForm.content" placeholder="请填写内容" height="450px" />
|
|
|
|
+ </el-form-item>
|
|
|
|
+ </el-col>
|
|
|
|
+ </template>
|
|
|
|
+ <template v-else>
|
|
|
|
+ <el-col>
|
|
|
|
+ <el-form-item label="视频封面" prop="videoCoverImgUrl" :rules="[{ required: true, message: '请上传视频封面', trigger: 'change' }]">
|
|
|
|
+ <el-upload
|
|
|
|
+ class="avatar-uploader"
|
|
|
|
+ :action="action"
|
|
|
|
+ :show-file-list="false"
|
|
|
|
+ :on-success="updateSuccessCareCell"
|
|
|
|
+ ref="uploadListRefCareCell"
|
|
|
|
+ name="fileData"
|
|
|
|
+ :on-error="onUploadError1"
|
|
|
|
+ accept="image/*"
|
|
|
|
+ :disabled="uploadingDisabled1"
|
|
|
|
+ :before-upload="beforeUpload1"
|
|
|
|
+ >
|
|
|
|
+ <img v-if="careCellImgUrl" :src="careCellImgUrl" class="avatar" alt="" />
|
|
|
|
+ <SvgIcon v-else class="avatar-uploader-icon" name="ele-Plus" size="28px" />
|
|
|
|
+ <template #tip v-if="uploadLoading1">
|
|
|
|
+ <div class="el-upload__tip"><el-text type="danger">上传中,请稍等...</el-text></div>
|
|
|
|
+ </template>
|
|
|
|
+ </el-upload>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col>
|
|
|
|
+ <el-form-item label="视频上传" prop="videoPath" :rules="[{ required: true, message: '请上传视频', trigger: 'change' }]">
|
|
|
|
+ <el-upload
|
|
|
|
+ ref="uploadVideoRef"
|
|
|
|
+ class="upload-demo w100"
|
|
|
|
+ :action="action"
|
|
|
|
+ :limit="1"
|
|
|
|
+ name="fileData"
|
|
|
|
+ :on-error="onUploadError"
|
|
|
|
+ :on-exceed="handleExceed"
|
|
|
|
+ accept="video/mp4,video/mov"
|
|
|
|
+ :on-success="updateSuccessVideoPath"
|
|
|
|
+ v-model:file-list="fileList"
|
|
|
|
+ :disabled="uploadingDisabled"
|
|
|
|
+ :before-upload="beforeUpload"
|
|
|
|
+ :on-remove="handRemove"
|
|
|
|
+ >
|
|
|
|
+ <template #trigger>
|
|
|
|
+ <el-button type="primary" :loading="uploadLoading" :disabled="uploadingDisabled">
|
|
|
|
+ <SvgIcon name="ele-Upload" class="mr5" /> {{ uploadLoading ? '上传中,请稍等...' : '视频上传' }}
|
|
|
|
+ </el-button>
|
|
|
|
+ </template>
|
|
|
|
+ <template #tip>
|
|
|
|
+ <div class="el-upload__tip">视频上传:支持上传mp4、mov格式的视频</div>
|
|
|
|
+ </template>
|
|
|
|
+ </el-upload>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ </el-col>
|
|
|
|
+ </template>
|
|
</el-row>
|
|
</el-row>
|
|
</el-form>
|
|
</el-form>
|
|
<template #footer>
|
|
<template #footer>
|
|
@@ -120,9 +176,9 @@
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script setup lang="tsx" name="noticeDetail">
|
|
<script setup lang="tsx" name="noticeDetail">
|
|
-import { reactive, ref, defineAsyncComponent } from 'vue';
|
|
|
|
|
|
+import { reactive, ref, defineAsyncComponent, computed } from 'vue';
|
|
import { throttle } from '@/utils/tools';
|
|
import { throttle } from '@/utils/tools';
|
|
-import { ElMessage, FormInstance } from 'element-plus';
|
|
|
|
|
|
+import { ElMessage, FormInstance, genFileId, UploadFile, UploadFiles, UploadProps, UploadRawFile, UploadUserFile } from 'element-plus';
|
|
import { disabledDate } from '@/utils/constants';
|
|
import { disabledDate } from '@/utils/constants';
|
|
import { ElCheckbox } from 'element-plus';
|
|
import { ElCheckbox } from 'element-plus';
|
|
import { addSnapshotBulletin, editSnapshotBulletinBase } from '@/api/snapshot/info';
|
|
import { addSnapshotBulletin, editSnapshotBulletinBase } from '@/api/snapshot/info';
|
|
@@ -152,9 +208,9 @@ const state = reactive<any>({
|
|
content: null, // 内容
|
|
content: null, // 内容
|
|
videoPath: null, // 视频地址
|
|
videoPath: null, // 视频地址
|
|
sourceMode: '1', // 来源方式 默认自建
|
|
sourceMode: '1', // 来源方式 默认自建
|
|
- isSnapshot: false, // 是否随手拍
|
|
|
|
- safetyTypes: [], // 志愿者类型
|
|
|
|
- type: '1', // 公告形式
|
|
|
|
|
|
+ safetyTypeId: [], // 志愿者类型
|
|
|
|
+ shape: 0, // 公告形式
|
|
|
|
+ videoCoverImgUrl: null, // 视频封面
|
|
},
|
|
},
|
|
});
|
|
});
|
|
let loading = ref<boolean>(false); // 加载状态
|
|
let loading = ref<boolean>(false); // 加载状态
|
|
@@ -186,7 +242,109 @@ const changeOrg = () => {
|
|
if (currentNode) state.ruleForm.departmentName = currentNode[0].label;
|
|
if (currentNode) state.ruleForm.departmentName = currentNode[0].label;
|
|
else state.ruleForm.departmentName = null;
|
|
else state.ruleForm.departmentName = null;
|
|
};
|
|
};
|
|
|
|
+// 选择类型
|
|
|
|
+const selectType = () => {
|
|
|
|
+ if (state.ruleForm.shape === 0) {
|
|
|
|
+ state.ruleForm.videoPath = null;
|
|
|
|
+ careCellImgUrl.value = '';
|
|
|
|
+ state.ruleForm.videoCoverImgUrl = null;
|
|
|
|
+ fileList.value = [];
|
|
|
|
+ } else {
|
|
|
|
+ state.ruleForm.content = null;
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+// 上传地址
|
|
|
|
+const action = computed(() => {
|
|
|
|
+ return import.meta.env.VITE_API_UPLOAD_URL + '/file/upload?source=hotline';
|
|
|
|
+});
|
|
|
|
+// 上传视频封面
|
|
|
|
+const uploadLoading1 = ref(false);
|
|
|
|
+const uploadingDisabled1 = ref(false);
|
|
|
|
+const careCellImgUrl = ref('');
|
|
|
|
+const uploadListRefCareCell = ref<RefType>();
|
|
|
|
+const beforeUpload1 = () => {
|
|
|
|
+ uploadingDisabled1.value = true;
|
|
|
|
+ uploadLoading1.value = true; // 模拟上传过程
|
|
|
|
+};
|
|
|
|
+const updateSuccessCareCell = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
|
|
|
|
+ if (response.result.path) {
|
|
|
|
+ careCellImgUrl.value = import.meta.env.VITE_API_UPLOAD_URL + response.result.path;
|
|
|
|
+ // careCellImgUrl.value = URL.createObjectURL(uploadFile.raw!);
|
|
|
|
+ state.ruleForm.videoCoverImgUrl = response.result.path;
|
|
|
|
+ } else {
|
|
|
|
+ uploadListRefCareCell.value.handleRemove(uploadFile);
|
|
|
|
+ ElMessage.error('上传失败');
|
|
|
|
+ }
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ uploadLoading1.value = false; // 模拟上传过程
|
|
|
|
+ uploadingDisabled1.value = false;
|
|
|
|
+ }, 100);
|
|
|
|
+};
|
|
|
|
+// 上传视频
|
|
|
|
+const uploadVideoRef = ref<RefType>();
|
|
|
|
+const fileList = ref<UploadFiles>([
|
|
|
|
+ /*{
|
|
|
|
+ name: '12239_1739325758.mp4',
|
|
|
|
+ url: '/file/files_indefinitely?id=08dd8555-5673-4e45-80eb-12cdc7ac8125&expires=1745739172&clientid=hotline&signature=BF5AD8DBEF553CDA7750BBDF01A07C33689FAB83DB5163CADE787E327E366DD426861371167F86296E6DE9C696F65F3C92F3742DE762EE50',
|
|
|
|
+ },*/
|
|
|
|
+]);
|
|
|
|
+const uploadLoading = ref(false);
|
|
|
|
+const uploadingDisabled = ref(false);
|
|
|
|
+const beforeUpload = () => {
|
|
|
|
+ uploadingDisabled.value = true;
|
|
|
|
+ uploadLoading.value = true; // 模拟上传过程
|
|
|
|
+};
|
|
|
|
+const handleExceed = (files: any, uploadFiles: UploadUserFile[]) => {
|
|
|
|
+ ElMessage.warning(`当前限制最多上传1个文件,已经上传了${uploadFiles.length}个文件,本次选择了 ${files.length} 个文件。`);
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ uploadLoading.value = false; // 模拟上传过程
|
|
|
|
+ }, 100);
|
|
|
|
+};
|
|
|
|
|
|
|
|
+const updateSuccessVideoPath = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
|
|
|
|
+ if (response.result.path) {
|
|
|
|
+ state.ruleForm.videoPath = response.result.path;
|
|
|
|
+ } else {
|
|
|
|
+ uploadVideoRef.value.handleRemove(uploadFile);
|
|
|
|
+ ElMessage.error('上传失败');
|
|
|
|
+ }
|
|
|
|
+ console.log(fileList.value, state.ruleForm.videoPath, '111');
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ uploadLoading.value = false; // 模拟上传过程
|
|
|
|
+ uploadingDisabled.value = false;
|
|
|
|
+ }, 100);
|
|
|
|
+};
|
|
|
|
+// 删除文件
|
|
|
|
+const handRemove = (uploadFile: UploadFile, uploadFiles: UploadFiles) => {
|
|
|
|
+ fileList.value = uploadFiles;
|
|
|
|
+ state.ruleForm.videoPath = null;
|
|
|
|
+};
|
|
|
|
+// 上传失败
|
|
|
|
+const onUploadError = (error: Error) => {
|
|
|
|
+ try {
|
|
|
|
+ const errMessage = JSON.parse(error.message)?.message ?? '上传失败';
|
|
|
|
+ ElMessage.error(errMessage);
|
|
|
|
+ } catch (e) {
|
|
|
|
+ ElMessage.error('上传失败');
|
|
|
|
+ }
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ uploadLoading.value = false; // 模拟上传过程
|
|
|
|
+ uploadingDisabled.value = false;
|
|
|
|
+ }, 100);
|
|
|
|
+};
|
|
|
|
+// 上传失败
|
|
|
|
+const onUploadError1 = (error: Error) => {
|
|
|
|
+ try {
|
|
|
|
+ const errMessage = JSON.parse(error.message)?.message ?? '上传失败';
|
|
|
|
+ ElMessage.error(errMessage);
|
|
|
|
+ } catch (e) {
|
|
|
|
+ ElMessage.error('上传失败');
|
|
|
|
+ }
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ uploadLoading1.value = false; // 模拟上传过程
|
|
|
|
+ uploadingDisabled1.value = false;
|
|
|
|
+ }, 100);
|
|
|
|
+};
|
|
// 保存
|
|
// 保存
|
|
const onSubmit = throttle(async (formEl: FormInstance | undefined) => {
|
|
const onSubmit = throttle(async (formEl: FormInstance | undefined) => {
|
|
if (!formEl) return;
|
|
if (!formEl) return;
|
|
@@ -215,6 +373,7 @@ const closeDialog = () => {
|
|
const close = () => {
|
|
const close = () => {
|
|
ruleFormRef.value?.clearValidate();
|
|
ruleFormRef.value?.clearValidate();
|
|
ruleFormRef.value?.resetFields();
|
|
ruleFormRef.value?.resetFields();
|
|
|
|
+ state.ruleForm.bulletinTypeId = null;
|
|
};
|
|
};
|
|
// 暴露变量
|
|
// 暴露变量
|
|
defineExpose({
|
|
defineExpose({
|
|
@@ -222,3 +381,31 @@ defineExpose({
|
|
closeDialog,
|
|
closeDialog,
|
|
});
|
|
});
|
|
</script>
|
|
</script>
|
|
|
|
+<style scoped lang="scss">
|
|
|
|
+.avatar-uploader .avatar {
|
|
|
|
+ width: 178px;
|
|
|
|
+ height: 178px;
|
|
|
|
+ display: block;
|
|
|
|
+}
|
|
|
|
+</style>
|
|
|
|
+<style>
|
|
|
|
+.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);
|
|
|
|
+}
|
|
|
|
+.avatar-uploader-icon {
|
|
|
|
+ font-size: 28px;
|
|
|
|
+ color: #8c939d;
|
|
|
|
+ width: 178px;
|
|
|
|
+ height: 178px;
|
|
|
|
+ text-align: center;
|
|
|
|
+}
|
|
|
|
+</style>
|