This commit is contained in:
qiuyuan 2025-08-27 16:58:52 +08:00
commit 85251a951d
12 changed files with 61 additions and 23 deletions

12
package-lock.json generated
View File

@ -16,6 +16,7 @@
"axios": "^1.4.0",
"clipboard": "^2.0.11",
"cropperjs": "^1.5.13",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.9",
"echarts": "^5.4.3",
"filesize": "^10.0.12",
@ -1849,6 +1850,12 @@
"node": ">= 8"
}
},
"node_modules/crypto-js": {
"version": "4.2.0",
"resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.2.0.tgz",
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==",
"license": "MIT"
},
"node_modules/cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz",
@ -6370,6 +6377,11 @@
"which": "^2.0.1"
}
},
"crypto-js": {
"version": "4.2.0",
"resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.2.0.tgz",
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
},
"cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz",

View File

@ -25,6 +25,7 @@
"axios": "^1.4.0",
"clipboard": "^2.0.11",
"cropperjs": "^1.5.13",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.9",
"echarts": "^5.4.3",
"filesize": "^10.0.12",

View File

@ -17,6 +17,7 @@ import TinyEditor from '@tinymce/tinymce-vue'
import { deepMerge } from '@/utils/util'
defineOptions({
name: 'XEditor',
})
@ -63,6 +64,8 @@ const opts = deepMerge(
language: 'zh-Hans',
height: props.height,
branding: false,
secretKey: 'gxzhonghai12345678', //
// originalString: 'hello, vue!', //
resize: false,
promotion: false,
plugins: 'image', //
@ -110,7 +113,6 @@ watch(
watch(
() => content.value,
(val) => {
console.log(1111)
emit('update:modelValue', val)
onFieldChange()
}
@ -129,6 +131,7 @@ function onInit(e) {
spinning.value = false
emit('ready', e.target)
}
</script>
<style lang="less">

View File

@ -39,6 +39,7 @@ const options = {
message.error({
content: error.detail,
key: MSG_ERROR_KEY,
})
}
},

View File

@ -1,6 +1,7 @@
import { isMatch, snakeCase, toUpper, cloneDeep, keys, pick } from 'lodash-es'
import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc'
import CryptoJS from 'crypto-js';
/**
* 数据映射
* @param {array} data 数据源
@ -333,4 +334,15 @@ export const spliceUrl=(fullUrl)=>{
if(!fullUrl) return null
const pathOnly = fullUrl.replace(/^https?:\/\/[^\/]+/, '');
return pathOnly
}
/**加密 */
export function encryptString(plaintext) {
if(!plaintext) return null
return CryptoJS.AES.encrypt(plaintext, 'gxzhonghai12345678',{mode: CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7,iv: CryptoJS.enc.Utf8.parse('0000000000000000'),format: CryptoJS.format.OpenSSL}).toString();
}
/**解密 */
export function decryptString(ciphertext) {
if(!ciphertext) return null
const bytes = CryptoJS.AES.decrypt(ciphertext, 'gxzhonghai12345678',{mode: CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7,iv: CryptoJS.enc.Utf8.parse('0000000000000000'),format: CryptoJS.format.OpenSSL});
return bytes.toString(CryptoJS.enc.Utf8);
}

View File

@ -140,7 +140,7 @@ import { useI18n } from 'vue-i18n'
import dayjs from 'dayjs'
import GxUpload from '@/components/GxUpload/index.vue'
import { typerEnum, areaEnum } from "@/enums/useEnum"
import { spliceUrl } from "@/utils/util"
import { spliceUrl,decryptString,encryptString } from "@/utils/util"
const emit = defineEmits(['ok'])
const { t } = useI18n() // t
const { modal, showModal, hideModal, showLoading, hideLoading } = useModal()
@ -212,7 +212,7 @@ async function handleEdit(record = {}) {
hideSpining()
formData.value = { ...data }
formData.value.expireAt = data?.expireAt ? dayjs(data?.expireAt) : ''
editorContent.value = data.details
editorContent.value = decryptString(data.details)
if (data.cover && data.cover.length > 0) {
formData.value.fileList = [data.cover].map(item => config('http.apiBasic') + item)
}
@ -235,7 +235,7 @@ function handleOk() {
const params = {
...values,
cover: spliceUrl(formData.value.fileList[0]),
details: editorContent.value,
details: encryptString(editorContent.value),
}
let result = null
switch (modal.value.type) {

View File

@ -134,7 +134,7 @@ import { useI18n } from 'vue-i18n'
import { PlusOutlined, MinusOutlined, SettingOutlined } from '@ant-design/icons-vue';
import dayjs from 'dayjs'
import { customersEnum, areaEnum } from "@/enums/useEnum"
import { spliceUrl } from "@/utils/util.js"
import { spliceUrl,decryptString,encryptString } from "@/utils/util.js"
const emit = defineEmits(['ok'])
const { t } = useI18n() // t
const { modal, showModal, hideModal, showLoading, hideLoading } = useModal()
@ -203,8 +203,8 @@ async function handleEdit(record = {}) {
formData.value = {
...data,
startAt:dayjs(data.startAt),
endAt:dayjs(data.endAt)
endAt:dayjs(data.endAt),
reason:decryptString(data.reason),
}
} catch (error) {
message.error({ content: error.message })
@ -221,7 +221,8 @@ function handleOk() {
showLoading()
const params = {
...values,
roles:formData.value.roles
roles:formData.value.roles,
reason:encryptString(formData.value.reason),
}
let result = null
switch (modal.value.type) {

View File

@ -44,7 +44,7 @@
<a-table :columns="columns" :data-source="listData" bordered="true" :loading="loading"
:pagination="paginationState" :scroll="{ x: 1000 }" @change="onTableChange">
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'areaId'">
<template v-if="column.dataIndex === 'areaId'">
<span>{{ areaEnum.getName(record.areaId) }}</span>
</template>
<template v-if="column.dataIndex === 'startAt'">
@ -53,8 +53,10 @@
<template v-if="column.dataIndex === 'endAt'">
<span>{{ dayjs(record.endAt).format('YYYY-MM-DD HH:mm:ss') }}</span>
</template>
<template v-if="'status' === column.dataIndex">
<template v-if="column.dataIndex === 'reason'">
<div v-html="decryptString(record.reason)"></div>
</template>
<template v-if="'status' === column.dataIndex">
<a-tag v-if="record.status === 'enabled'" :color="'green'">启用</a-tag>
<a-tag v-if="record.status === 'disabled'" :color="'red'">停用</a-tag>
</template>
@ -89,13 +91,14 @@ import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons-vu
import { useI18n } from 'vue-i18n'
import dayjs from 'dayjs'
import { customersEnum, areaEnum } from "@/enums/useEnum"
import { encryptString, decryptString } from "@/utils/util"
defineOptions({
name: 'lotteryRules',
})
const { t } = useI18n() // t
const columns = [
{ title: '所属区域', dataIndex: 'areaId' },
{ title: '规则名称', dataIndex: 'title'},
{ title: '规则名称', dataIndex: 'title' },
{ title: '开始时间', dataIndex: 'startAt', width: 180, align: 'center' },
{ title: '结束时间', dataIndex: 'endAt', width: 180, align: 'center' },
{ title: '消耗积分', dataIndex: 'price', align: 'center', width: 110 },

View File

@ -66,7 +66,7 @@ import { message } from 'ant-design-vue'
import { useI18n } from 'vue-i18n'
import dayjs from 'dayjs'
import GxUpload from '@/components/GxUpload/index.vue'
import { spliceUrl } from '@/utils/util'
import { spliceUrl,decryptString,encryptString } from '@/utils/util'
import { customersEnum, areaEnum } from "@/enums/useEnum"
const areaFormRef = ref()
const emit = defineEmits(['ok'])
@ -129,10 +129,11 @@ async function handleEdit(record = {}) {
title: data.title,
id:data.id,
status: data.status,
areaId: data.areaId,
pushAt: dayjs(data.pushAt),
imgList: [config('http.apiBasic') + data.cover]
}
editorContent.value = data.content
editorContent.value = decryptString(data.content)
if (data.cover) {
formData.value.fileList = [config('http.apiBasic') + data.img]
}
@ -158,7 +159,7 @@ function handleOk() {
name: formData.value.name,
status: formData.value.status,
title: formData.value.title,
content: editorContent.value,
content: encryptString(editorContent.value),
pushAt: formData.value.pushAt,
cover: formData.value.imgList && spliceUrl(formData.value.imgList[0])
}

View File

@ -360,7 +360,7 @@ import { useI18n } from 'vue-i18n'
import { PlusOutlined, MinusOutlined, SettingOutlined } from '@ant-design/icons-vue';
import dayjs from 'dayjs'
import { customersEnum, areaEnum } from "@/enums/useEnum"
import { spliceUrl } from "@/utils/util.js"
import { spliceUrl,decryptString,encryptString } from "@/utils/util.js"
const emit = defineEmits(['ok'])
const { t } = useI18n() // t
const { modal, showModal, hideModal, showLoading, hideLoading } = useModal()
@ -432,7 +432,7 @@ async function handleEdit(record = {}) {
price: data.price,
status: data.status,
basicArea: data.area,
disclaimerContain: data.disclaimerContain,
disclaimerContain: decryptString(data.disclaimerContain),
title: data.title,
videos: data.videos ? data.videos.map(item => config('http.apiBasic') + item) : [],
advisers: data.advisers ? data.advisers.map(item => ({ adviserName: item.name, adviserPhone: item.phone, adviserImg: item.avatar ? [config('http.apiBasic') + item.avatar] : [] })) : [{ adviserName: '', adviserPhone: '', adviserImg: [] },
@ -498,7 +498,7 @@ function handleOk() {
status: formData.value.status,
title: formData.value.title,
area: formData.value.basicArea,
disclaimerContain: formData.value.disclaimerContain,
disclaimerContain: encryptString(formData.value.disclaimerContain),
videos: formData.value.videos && formData.value.videos.map(item => spliceUrl(item)),
advisers: formData.value.advisers && formData.value.advisers.map(item => ({ name: item.adviserName, phone: item.adviserPhone, avatar: item.adviserImg[0] && spliceUrl(item.adviserImg[0]) })),
detail: {

View File

@ -79,7 +79,7 @@ import { message } from 'ant-design-vue'
import { useI18n } from 'vue-i18n'
import dayjs from 'dayjs'
import GxUpload from '@/components/GxUpload/index.vue'
import { spliceUrl } from '@/utils/util'
import { spliceUrl,decryptString,encryptString } from '@/utils/util'
const areaFormRef = ref()
const emit = defineEmits(['ok'])
const { t } = useI18n() // t
@ -142,10 +142,9 @@ async function handleEdit(id) {
return
}
hideSpining()
editorContent.value=data.content
formData.value = {
editorContent.value=decryptString(data.content)
formData.value = {
...data,
startAt:dayjs(data.startAt),
endAt:dayjs(data.endAt)
}
@ -171,7 +170,7 @@ function handleOk() {
showLoading()
const params = {
...values,
content:editorContent.value,
content:encryptString(editorContent.value),
img:formData.value.fileList?spliceUrl(formData.value.fileList[0]):''
}
let result = null

View File

@ -865,6 +865,11 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3:
shebang-command "^2.0.0"
which "^2.0.1"
crypto-js@^4.2.0:
version "4.2.0"
resolved "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.2.0.tgz"
integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==
cssesc@^3.0.0:
version "3.0.0"
resolved "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz"