merge v4.1.2

This commit is contained in:
RockYang
2024-11-27 15:00:02 +08:00
111 changed files with 3072 additions and 2940 deletions

View File

@@ -6,7 +6,7 @@
</div>
<div class="chat-item">
<div class="content" v-html="data.content"></div>
<div class="content" v-html="md.render(processContent(data.content))"></div>
<div class="bar" v-if="data.created_at">
<span class="bar-item"><el-icon><Clock/></el-icon> {{ dateFormat(data.created_at) }}</span>
<span class="bar-item">tokens: {{ data.tokens }}</span>
@@ -17,7 +17,7 @@
content="复制回答"
placement="bottom"
>
<el-icon class="copy-reply" :data-clipboard-text="data.orgContent">
<el-icon class="copy-reply" :data-clipboard-text="data.content">
<DocumentCopy/>
</el-icon>
</el-tooltip>
@@ -34,7 +34,7 @@
</el-tooltip>
</span>
<span class="bar-item" @click="synthesis(data.orgContent)">
<span class="bar-item" @click="synthesis(data.content)">
<el-tooltip
class="box-item"
effect="dark"
@@ -69,7 +69,7 @@
</div>
<div class="chat-item">
<div class="content-wrapper">
<div class="content" v-html="data.content"></div>
<div class="content" v-html="md.render(processContent(data.content))"></div>
</div>
<div class="bar" v-if="data.created_at">
<span class="bar-item"><el-icon><Clock/></el-icon> {{ dateFormat(data.created_at) }}</span>
@@ -81,7 +81,7 @@
content="复制回答"
placement="bottom"
>
<el-icon class="copy-reply" :data-clipboard-text="data.orgContent">
<el-icon class="copy-reply" :data-clipboard-text="data.content">
<DocumentCopy/>
</el-icon>
</el-tooltip>
@@ -98,7 +98,7 @@
</el-tooltip>
</span>
<span class="bar-item bg" @click="synthesis(data.orgContent)">
<span class="bar-item bg" @click="synthesis(data.content)">
<el-tooltip
class="box-item"
effect="dark"
@@ -118,7 +118,8 @@
<script setup>
import {Clock, DocumentCopy, Refresh} from "@element-plus/icons-vue";
import {ElMessage} from "element-plus";
import {dateFormat} from "@/utils/libs";
import {dateFormat, processContent} from "@/utils/libs";
import hl from "highlight.js";
// eslint-disable-next-line no-undef,no-unused-vars
const props = defineProps({
data: {
@@ -128,7 +129,6 @@ const props = defineProps({
content: "",
created_at: "",
tokens: 0,
orgContent: ""
},
},
readOnly: {
@@ -141,6 +141,33 @@ const props = defineProps({
},
})
const mathjaxPlugin = require('markdown-it-mathjax3')
const md = require('markdown-it')({
breaks: true,
html: true,
linkify: true,
typographer: true,
highlight: function (str, lang) {
const codeIndex = parseInt(Date.now()) + Math.floor(Math.random() * 10000000)
// 显示复制代码按钮
const copyBtn = `<span class="copy-code-btn" data-clipboard-action="copy" data-clipboard-target="#copy-target-${codeIndex}">复制</span>
<textarea style="position: absolute;top: -9999px;left: -9999px;z-index: -9999;" id="copy-target-${codeIndex}">${str.replace(/<\/textarea>/g, '&lt;/textarea>')}</textarea>`
if (lang && hl.getLanguage(lang)) {
const langHtml = `<span class="lang-name">${lang}</span>`
// 处理代码高亮
const preCode = hl.highlight(lang, str, true).value
// 将代码包裹在 pre 中
return `<pre class="code-container"><code class="language-${lang} hljs">${preCode}</code>${copyBtn} ${langHtml}</pre>`
}
// 处理代码高亮
const preCode = md.utils.escapeHtml(str)
// 将代码包裹在 pre 中
return `<pre class="code-container"><code class="language-${lang} hljs">${preCode}</code>${copyBtn}</pre>`
}
});
md.use(mathjaxPlugin)
const emits = defineEmits(['regen']);
if (!props.data.icon) {

View File

@@ -16,6 +16,7 @@
import {ref} from "vue";
import {httpGet} from "@/utils/http";
import {showMessageError} from "@/utils/dialog";
import {getLicenseInfo, getSystemInfo} from "@/store/cache";
const title = ref("")
const version = ref(process.env.VUE_APP_VERSION)
@@ -30,14 +31,14 @@ const props = defineProps({
});
// 获取系统配置
httpGet("/api/config/get?key=system").then(res => {
getSystemInfo().then(res => {
title.value = res.data.title??process.env.VUE_APP_TITLE
copyRight.value = res.data.copyright?res.data.copyright:'极客学长 © 2023 - '+new Date().getFullYear()+' All rights reserved.'
}).catch(e => {
showMessageError("获取系统配置失败:" + e.message)
})
httpGet("/api/config/license").then(res => {
getLicenseInfo().then(res => {
license.value = res.data
}).catch(e => {
showMessageError("获取 License 失败:" + e.message)

View File

@@ -221,14 +221,15 @@
</template>
<script setup>
import {nextTick, onUnmounted, ref, watch} from "vue"
import {httpGet, httpPost} from "@/utils/http";
import {ref, watch} from "vue"
import {httpPost} from "@/utils/http";
import {ElMessage} from "element-plus";
import {setUserToken} from "@/store/session";
import {validateEmail, validateMobile} from "@/utils/validate";
import {Checked, Close, Iphone, Lock, Message} from "@element-plus/icons-vue";
import SendMsg from "@/components/SendMsg.vue";
import {arrayContains} from "@/utils/libs";
import {getSystemInfo} from "@/store/cache";
// eslint-disable-next-line no-undef
const props = defineProps({
@@ -256,7 +257,7 @@ const wxImg = ref("/images/wx.png")
// eslint-disable-next-line no-undef
const emits = defineEmits(['hide', 'success']);
httpGet("/api/config/get?key=system").then(res => {
getSystemInfo().then(res => {
if (res.data) {
const registerWays = res.data['register_ways']
if (arrayContains(registerWays, "mobile")) {

View File

@@ -8,13 +8,9 @@
:title="title"
>
<div class="form" id="bind-mobile-form">
<el-alert v-if="mobile !== ''" type="info" show-icon :closable="false" style="margin-bottom: 20px;">
<p>请输入您参与众筹的 <strong style="color:#F56C6C">微信支付转账单号</strong> 兑换相应的对话次数</p>
</el-alert>
<el-form :model="form">
<el-form-item label="转账单号">
<el-input v-model="form.tx_id"/>
<el-form-item label="兑换码">
<el-input v-model="form.code"/>
</el-form-item>
</el-form>
</div>
@@ -22,7 +18,7 @@
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="save">
确认核销
立即兑换
</el-button>
</span>
</template>
@@ -33,36 +29,33 @@
import {computed, ref} from "vue";
import {ElMessage} from "element-plus";
import {httpPost} from "@/utils/http";
import {showMessageError, showMessageOK} from "@/utils/dialog";
const props = defineProps({
show: Boolean,
mobile: String
});
const showDialog = computed(() => {
return props.show
})
const title = ref('众筹码核销')
const title = ref('兑换码核销')
const form = ref({
tx_id: '',
code: '',
})
const emits = defineEmits(['hide']);
const save = () => {
if (form.value.tx_id === '') {
return ElMessage.error({message: "请输入微信支付转账单号"});
if (form.value.code === '') {
return ElMessage.error({message: "请输入兑换码"});
}
httpPost('/api/reward/verify', form.value).then(() => {
ElMessage.success({
message: '核销成功',
duration: 1000,
onClose: () => location.reload()
})
httpPost('/api/redeem/verify', form.value).then(() => {
showMessageOK("兑换成功!")
emits('hide', true)
}).catch(e => {
ElMessage.error({message: "核销失败:" + e.message});
showMessageError("兑换失败:" + e.message)
})
}

View File

@@ -50,7 +50,7 @@ import {ElMessage} from "element-plus";
import {Plus} from "@element-plus/icons-vue";
import Compressor from "compressorjs";
import {dateFormat} from "@/utils/libs";
import {checkSession} from "@/action/session";
import {checkSession} from "@/store/cache";
const user = ref({
vip: false,

View File

@@ -56,8 +56,8 @@
<script setup>
import {onMounted, ref} from "vue";
import {httpGet} from "@/utils/http";
import {ElMessage} from "element-plus";
import {getSystemInfo} from "@/store/cache";
const title = ref(process.env.VUE_APP_TITLE)
const version = ref(process.env.VUE_APP_VERSION)
@@ -99,7 +99,7 @@ const capabilities = ref([
])
onMounted(() => {
httpGet("/api/config/get?key=system").then(res => {
getSystemInfo().then(res => {
title.value = res.data.title
}).catch(e => {
ElMessage.error("获取系统配置失败:" + e.message)

View File

@@ -118,8 +118,8 @@ const items = [
},
{
icon: 'reward',
index: '/admin/reward',
title: '众筹管理',
index: '/admin/redeem',
title: '兑换码',
},
{
icon: 'control',

View File

@@ -36,7 +36,7 @@
import {useTagsStore} from '@/store/tags';
import {onBeforeRouteUpdate, useRoute, useRouter} from 'vue-router';
import {ArrowDown, Close} from "@element-plus/icons-vue";
import {checkAdminSession} from "@/action/session";
import {checkAdminSession} from "@/store/cache";
import {ElMessageBox} from "element-plus";
import {computed} from "vue";