添加批阅功能

This commit is contained in:
yangjun 2024-10-08 08:29:29 +08:00
parent 892830bf59
commit ce86a4d849
9 changed files with 654 additions and 32 deletions

View File

@ -0,0 +1,39 @@
<template>
<Tinymce v-bind="bindProps" @change="onChange" />
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue';
import { Tinymce } from '/@/components/Tinymce/index2';
import { propTypes } from '/@/utils/propTypes';
export default defineComponent({
name: 'JEditor',
// attrs html
inheritAttrs: false,
components: { Tinymce },
props: {
value: propTypes.string.def(''),
disabled: propTypes.bool.def(false),
},
emits: ['change', 'update:value'],
setup(props, { emit, attrs }) {
// props attrs
const bindProps = computed(() => Object.assign({}, props, attrs));
// value change
function onChange(value) {
emit('change', value);
emit('update:value', value);
}
return {
bindProps,
onChange,
};
},
});
</script>
<style lang="less" scoped></style>

View File

@ -0,0 +1,4 @@
import { withInstall } from '/@/utils/index';
import tinymce from './src/Editor2.vue';
export const Tinymce = withInstall(tinymce);

View File

@ -90,7 +90,7 @@
height: { height: {
type: [Number, String] as PropType<string | number>, type: [Number, String] as PropType<string | number>,
required: false, required: false,
default: 400, default: 220,
}, },
width: { width: {
type: [Number, String] as PropType<string | number>, type: [Number, String] as PropType<string | number>,

View File

@ -0,0 +1,331 @@
<template>
<div :class="prefixCls" :style="{ width: containerWidth }">
<ImgUpload
:fullscreen="fullscreen"
@uploading="handleImageUploading"
@done="handleDone"
v-if="showImageUpload"
v-show="editorRef"
:disabled="disabled"
/>
<textarea :id="tinymceId" ref="elRef" :style="{ visibility: 'hidden' }" v-if="!initOptions.inline"></textarea>
<slot v-else></slot>
</div>
</template>
<script lang="ts">
import type { Editor, RawEditorSettings } from 'tinymce2';
import tinymce from 'tinymce/tinymce';
import { defineComponent, computed, nextTick, ref, unref, watch, onDeactivated, onBeforeUnmount } from 'vue';
import ImgUpload from './ImgUpload.vue';
import { toolbar, plugins, simplePlugins, simpleToolbar, menubar } from './tinymce2';
import { buildShortUUID } from '/@/utils/uuid';
import { bindHandlers } from './helper';
import { onMountedOrActivated } from '/@/hooks/core/onMountedOrActivated';
import { useDesign } from '/@/hooks/web/useDesign';
import { isNumber } from '/@/utils/is';
import { useLocale } from '/@/locales/useLocale';
import { useAppStore } from '/@/store/modules/app';
import { uploadFile } from '/@/api/common/api';
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
const tinymceProps = {
options: {
type: Object as PropType<Partial<RawEditorSettings>>,
default: {},
},
value: {
type: String,
},
toolbar: {
type: [Array as PropType<string[]>, String],
default: toolbar,
},
plugins: {
type: Array as PropType<string[]>,
default: plugins,
},
menubar: {
type: [Object, String],
default: menubar,
},
modelValue: {
type: String,
},
height: {
type: [Number, String] as PropType<string | number>,
required: false,
default: 120,
},
width: {
type: [Number, String] as PropType<string | number>,
required: false,
default: 'auto',
},
showImageUpload: {
type: Boolean,
default: true,
},
};
export default defineComponent({
name: 'Tinymce',
components: { ImgUpload },
inheritAttrs: false,
props: tinymceProps,
emits: ['change', 'update:modelValue', 'inited', 'init-error'],
setup(props, { emit, attrs }) {
const editorRef = ref<Nullable<Editor>>(null);
const fullscreen = ref(false);
const tinymceId = ref<string>(buildShortUUID('tiny-vue'));
const elRef = ref<Nullable<HTMLElement>>(null);
const { prefixCls } = useDesign('tinymce-container');
const appStore = useAppStore();
const tinymceContent = computed(() => props.modelValue);
const containerWidth = computed(() => {
const width = props.width;
if (isNumber(width)) {
return `${width}px`;
}
return width;
});
const skinName = computed(() => {
return appStore.getDarkMode === 'light' ? 'jeecg' : 'oxide-dark';
});
const langName = computed(() => {
const lang = useLocale().getLocale.value;
return ['zh_CN', 'en'].includes(lang) ? lang : 'zh_CN';
});
const initOptions = computed((): RawEditorSettings => {
const { height, options, toolbar, plugins, menubar } = props;
const publicPath = import.meta.env.VITE_PUBLIC_PATH || '/';
return {
selector: `#${unref(tinymceId)}`,
height,
toolbar,
menubar: menubar,
plugins,
language_url: publicPath + 'resource/tinymce/langs/' + langName.value + '.js',
language: langName.value,
branding: false,
default_link_target: '_blank',
link_title: false,
object_resizing: true,
toolbar_mode: 'sliding',
auto_focus: true,
toolbar_groups: true,
skin: skinName.value,
skin_url: publicPath + 'resource/tinymce/skins/ui/' + skinName.value,
images_upload_handler: (blobInfo, success) => {
let params = {
file: blobInfo.blob(),
filename: blobInfo.filename(),
data: { biz: 'jeditor', jeditor: '1' },
};
const uploadSuccess = (res) => {
if (res.success) {
if (res.message == 'local') {
const img = 'data:image/jpeg;base64,' + blobInfo.base64();
success(img);
} else {
let img = getFileAccessHttpUrl(res.message);
success(img);
}
}
};
uploadFile(params, uploadSuccess);
},
content_css: publicPath + 'resource/tinymce/skins/ui/' + skinName.value + '/content.min.css',
...options,
setup: (editor: Editor) => {
editorRef.value = editor;
editor.on('init', (e) => initSetup(e));
},
};
});
const disabled = computed(() => {
const { options } = props;
const getdDisabled = options && Reflect.get(options, 'readonly');
const editor = unref(editorRef);
// update-begin-author:taoyan date:20220407 for: disabled
if (editor) {
editor.setMode(getdDisabled || attrs.disabled === true ? 'readonly' : 'design');
}
if (attrs.disabled === true) {
return true;
}
// update-end-author:taoyan date:20220407 for: disabled
return getdDisabled ?? false;
});
watch(
() => attrs.disabled,
() => {
const editor = unref(editorRef);
if (!editor) {
return;
}
editor.setMode(attrs.disabled ? 'readonly' : 'design');
}
);
onMountedOrActivated(() => {
if (!initOptions.value.inline) {
tinymceId.value = buildShortUUID('tiny-vue');
}
nextTick(() => {
setTimeout(() => {
initEditor();
}, 30);
});
});
onBeforeUnmount(() => {
destory();
});
onDeactivated(() => {
destory();
});
function destory() {
if (tinymce !== null) {
tinymce?.remove?.(unref(initOptions).selector!);
}
}
function initEditor() {
const el = unref(elRef);
if (el) {
el.style.visibility = '';
}
tinymce
.init(unref(initOptions))
.then((editor) => {
emit('inited', editor);
})
.catch((err) => {
emit('init-error', err);
});
}
function initSetup(e) {
const editor = unref(editorRef);
if (!editor) {
return;
}
const value = props.modelValue || '';
editor.setContent(value);
bindModelHandlers(editor);
bindHandlers(e, attrs, unref(editorRef));
}
function setValue(editor: Recordable, val: string, prevVal?: string) {
if (editor && typeof val === 'string' && val !== prevVal && val !== editor.getContent({ format: attrs.outputFormat })) {
editor.setContent(val);
}
}
function bindModelHandlers(editor: any) {
const modelEvents = attrs.modelEvents ? attrs.modelEvents : null;
const normalizedEvents = Array.isArray(modelEvents) ? modelEvents.join(' ') : modelEvents;
watch(
() => props.modelValue,
(val: string, prevVal: string) => {
setValue(editor, val, prevVal);
}
);
watch(
() => props.value,
(val: string, prevVal: string) => {
setValue(editor, val, prevVal);
},
{
immediate: true,
}
);
editor.on(normalizedEvents ? normalizedEvents : 'change keyup undo redo', () => {
const content = editor.getContent({ format: attrs.outputFormat });
emit('update:modelValue', content);
emit('change', content);
});
editor.on('FullscreenStateChanged', (e) => {
fullscreen.value = e.state;
});
}
function handleImageUploading(name: string) {
const editor = unref(editorRef);
if (!editor) {
return;
}
editor.execCommand('mceInsertContent', false, getUploadingImgName(name));
const content = editor?.getContent() ?? '';
setValue(editor, content);
}
function handleDone(name: string, url: string) {
const editor = unref(editorRef);
if (!editor) {
return;
}
const content = editor?.getContent() ?? '';
const val = content?.replace(getUploadingImgName(name), `<img src="${url}"/>`) ?? '';
setValue(editor, val);
}
function getUploadingImgName(name: string) {
return `[uploading:${name}]`;
}
return {
prefixCls,
containerWidth,
initOptions,
tinymceContent,
elRef,
tinymceId,
handleImageUploading,
handleDone,
editorRef,
fullscreen,
disabled,
};
},
});
</script>
<style lang="less" scoped></style>
<style lang="less">
@prefix-cls: ~'@{namespace}-tinymce-container';
.@{prefix-cls} {
position: relative;
line-height: normal;
textarea {
z-index: -1;
visibility: hidden;
}
}
.jeecg-tinymce-img-upload[data-v-aeb4161f] {
position: absolute;
top: -32px;
right: 0px;
z-index: 20;
}
</style>

View File

@ -0,0 +1,39 @@
// Any plugins you want to setting has to be imported
// Detail plugins list see https://www.tinymce.com/docs/plugins/
// Custom builds see https://www.tinymce.com/download/custom-builds/
// colorpicker/contextmenu/textcolor plugin is now built in to the core editor, please remove it from your editor configuration
// export const plugins = [
// 'advlist anchor autolink autosave code codesample directionality fullscreen hr insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus template textpattern visualblocks visualchars wordcount image',
// ];
// export const toolbar =
// 'fullscreen code preview | undo redo | bold italic underline strikethrough | fontselect fontsizeselect formatselect | alignleft aligncenter alignright alignjustify | outdent indent lineheight|subscript superscript blockquote| numlist bullist checklist | forecolor backcolor casechange permanentpen formatpainter removeformat | pagebreak | charmap emoticons | insertfile image media pageembed link anchor codesample insertdatetime hr| a11ycheck ltr rtl';
// export const simplePlugins = ['lists image link media table textcolor wordcount contextmenu fullscreen'];
// export const simpleToolbar = [
// 'undo redo formatselect bold italic alignleft aligncenter alignright alignjustify bullist numlist outdent indent',
// 'lists link unlink image media table removeformat fullscreen',
// ];
// export const menubar = 'file edit insert view format table';
export const plugins = [
'image',
];
// export const toolbar =
// 'fullscreen code preview | undo redo | bold italic underline strikethrough | fontselect fontsizeselect formatselect | alignleft aligncenter alignright alignjustify | outdent indent lineheight|subscript superscript blockquote| numlist bullist checklist | forecolor backcolor casechange permanentpen formatpainter removeformat | pagebreak | charmap emoticons | insertfile image media pageembed link anchor codesample insertdatetime hr| a11ycheck ltr rtl';
export const toolbar =
'';
// fullscreen code preview | undo redo |
export const simplePlugins = ['lists image link media table textcolor wordcount contextmenu fullscreen'];
export const simpleToolbar = [
'lists link unlink image media table removeformat fullscreen',
];
export const menubar = '';

View File

@ -172,11 +172,11 @@
>填空</a-button >填空</a-button
></p ></p
> >
<!-- <p <p
><a-button type="primary" preIcon="ant-design:check-square-outlined" @click="addTigan(8)" :disabled="editDisabled" ><a-button type="primary" preIcon="ant-design:check-square-outlined" @click="addTigan(8)" :disabled="editDisabled"
>文件</a-button >文件</a-button
></p ></p
> --> >
</a-card> </a-card>
<a-card title="引用题库"> <a-card title="引用题库">
<p><a-button type="primary" @click="handleYylx('0')" :disabled="editDisabled">我的题库</a-button></p> <p><a-button type="primary" @click="handleYylx('0')" :disabled="editDisabled">我的题库</a-button></p>
@ -430,14 +430,29 @@
<template #title> <template #title>
<span>{{ index + 1 }}</span> <span>{{ index + 1 }}</span>
<a-textarea <a-textarea
placeholder="请填写文件上传题题干" placeholder="请填写文件题题干"
v-model:value="item.wjTitle" v-model:value="item.wjTitle"
:bordered="false" :bordered="false"
:style="{ width: '30rem' }" :style="{ width: '30rem' }"
:auto-size="{ minRows: 1, maxRows: 5 }" :auto-size="{ minRows: 1, maxRows: 5 }"
:disabled="editDisabled" :disabled="editDisabled"
/> />
<span style="color: #c2bfbf">[文件上传]</span> <span style="color: #c2bfbf">[文件]</span>
<!-- <a-textarea
placeholder="请填写文件上传题题干"
v-model:value="item.wjTitle"
:bordered="false"
:style="{ width: '30rem' }"
:auto-size="{ minRows: 1, maxRows: 5 }"
:disabled="editDisabled"
/> -->
<!-- <JEditor2 placeholder="请填写文件上传题题干"
v-model:value="item.wjTitle"
:bordered="false"
:style="{ width: '30rem' }"
:auto-size="{ minRows: 1, maxRows: 5 }"
:disabled="editDisabled" v-if="!editDisabled"/>
<div v-else v-html="item.wjTitle"></div> -->
</template> </template>
<template #extra> <template #extra>
<a-tooltip placement="topLeft" title="题目分数" v-if="isShow"> <a-tooltip placement="topLeft" title="题目分数" v-if="isShow">
@ -474,7 +489,9 @@
@click="handleDelTigan(item, index)" @click="handleDelTigan(item, index)"
v-if="!editDisabled" v-if="!editDisabled"
/></a-tooltip> /></a-tooltip>
<!-- <JUpload ref="uploadRef" /> -->
</template> </template>
<j-upload v-model:value="item.picPath" fileType="image" maxCount="9"></j-upload>
</a-card> </a-card>
</div> </div>
@ -945,10 +962,12 @@ import { list, deleteOne, saveOrUpdate } from '/@/views/kc/wjxWjxx/WjxWjxx.api';
import { Form } from 'ant-design-vue'; import { Form } from 'ant-design-vue';
import { getValueType } from '/@/utils'; import { getValueType } from '/@/utils';
import JEditor from '/@/components/Form/src/jeecg/components/JEditor.vue'; import JEditor from '/@/components/Form/src/jeecg/components/JEditor.vue';
import JEditor2 from '/@/components/Form/src/jeecg/components/JEditor2.vue';
import { useUserStore } from '/@/store/modules/user'; import { useUserStore } from '/@/store/modules/user';
import draggable from 'vuedraggable'; import draggable from 'vuedraggable';
import { QrCode } from '/@/components/Qrcode/index'; import { QrCode } from '/@/components/Qrcode/index';
import { useGlobSetting } from '/@/hooks/setting'; import { useGlobSetting } from '/@/hooks/setting';
import JUpload from '/@/components/Form/src/jeecg/components/JUpload/JUpload.vue';
import WjxWjxxTmlbDjjgsModal from '/@/views/kc/wjxWjxx/components/WjxWjxxTmlbDjjgsModal.vue'; import WjxWjxxTmlbDjjgsModal from '/@/views/kc/wjxWjxx/components/WjxWjxxTmlbDjjgsModal.vue';
import XxhbbksListModal from '/@/views/kc/xxhbbks/XxhbbksListModal.vue'; import XxhbbksListModal from '/@/views/kc/xxhbbks/XxhbbksListModal.vue';
@ -2279,4 +2298,8 @@ onMounted(() => {
white-space: nowrap; white-space: nowrap;
text-overflow: clip; text-overflow: clip;
} }
// /deep/.jeecg-tinymce-container{
// width: 20rem !important;
// height: 100px;
// }
</style> </style>

View File

@ -934,7 +934,7 @@ function handleScoreFabu(record: Recordable) {
} }
// //
function handlepiyue(record: Recordable) { function handlepiyue(record: Recordable) {
registerPiyueModal.value.disableSubmit = false; registerPiyueModal.value.disableSubmit = true;
registerPiyueModal.value.edit(record); registerPiyueModal.value.edit(record);
} }

View File

@ -2,9 +2,32 @@
<a-spin :spinning="confirmLoading"> <a-spin :spinning="confirmLoading">
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol"> <a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-row> <a-row>
<!-- <a-col :span="24"> <a-col :span="12">
<span style="margin-left: 8%;line-height:60px;">预设作业分值{{zyInfo.score?zyInfo.score+"分 评分不能高于预设分值":'未设置 评分不能高于100分'}}</span> <div v-if="showType=='1'">
</a-col> --> <iframe id="pdfPreviewIframe" :src="ylurl" frameborder="0" width="100%" height="550px" scrolling="auto"></iframe>
</div>
<div v-else-if="showType=='2'">
<img :src="ylurl" style="width: 100%;min-height:200px;" />
</div>
<div v-else-if="showType=='3'">
<div class="video-container">
<video
ref="videoPlayer"
:controls="controls"
:autoplay="autoplay"
:loop="loop"
:src="videoUrl"
@loadedmetadata="playVideoInFullscreen"
>
</video>
</div>
</div>
<div v-else>
<a-button type="primary">下载文件</a-button>
</div>
</a-col>
<a-col :span="12">
<a-row>
<a-col :span="24"> <a-col :span="24">
<a-form-item label="作业名称"> <a-form-item label="作业名称">
{{zyInfo.title}} {{zyInfo.title}}
@ -15,6 +38,11 @@
{{formData.studentName}} {{formData.studentName}}
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="24">
<a-form-item label="评分" v-bind="validateInfos.score">
<a-input-number v-model:value="formData.score" style="width: 100%" placeholder="请填写评分" ></a-input-number>
</a-form-item>
</a-col>
<a-col :span="24"> <a-col :span="24">
<a-form-item label="批阅内容" v-bind="validateInfos.pyContent"> <a-form-item label="批阅内容" v-bind="validateInfos.pyContent">
<JEditor v-model:value="formData.pyContent" /> <JEditor v-model:value="formData.pyContent" />
@ -22,16 +50,25 @@
</a-col> </a-col>
<a-col :span="24"> <a-col :span="24">
<a-form-item label="批阅附件" v-bind="validateInfos.pyFilePath"> <a-form-item label="批阅附件" v-bind="validateInfos.pyFilePath">
<j-upload v-model:value="formData.pyFilePath" :disabled="disabled" maxCount="1" :text="`上传批阅附件`" style="background: #ededed; " :forceAcceptVerify="true" ></j-upload> <j-upload v-model:value="formData.pyFilePath" maxCount="1" :text="`上传批阅附件`" style="background: #ededed; " :forceAcceptVerify="true" ></j-upload>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="24" style="text-align: center;" v-if="disabled">
<div >
<a-button type="primary" @click="submitForm">保存</a-button>
<a-button type="primary" @click="submitNextForm" style="margin-left: 10px;">保存并下一个</a-button>
</div>
</a-col>
</a-row>
</a-col>
</a-row> </a-row>
</a-form> </a-form>
</a-spin> </a-spin>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, reactive, defineExpose, nextTick, defineProps, computed, onMounted } from 'vue'; import { ref, reactive, defineExpose, nextTick, defineProps, computed, onMounted,onUnmounted } from 'vue';
import { defHttp } from '/@/utils/http/axios'; import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage'; import { useMessage } from '/@/hooks/web/useMessage';
import JUpload from '/@/components/Form/src/jeecg/components/JUpload/JUpload.vue'; import JUpload from '/@/components/Form/src/jeecg/components/JUpload/JUpload.vue';
@ -39,6 +76,9 @@
import { saveOrUpdate } from '../ZyInfoStudent.api'; import { saveOrUpdate } from '../ZyInfoStudent.api';
import { Form } from 'ant-design-vue'; import { Form } from 'ant-design-vue';
import JEditor from '/@/components/Form/src/jeecg/components/JEditor.vue'; import JEditor from '/@/components/Form/src/jeecg/components/JEditor.vue';
import { useGlobSetting } from '/@/hooks/setting';
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
import { getToken } from '/@/utils/auth';
const props = defineProps({ const props = defineProps({
formDisabled: { type: Boolean, default: false }, formDisabled: { type: Boolean, default: false },
@ -47,18 +87,33 @@
}); });
const formRef = ref(); const formRef = ref();
const useForm = Form.useForm; const useForm = Form.useForm;
const emit = defineEmits(['register', 'ok']); const emit = defineEmits(['register', 'ok', 'ok2']);
const formData = reactive<Record<string, any>>({ const formData = reactive<Record<string, any>>({
id: '', id: '',
score: '', score: '',
pyContent: '',
pyFilePath: '',
}); });
const { createMessage } = useMessage(); const { createMessage } = useMessage();
const labelCol = ref<any>({ xs: { span: 24 }, sm: { span: 5 } }); const labelCol = ref<any>({ xs: { span: 24 }, sm: { span: 5 } });
const wrapperCol = ref<any>({ xs: { span: 24 }, sm: { span: 16 } }); const wrapperCol = ref<any>({ xs: { span: 24 }, sm: { span: 16 } });
const confirmLoading = ref<boolean>(false); const confirmLoading = ref<boolean>(false);
const showType = ref<string>('0');
const ylurl = ref<string>('');
const zyInfo = ref<any>({}); const zyInfo = ref<any>({});
const globSetting = useGlobSetting();
const baseApiUrl = globSetting.domainUrl;
const videoPlayer = ref(null);
const videoOpen = ref<boolean>(false);
const controls = ref(true);
const autoplay = ref(false)
const loop = ref(false);
const videoUrl = ref<String>('');
// //
const validatorRules = { const validatorRules = {
score: [{ required: true, message: '请输入分数!' }],
}; };
const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: true }); const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: true });
@ -111,6 +166,7 @@
* 编辑 * 编辑
*/ */
function edit(record) { function edit(record) {
formData.pyContent = ''
nextTick(() => { nextTick(() => {
resetFields(); resetFields();
@ -118,14 +174,90 @@
console.log(`🚀 ~ defHttp.get ~ res:`, res) console.log(`🚀 ~ defHttp.get ~ res:`, res)
zyInfo.value = res; zyInfo.value = res;
}) })
const parts = record.filePath.split('.');
const filetype = parts[parts.length - 1];
console.log(`🚀 ~ nextTick ~ filetype:`, filetype)
var file = getFileAccessHttpUrl(record.filePath);
ylurl.value = file;
if(filetype=='jpg' || filetype=='png' || filetype=='jpeg' || filetype=='xls' || filetype=='xlsx' || filetype=='text' ){
showType.value = '2';
}else if(filetype=='doc' || filetype=='docx' || filetype=='pdf'){
showType.value = '1';
var file2 = getFileAccessHttpUrl(record.pdfPath);
let url2 = baseApiUrl + '/generic/web/viewer.html?file=' + encodeURIComponent(file2);
ylurl.value = url2;
}else if(filetype=='mp4'|| filetype=='avi'|| filetype=='mp3'|| filetype=='wav'){
showType.value = '3';
let url = getFileAccessHttpUrl(record.filePath);
console.log('视频预览-----》',url);
// videoOpen.value = true;
videoUrl.value = url;
}else{
showType.value = '0';
}
// //
Object.assign(formData, record); Object.assign(formData, record);
}); });
} }
// --------------------------------------------------------
const playVideo = () => {
videoPlayer.value.play();
};
const pauseVideo = () => {
videoPlayer.value.pause();
};
const handleFullScreenChange = () => {
if (!document.fullscreenElement) {
console.log('Video exited fullscreen');
//
videoOpen.value = false;
videoPlayer.value.pause();
}
};
function videoHandleCancel(){
pauseVideo();
videoOpen.value = false;
}
onMounted(() => {
document.addEventListener('fullscreenchange', handleFullScreenChange);
});
onUnmounted(() => {
document.removeEventListener('fullscreenchange', handleFullScreenChange);
});
//
function handleVideo(three){
let url = getFileAccessHttpUrl(three.filePath);
console.log('视频预览-----》',url);
videoOpen.value = true;
videoUrl.value = url;
playVideoInFullscreen();
// setTimeout(() => {
// playVideo();
// }, 1000);
}
// --------------------------------------------------------
const playVideoInFullscreen = async () => {
if (videoPlayer.value) {
try {
// 使DOM
// await videoPlayer.value.requestFullscreen();
} catch (err) {
console.error(err);
}
}
};
/** /**
* 提交数据 * 提交数据
*/ */
@ -171,6 +303,49 @@
// }); // });
} }
/**
* 提交数据并下一个
*/
async function submitNextForm() {
//
await validate();
confirmLoading.value = true;
const isUpdate = ref<boolean>(false);
//
let model = formData;
if (model.id) {
isUpdate.value = true;
}
//
for (let data in model) {
//
if (model[data] instanceof Array) {
let valueType = getValueType(formRef.value.getProps, data);
//
if (valueType === 'string') {
model[data] = model[data].join(',');
}
}
}
await defHttp.post({url:'/zyInfoStudent/zyInfoStudent/editPiyue',params:model}).then(res =>{
emit('ok2');
})
await defHttp.get({url:'/zyInfoStudent/zyInfoStudent/getList2',params:{column:'createTime',order:'asc',pageNo:1,pageSize:10,ywid:zyInfo.value.id,rwbh:zyInfo.value.rwbh,queryType:5}}).then(res =>{
console.log(`🚀 ~ awaitdefHttp.post ~ res:`, res)
var list = res.records;
if(list.length>0){
edit(list[0])
}else{
createMessage.warning('已批阅完毕,暂无下一条批阅数据!');
}
})
.finally(() => {
confirmLoading.value = false;
});
}
defineExpose({ defineExpose({
add, add,
@ -185,4 +360,11 @@
overflow-y: auto; overflow-y: auto;
padding: 24px 24px 24px 24px; padding: 24px 24px 24px 24px;
} }
.video-container {
text-align: center;
}
video {
display: block;
max-width: 100%; /* 确保视频宽度不超过其容器宽度 */
}
</style> </style>

View File

@ -1,6 +1,6 @@
<template> <template>
<a-modal :title="title" :width="width" :visible="visible" @ok="handleOk" :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }" @cancel="handleCancel" cancelText="关闭"> <a-modal :title="title" :width="width" :visible="visible" @ok="handleOk" :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }" @cancel="handleCancel" cancelText="关闭">
<ZyInfoStudentPiyueForm ref="registerForm" @ok="submitCallback" :formDisabled="disableSubmit" :formBpm="false"></ZyInfoStudentPiyueForm> <ZyInfoStudentPiyueForm ref="registerForm" @ok="submitCallback" @ok2="submitCallback2" :formDisabled="disableSubmit" :formBpm="false"></ZyInfoStudentPiyueForm>
</a-modal> </a-modal>
</template> </template>
@ -9,7 +9,7 @@
import ZyInfoStudentPiyueForm from './ZyInfoStudentPiyueForm.vue' import ZyInfoStudentPiyueForm from './ZyInfoStudentPiyueForm.vue'
const title = ref<string>(''); const title = ref<string>('');
const width = ref<number>(800); const width = ref<string>('100%');
const visible = ref<boolean>(false); const visible = ref<boolean>(false);
const disableSubmit = ref<boolean>(false); const disableSubmit = ref<boolean>(false);
const registerForm = ref(); const registerForm = ref();
@ -53,6 +53,10 @@
emit('success'); emit('success');
} }
function submitCallback2() {
emit('success');
}
/** /**
* 取消按钮回调事件 * 取消按钮回调事件
*/ */