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", "axios": "^1.4.0",
"clipboard": "^2.0.11", "clipboard": "^2.0.11",
"cropperjs": "^1.5.13", "cropperjs": "^1.5.13",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.9", "dayjs": "^1.11.9",
"echarts": "^5.4.3", "echarts": "^5.4.3",
"filesize": "^10.0.12", "filesize": "^10.0.12",
@ -1849,6 +1850,12 @@
"node": ">= 8" "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": { "node_modules/cssesc": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz", "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz",
@ -6370,6 +6377,11 @@
"which": "^2.0.1" "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": { "cssesc": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz", "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz",

View File

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

View File

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

View File

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

View File

@ -1,6 +1,7 @@
import { isMatch, snakeCase, toUpper, cloneDeep, keys, pick } from 'lodash-es' import { isMatch, snakeCase, toUpper, cloneDeep, keys, pick } from 'lodash-es'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc' import utc from 'dayjs/plugin/utc'
import CryptoJS from 'crypto-js';
/** /**
* 数据映射 * 数据映射
* @param {array} data 数据源 * @param {array} data 数据源
@ -334,3 +335,14 @@ export const spliceUrl=(fullUrl)=>{
const pathOnly = fullUrl.replace(/^https?:\/\/[^\/]+/, ''); const pathOnly = fullUrl.replace(/^https?:\/\/[^\/]+/, '');
return pathOnly 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 dayjs from 'dayjs'
import GxUpload from '@/components/GxUpload/index.vue' import GxUpload from '@/components/GxUpload/index.vue'
import { typerEnum, areaEnum } from "@/enums/useEnum" import { typerEnum, areaEnum } from "@/enums/useEnum"
import { spliceUrl } from "@/utils/util" import { spliceUrl,decryptString,encryptString } from "@/utils/util"
const emit = defineEmits(['ok']) const emit = defineEmits(['ok'])
const { t } = useI18n() // t const { t } = useI18n() // t
const { modal, showModal, hideModal, showLoading, hideLoading } = useModal() const { modal, showModal, hideModal, showLoading, hideLoading } = useModal()
@ -212,7 +212,7 @@ async function handleEdit(record = {}) {
hideSpining() hideSpining()
formData.value = { ...data } formData.value = { ...data }
formData.value.expireAt = data?.expireAt ? dayjs(data?.expireAt) : '' formData.value.expireAt = data?.expireAt ? dayjs(data?.expireAt) : ''
editorContent.value = data.details editorContent.value = decryptString(data.details)
if (data.cover && data.cover.length > 0) { if (data.cover && data.cover.length > 0) {
formData.value.fileList = [data.cover].map(item => config('http.apiBasic') + item) formData.value.fileList = [data.cover].map(item => config('http.apiBasic') + item)
} }
@ -235,7 +235,7 @@ function handleOk() {
const params = { const params = {
...values, ...values,
cover: spliceUrl(formData.value.fileList[0]), cover: spliceUrl(formData.value.fileList[0]),
details: editorContent.value, details: encryptString(editorContent.value),
} }
let result = null let result = null
switch (modal.value.type) { 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 { PlusOutlined, MinusOutlined, SettingOutlined } from '@ant-design/icons-vue';
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { customersEnum, areaEnum } from "@/enums/useEnum" 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 emit = defineEmits(['ok'])
const { t } = useI18n() // t const { t } = useI18n() // t
const { modal, showModal, hideModal, showLoading, hideLoading } = useModal() const { modal, showModal, hideModal, showLoading, hideLoading } = useModal()
@ -203,8 +203,8 @@ async function handleEdit(record = {}) {
formData.value = { formData.value = {
...data, ...data,
startAt:dayjs(data.startAt), startAt:dayjs(data.startAt),
endAt:dayjs(data.endAt) endAt:dayjs(data.endAt),
reason:decryptString(data.reason),
} }
} catch (error) { } catch (error) {
message.error({ content: error.message }) message.error({ content: error.message })
@ -221,7 +221,8 @@ function handleOk() {
showLoading() showLoading()
const params = { const params = {
...values, ...values,
roles:formData.value.roles roles:formData.value.roles,
reason:encryptString(formData.value.reason),
} }
let result = null let result = null
switch (modal.value.type) { switch (modal.value.type) {

View File

@ -53,7 +53,9 @@
<template v-if="column.dataIndex === 'endAt'"> <template v-if="column.dataIndex === 'endAt'">
<span>{{ dayjs(record.endAt).format('YYYY-MM-DD HH:mm:ss') }}</span> <span>{{ dayjs(record.endAt).format('YYYY-MM-DD HH:mm:ss') }}</span>
</template> </template>
<template v-if="column.dataIndex === 'reason'">
<div v-html="decryptString(record.reason)"></div>
</template>
<template v-if="'status' === column.dataIndex"> <template v-if="'status' === column.dataIndex">
<a-tag v-if="record.status === 'enabled'" :color="'green'">启用</a-tag> <a-tag v-if="record.status === 'enabled'" :color="'green'">启用</a-tag>
<a-tag v-if="record.status === 'disabled'" :color="'red'">停用</a-tag> <a-tag v-if="record.status === 'disabled'" :color="'red'">停用</a-tag>
@ -89,13 +91,14 @@ import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons-vu
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { customersEnum, areaEnum } from "@/enums/useEnum" import { customersEnum, areaEnum } from "@/enums/useEnum"
import { encryptString, decryptString } from "@/utils/util"
defineOptions({ defineOptions({
name: 'lotteryRules', name: 'lotteryRules',
}) })
const { t } = useI18n() // t const { t } = useI18n() // t
const columns = [ const columns = [
{ title: '所属区域', dataIndex: 'areaId' }, { title: '所属区域', dataIndex: 'areaId' },
{ title: '规则名称', dataIndex: 'title'}, { title: '规则名称', dataIndex: 'title' },
{ title: '开始时间', dataIndex: 'startAt', width: 180, align: 'center' }, { title: '开始时间', dataIndex: 'startAt', width: 180, align: 'center' },
{ title: '结束时间', dataIndex: 'endAt', width: 180, align: 'center' }, { title: '结束时间', dataIndex: 'endAt', width: 180, align: 'center' },
{ title: '消耗积分', dataIndex: 'price', align: 'center', width: 110 }, { 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 { useI18n } from 'vue-i18n'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import GxUpload from '@/components/GxUpload/index.vue' 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" import { customersEnum, areaEnum } from "@/enums/useEnum"
const areaFormRef = ref() const areaFormRef = ref()
const emit = defineEmits(['ok']) const emit = defineEmits(['ok'])
@ -129,10 +129,11 @@ async function handleEdit(record = {}) {
title: data.title, title: data.title,
id:data.id, id:data.id,
status: data.status, status: data.status,
areaId: data.areaId,
pushAt: dayjs(data.pushAt), pushAt: dayjs(data.pushAt),
imgList: [config('http.apiBasic') + data.cover] imgList: [config('http.apiBasic') + data.cover]
} }
editorContent.value = data.content editorContent.value = decryptString(data.content)
if (data.cover) { if (data.cover) {
formData.value.fileList = [config('http.apiBasic') + data.img] formData.value.fileList = [config('http.apiBasic') + data.img]
} }
@ -158,7 +159,7 @@ function handleOk() {
name: formData.value.name, name: formData.value.name,
status: formData.value.status, status: formData.value.status,
title: formData.value.title, title: formData.value.title,
content: editorContent.value, content: encryptString(editorContent.value),
pushAt: formData.value.pushAt, pushAt: formData.value.pushAt,
cover: formData.value.imgList && spliceUrl(formData.value.imgList[0]) 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 { PlusOutlined, MinusOutlined, SettingOutlined } from '@ant-design/icons-vue';
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { customersEnum, areaEnum } from "@/enums/useEnum" 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 emit = defineEmits(['ok'])
const { t } = useI18n() // t const { t } = useI18n() // t
const { modal, showModal, hideModal, showLoading, hideLoading } = useModal() const { modal, showModal, hideModal, showLoading, hideLoading } = useModal()
@ -432,7 +432,7 @@ async function handleEdit(record = {}) {
price: data.price, price: data.price,
status: data.status, status: data.status,
basicArea: data.area, basicArea: data.area,
disclaimerContain: data.disclaimerContain, disclaimerContain: decryptString(data.disclaimerContain),
title: data.title, title: data.title,
videos: data.videos ? data.videos.map(item => config('http.apiBasic') + item) : [], 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: [] }, 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, status: formData.value.status,
title: formData.value.title, title: formData.value.title,
area: formData.value.basicArea, area: formData.value.basicArea,
disclaimerContain: formData.value.disclaimerContain, disclaimerContain: encryptString(formData.value.disclaimerContain),
videos: formData.value.videos && formData.value.videos.map(item => spliceUrl(item)), 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]) })), advisers: formData.value.advisers && formData.value.advisers.map(item => ({ name: item.adviserName, phone: item.adviserPhone, avatar: item.adviserImg[0] && spliceUrl(item.adviserImg[0]) })),
detail: { detail: {

View File

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

View File

@ -865,6 +865,11 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3:
shebang-command "^2.0.0" shebang-command "^2.0.0"
which "^2.0.1" 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: cssesc@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz" resolved "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz"