username 10 月之前
父節點
當前提交
466ed623b0

+ 336
- 326
src/views/onlineBusinessHall/productManagement/equityProduct/components/Tinymce/index.vue 查看文件

@@ -1,371 +1,381 @@
<template>
<div class="prefixCls" :style="{ width: containerWidth, height: containerHeigth }" v-loading="isLoading">
<textarea :id="tinymceId" ref="elRef" :style="{ visibility: 'hidden' }" class="tinymce-textarea"></textarea>
<div
class="prefixCls"
:style="{ width: containerWidth, height: containerHeigth }"
v-loading="isLoading"
>
<textarea
:id="tinymceId"
ref="elRef"
:style="{ visibility: 'hidden' }"
class="tinymce-textarea"
></textarea>
</div>
</template>

<script setup>
import {
computed,
nextTick,
ref,
unref,
watch,
onDeactivated,
onBeforeUnmount,
defineProps,
defineEmits,
getCurrentInstance,
onMounted,
} from 'vue'
import { toolbar, plugins } from './tinymce'
import { bindHandlers } from './helper'
import { isNumber, onMountedOrActivated, buildShortUUID } from './utils'
import {
computed,
nextTick,
ref,
unref,
watch,
onDeactivated,
onBeforeUnmount,
defineProps,
defineEmits,
getCurrentInstance,
onMounted,
} from 'vue'
import { toolbar, plugins } from './tinymce'
import { bindHandlers } from './helper'
import { isNumber, onMountedOrActivated, buildShortUUID } from './utils'

const props = defineProps({
options: {
type: Object,
default: () => { },
},
value: {
type: String,
},

toolbar: {
type: Array,
default: toolbar,
},
plugins: {
type: [Array, String],
default: plugins,
},
modelValue: {
type: String,
},
height: {
type: [Number, String],
required: false,
default: 400,
},
width: {
type: [Number, String],
required: false,
default: 'auto',
},
showImageUpload: {
type: Boolean,
default: true,
},
fileBaseUrl: {
type: String,
default: import.meta.env.VITE_APP_UPLOAD_URL + 'sett-minio/',
},
minioBucket: {
type: String,
default: 'sett-minio',
},
})
const emits = defineEmits([
'change',
'update:modelValue',
'inited',
'init-error',
'uploadFile',
])
const { attrs } = getCurrentInstance()
const tinymceId = ref(buildShortUUID('tiny-vue'))
const props = defineProps({
options: {
type: Object,
default: () => {},
},
value: {
type: String,
},

const containerWidth = computed(() => {
const width = props.width
if (isNumber(width)) {
return `${width}px`
}
return width
})
const containerHeigth = computed(() => {
const height = props.height
if (isNumber(height)) {
return `${height}px`
}
return height
})
const editorRef = ref(null)
const fullscreen = ref(false)
const elRef = ref(null)
const tinymceContent = computed(() => props.modelValue)

const example_image_upload_handler = (blobInfo, progress) =>
new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.withCredentials = false
xhr.open('POST', '/minIo/upload')
toolbar: {
type: Array,
default: toolbar,
},
plugins: {
type: [Array, String],
default: plugins,
},
modelValue: {
type: String,
},
height: {
type: [Number, String],
required: false,
default: 400,
},
width: {
type: [Number, String],
required: false,
default: 'auto',
},
showImageUpload: {
type: Boolean,
default: true,
},
fileBaseUrl: {
type: String,
default: import.meta.env.VITE_APP_UPLOAD_URL + 'sett-minio/',
},
minioBucket: {
type: String,
default: 'sett-minio',
},
})
const emits = defineEmits([
'change',
'update:modelValue',
'inited',
'init-error',
'uploadFile',
])
const { attrs } = getCurrentInstance()
const tinymceId = ref(buildShortUUID('tiny-vue'))

xhr.upload.onprogress = (e) => {
progress((e.loaded / e.total) * 100)
}
const containerWidth = computed(() => {
const width = props.width
if (isNumber(width)) {
return `${width}px`
}
return width
})
const containerHeigth = computed(() => {
const height = props.height
if (isNumber(height)) {
return `${height}px`
}
return height
})
const editorRef = ref(null)
const fullscreen = ref(false)
const elRef = ref(null)
const tinymceContent = computed(() => props.modelValue)

xhr.onload = () => {
if (xhr.status === 403) {
reject({ message: 'HTTP Error: ' + xhr.status, remove: true })
return
}
const example_image_upload_handler = (blobInfo, progress) =>
new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.withCredentials = false
xhr.open('POST', '/minIo/upload')

if (xhr.status < 200 || xhr.status >= 300) {
reject('HTTP Error: ' + xhr.status)
return
}
xhr.upload.onprogress = (e) => {
progress((e.loaded / e.total) * 100)
}

const json = JSON.parse(xhr.responseText)
xhr.onload = () => {
if (xhr.status === 403) {
reject({ message: 'HTTP Error: ' + xhr.status, remove: true })
return
}

if (!json) {
reject('Invalid JSON: ' + xhr.responseText)
return
}
if (xhr.status < 200 || xhr.status >= 300) {
reject('HTTP Error: ' + xhr.status)
return
}

const imgUrl = props.fileBaseUrl + json.data.ossFilePath
const json = JSON.parse(xhr.responseText)

emits('uploadFile', {
imgUrl,
...json.data,
})
resolve(imgUrl)
}
xhr.onerror = () => {
reject('图片上传错误,错误码: ' + xhr.status)
if (!json) {
reject('Invalid JSON: ' + xhr.responseText)
return
}

const formData = new FormData()
formData.append('file', blobInfo.blob()) //此处与源文档不一样
formData.append('bucket', props.minioBucket) //此处与源文档不一样
xhr.send(formData)
})
const initOptions = computed(() => {
const { height, options, toolbar, plugins } = props
const publicPath = '/'
return {
selector: `#${unref(tinymceId)}`,
language: 'zh-Hans', //注意大小写
resize: 'both', //编辑器宽高是否可变,false-否,true-高可变,'both'-宽高均可,注意引号
font_formats:
'微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;', //字体样式
plugins,
height,
toolbar, //工具栏配置,设为false则隐藏
statusbar: false,
relative_urls: false,
remove_script_host: false,
convert_urls: false,//绝对路径
// 此处为图片上传处理函数,这个直接用了base64的图片形式上传图片,
images_upload_handler: example_image_upload_handler,
content_style: 'img {width:100%;height:100%;vertical-align:top}',
image_dimensions: false, // 默认的宽度和高度设置
document_base_url: props.fileBaseUrl,
paste_data_images: true, //图片是否可粘贴
file_picker_types: 'image', //file image media分别对应三个类型文件的上传:link插件,image和axupimgs插件,media插件。想屏蔽某个插件的上传就去掉对应的参数
file_picker_callback: function (callback, value, meta) {
//文件分类
let filetype =
'.pdf, .txt, .zip, .rar, .7z, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .mp3, .mp4'
//后端接收上传文件的地址
let upurl = '/minIo/upload'
//为不同插件指定文件类型及后端地址
switch (meta.filetype) {
case 'image':
filetype = '.jpg, .jpeg, .png, .gif'
upurl = '/minIo/upload'
break
case 'media':
filetype = '.mp3, .mp4'
upurl = '/minIo/upload'
break
case 'file':
default:
}
//模拟出一个input用于添加本地文件
let input = document.createElement('input')
input.setAttribute('type', 'file')
input.setAttribute('accept', filetype)
input.click()
input.onchange = function () {
let file = this.files[0]
let xhr, formData
xhr = new XMLHttpRequest()
xhr.withCredentials = false
xhr.open('POST', upurl)
xhr.onload = function () {
let json
if (xhr.status != 200) {
return
}
json = JSON.parse(xhr.responseText)
const imgUrl = props.fileBaseUrl + json.data.ossFilePath
emits('uploadFile', {
imgUrl,
...json.data,
})
callback(imgUrl)
}
formData = new FormData()
formData.append('file', file)
formData.append('bucket', props.minioBucket) //此处与源文档不一样
xhr.send(formData)
}
},
...options,
setup: (editor) => {
editorRef.value = editor
editor.on('init', (e) => {
initSetup(e)
})
},
}
})
const imgUrl = props.fileBaseUrl + json.data.ossFilePath

const disabled = computed(() => {
const { options } = props
const getdDisabled = options && Reflect.get(options, 'readonly')
const editor = unref(editorRef)
if (editor) {
editor.setMode(getdDisabled ? 'readonly' : 'design')
emits('uploadFile', {
imgUrl,
...json.data,
})
resolve(imgUrl)
}
return getdDisabled ?? false
})

watch(
() => attrs.disabled,
() => {
const editor = unref(editorRef)
if (!editor) {
return
}
editor.setMode(attrs.disabled ? 'readonly' : 'design')
xhr.onerror = () => {
reject('图片上传错误,错误码: ' + xhr.status)
}
)

onBeforeUnmount(() => {
destory()
})

onDeactivated(() => {
destory()
const formData = new FormData()
formData.append('file', blobInfo.blob()) //此处与源文档不一样
formData.append('bucket', props.minioBucket) //此处与源文档不一样
xhr.send(formData)
})
const initOptions = computed(() => {
const { height, options, toolbar, plugins } = props
const publicPath = '/'
return {
selector: `#${unref(tinymceId)}`,
language: 'zh-Hans', //注意大小写
resize: 'both', //编辑器宽高是否可变,false-否,true-高可变,'both'-宽高均可,注意引号
font_formats:
'微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;', //字体样式
plugins,
height,
toolbar, //工具栏配置,设为false则隐藏
statusbar: false,
relative_urls: false,
remove_script_host: false,
convert_urls: false, //绝对路径
// 此处为图片上传处理函数,这个直接用了base64的图片形式上传图片,
images_upload_handler: example_image_upload_handler,
content_style: 'img {width:100%;height:100%;vertical-align:top}',
image_dimensions: false, // 默认的宽度和高度设置
document_base_url: props.fileBaseUrl,
paste_data_images: true, //图片是否可粘贴
file_picker_types: 'image', //file image media分别对应三个类型文件的上传:link插件,image和axupimgs插件,media插件。想屏蔽某个插件的上传就去掉对应的参数
file_picker_callback: function (callback, value, meta) {
//文件分类
let filetype =
'.pdf, .txt, .zip, .rar, .7z, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .mp3, .mp4'
//后端接收上传文件的地址
let upurl = '/minIo/upload'
//为不同插件指定文件类型及后端地址
switch (meta.filetype) {
case 'image':
filetype = '.jpg, .jpeg, .png, .gif'
upurl = '/minIo/upload'
break
case 'media':
filetype = '.mp3, .mp4'
upurl = '/minIo/upload'
break
case 'file':
default:
}
//模拟出一个input用于添加本地文件
let input = document.createElement('input')
input.setAttribute('type', 'file')
input.setAttribute('accept', filetype)
input.click()
input.onchange = function () {
let file = this.files[0]
let xhr, formData
xhr = new XMLHttpRequest()
xhr.withCredentials = false
xhr.open('POST', upurl)
xhr.onload = function () {
let json
if (xhr.status != 200) {
return
}
json = JSON.parse(xhr.responseText)
const imgUrl = props.fileBaseUrl + json.data.ossFilePath
emits('uploadFile', {
imgUrl,
...json.data,
})
callback(imgUrl)
}
formData = new FormData()
formData.append('file', file)
formData.append('bucket', props.minioBucket) //此处与源文档不一样
xhr.send(formData)
}
},
...options,
setup: (editor) => {
editorRef.value = editor
editor.on('init', (e) => {
initSetup(e)
})
},
}
})

function destory() {
if (tinymce !== null) {
// tinymce?.remove?.(unref(initOptions).selector!);
}
const disabled = computed(() => {
const { options } = props
const getdDisabled = options && Reflect.get(options, 'readonly')
const editor = unref(editorRef)
if (editor) {
editor.setMode(getdDisabled ? 'readonly' : 'design')
}
return getdDisabled ?? false
})

function initSetup(e) {
watch(
() => attrs.disabled,
() => {
const editor = unref(editorRef)
if (!editor) {
return
}
const value = props.modelValue || ''
editor.setMode(attrs.disabled ? 'readonly' : 'design')
}
)

onBeforeUnmount(() => {
destory()
})

editor.setContent(value)
bindModelHandlers(editor)
bindHandlers(e, attrs, unref(editorRef))
onDeactivated(() => {
destory()
})

function destory() {
if (tinymce !== null) {
// tinymce?.remove?.(unref(initOptions).selector!);
}
const isLoading = ref(false)
function initEditor() {
const el = unref(elRef)
if (el) {
el.style.visibility = ''
}
isLoading.value = true
tinymce
.init(unref(initOptions))
.then((editor) => {
emits('inited', editor)
})
.catch((err) => {
emits('init-error', err)
})
.finally(() => {
isLoading.value = false
})
}

function initSetup(e) {
const editor = unref(editorRef)
if (!editor) {
return
}
const value = props.modelValue || ''

function setValue(editor, val, prevVal) {
if (
editor &&
typeof val === 'string' &&
val !== prevVal &&
val !== editor.getContent({ format: attrs.outputFormat })
) {
editor.setContent(val)
}
editor.setContent(value)
bindModelHandlers(editor)
bindHandlers(e, attrs, unref(editorRef))
}
const isLoading = ref(false)
function initEditor() {
const el = unref(elRef)
if (el) {
el.style.visibility = ''
}
isLoading.value = true
tinymce
.init(unref(initOptions))
.then((editor) => {
emits('inited', editor)
})
.catch((err) => {
emits('init-error', err)
})
.finally(() => {
isLoading.value = false
})
}

function bindModelHandlers(editor) {
const modelEvents = attrs.modelEvents ? attrs.modelEvents : null
const normalizedEvents = Array.isArray(modelEvents)
? modelEvents.join(' ')
: modelEvents
function setValue(editor, val, prevVal) {
if (
editor &&
typeof val === 'string' &&
val !== prevVal &&
val !== editor.getContent({ format: attrs.outputFormat })
) {
editor.setContent(val)
}
}

watch(
() => props.modelValue,
(val, prevVal) => {
setValue(editor, val, prevVal)
}
)
function bindModelHandlers(editor) {
const modelEvents = attrs.modelEvents ? attrs.modelEvents : null
const normalizedEvents = Array.isArray(modelEvents)
? modelEvents.join(' ')
: modelEvents

watch(
() => props.value,
(val, prevVal) => {
setValue(editor, val, prevVal)
},
{
immediate: true,
}
)
watch(
() => props.modelValue,
(val, prevVal) => {
setValue(editor, val, prevVal)
}
)

editor.on(normalizedEvents || 'change keyup undo redo', () => {
const content = editor.getContent({ format: attrs.outputFormat })
emits('update:modelValue', content)
emits('change', content)
})
watch(
() => props.value,
(val, prevVal) => {
setValue(editor, val, prevVal)
},
{
immediate: true,
}
)

editor.on('FullscreenStateChanged', (e) => {
fullscreen.value = e.state
})
}
editor.on(normalizedEvents || 'change keyup undo redo', () => {
const content = editor.getContent({ format: attrs.outputFormat })
emits('update:modelValue', content)
emits('change', content)
})

function getUploadingImgName(name) {
return `[uploading:${name}]`
}
const src = './tinymce/js/tinymce/tinymce.min.js'
const dynamicLoadScript = () => {
const tinymcemin = document.getElementById('tinymcemin')
if (!tinymcemin) {
const script = document.createElement('script')
script.src = src // src url for the third-party library being loaded.
script.id = 'tinymcemin'
document.body.appendChild(script)
script.onload = function () {
initEditor()
}
} else {
editor.on('FullscreenStateChanged', (e) => {
fullscreen.value = e.state
})
}

function getUploadingImgName(name) {
return `[uploading:${name}]`
}
const src = './tinymce/js/tinymce/tinymce.min.js'
const dynamicLoadScript = () => {
const tinymcemin = document.getElementById(tinymceId.value)
if (!tinymcemin) {
const script = document.createElement('script')
script.src = src // src url for the third-party library being loaded.
script.id = 'tinymcemin'
document.body.appendChild(script)
script.onload = function () {
initEditor()
}
} else {
initEditor()
}
onMounted(() => {
if (!initOptions.value.inline) {
tinymceId.value = buildShortUUID('tiny-vue')
}
dynamicLoadScript()
})
// onMountedOrActivated(() => {
// if (!initOptions.value.inline) {
// tinymceId.value = buildShortUUID('tiny-vue')
// }
// nextTick(() => {
// setTimeout(() => {
// initEditor()
// }, 30)
// })
// })
}
onMounted(() => {
console.log('onMountedtiny');
if (!initOptions.value.inline) {
tinymceId.value = buildShortUUID('tiny-vue')
}
dynamicLoadScript()
})
// onMountedOrActivated(() => {
// if (!initOptions.value.inline) {
// tinymceId.value = buildShortUUID('tiny-vue')
// }
// nextTick(() => {
// setTimeout(() => {
// initEditor()
// }, 30)
// })
// })
</script>

<style scoped>

+ 14
- 10
src/views/onlineBusinessHall/productManagement/equityProduct/index.vue 查看文件

@@ -60,7 +60,7 @@
@updateModelValue="handleDescriptionData"
/> -->

<equityDescription v-model="crudRef.form['productIntro']" />
<equityDescription v-model="crudRef.form['productIntro']" v-if="equityDescriptionShow"/>
</template>
<template #descriptionInfo>
<!-- <equityDescription
@@ -110,7 +110,7 @@
</template>
<!-- 单项权益管理 -->
<script setup lang="ts">
import { ref, toRaw, onMounted, computed, onBeforeMount } from 'vue'
import { ref, toRaw, onMounted, computed, onBeforeMount, onActivated,nextTick } from 'vue'
// @ts-ignore crudFrom模板
import CrudTemplate from '@/crud/index.vue'
import $storeinitData from '@/store/initData' //引入tab vuex
@@ -179,10 +179,18 @@ const searchForm = ref({
})
let tableData: any = ref([])
const typeOption = ref('')
onActivated(() => {
console.log('onActivated内层');
getAgenCy()
getEquity()
equityDescriptionShow.value = false
nextTick(() => {
equityDescriptionShow.value = true

})
})
onMounted(() => {
getList()
getEquity()
})
// 编辑按钮
function handleEdit(idx: any, row: any) {
@@ -193,7 +201,7 @@ function handleEdit(idx: any, row: any) {
function handleInfo(value, row) {
customSelectorSelection(row.validityFormat, validityFormat, {})
}
const equityDescriptionShow = ref(true) //修改
// 新增
function add() {
typeOption.value = 'add'
@@ -220,9 +228,7 @@ function assignment(datas, row) {
}
}
}
function handleIntroduction() {
isdescriptionInfoShow.value = true
}

const isdescriptionInfoShow = ref(false)
// 搜索按钮
function btnSearch() {
@@ -473,9 +479,7 @@ function submit(data: any) {
}
})
}
onBeforeMount(() => {
getAgenCy()
})

const agencyIdList = ref([])
function getAgenCy() {
BaseService.post('/userw/agency/agencyqueryall', {}).then((res: any) => {

+ 4
- 1
src/views/onlineBusinessHall/productManagement/promoteAnd/components/feeList.vue 查看文件

@@ -12,6 +12,9 @@
<div class="input-wrap">
<el-form-item
:prop="`dataForm.${scope.$index}.processingFeeType`"
:disabled="true"

>
<el-select
:disabled="true"
@@ -60,7 +63,7 @@
</template>
<template v-slot="scope">
<div class="input-wrap">
<el-form-item :prop="`dataForm.${scope.$index}.useFeeType`">
<el-form-item :prop="`dataForm.${scope.$index}.useFeeType`" :disabled="true">
<el-select
:disabled="true"
v-model="scope.row.useFeeType"

+ 15
- 8
src/views/onlineBusinessHall/productManagement/releaseProduct/index.vue 查看文件

@@ -797,7 +797,7 @@ function handleDialog(row, key) {
}

onActivated(() => {
console.log('onActivated');
console.log('onActivated')
getProductStandardsIdList()
getList()
getAgencyList()
@@ -816,8 +816,7 @@ const isChangeInfoShow = ref(false)

onMounted(() => {
getList()
console.log('onMounted');

console.log('onMounted')
})
onBeforeMount(() => {
getProductStandardsIdList()
@@ -1010,7 +1009,15 @@ function submit(data: any) {
console.log(datas, 'datasdatas')
datas.dateOfDelist = datas.dateOfDelist.replace('T', ' ')
datas.dateOfListing = datas.dateOfListing.replace('T', ' ')
datas.vehicleType = datas.vehicleType.map((items) => items[1])
datas.vehicleType = datas.vehicleType.map((items) => {
if (Array.isArray(items)) {
return items[1]
}else{
return items
}
})
// console.log('请请i参数', datas)
BaseService.postN(api, datas).then((res: any) => {
if (res && res.code === 0) {
ElMessage.success('操作成功')
@@ -1976,7 +1983,7 @@ let field = ref<any>({
prop: 'remarks',
label: '备注',
hide: true,
span:3,
span: 3,
form: {
digit: 100,
width: '90%',
@@ -2124,7 +2131,7 @@ let field = ref<any>({
hide: true,
listData: expenseTypeOptions,
form: {
hideInfo:true,
hideInfo: true,
width: '45%',
placeholder: '请选择费用类型',
formLabelWidth: '120px',
@@ -2140,7 +2147,7 @@ let field = ref<any>({
span: 3,
form: {
width: '95%',
hideInfo:true,
hideInfo: true,
hideEdit: true,
slotSetEdit: true,
slotSetNameEdit: 'processingFeeList',
@@ -2157,7 +2164,7 @@ let field = ref<any>({
form: {
width: '95%',
hideEdit: true,
hideInfo:true,
hideInfo: true,
slotSetEdit: true,
slotSetNameEdit: 'useFeeList',
slotSetInfo: true,

Loading…
取消
儲存