mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-11-12 20:23:46 +08:00
merge v4.1.2
This commit is contained in:
@@ -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, '</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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")) {
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -118,8 +118,8 @@ const items = [
|
||||
},
|
||||
{
|
||||
icon: 'reward',
|
||||
index: '/admin/reward',
|
||||
title: '众筹管理',
|
||||
index: '/admin/redeem',
|
||||
title: '兑换码',
|
||||
},
|
||||
{
|
||||
icon: 'control',
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user