This commit is contained in:
孟帅
2022-11-24 23:37:34 +08:00
parent 4ffe54b6ac
commit 29bda0dcdd
1487 changed files with 97869 additions and 96539 deletions

View File

@@ -0,0 +1,205 @@
<template>
<div>
<n-spin :show="show" description="正在获取配置...">
<n-grid cols="2 s:2 m:2 l:2 xl:2 2xl:2" responsive="screen">
<n-grid-item>
<n-form :label-width="80" :model="formValue" :rules="rules" ref="formRef">
<n-form-item label="网站名称" path="basicName">
<n-input v-model:value="formValue.basicName" placeholder="请输入网站名称" />
</n-form-item>
<n-form-item label="网站logo" path="basicLogo">
<BasicUpload
:action="`${uploadUrl}/admin/upload/image`"
:headers="uploadHeaders"
:data="{ type: 0 }"
name="file"
:width="100"
:height="100"
:maxNumber="1"
@uploadChange="uploadChange"
v-model:value="formValue.basicLogo"
:helpText="
'网站logo适用于客户端使用图片大小不超过' +
componentSetting.upload.maxSize +
'MB'
"
/>
</n-form-item>
<n-form-item label="用户是否可注册开关" path="basicRegisterSwitch">
<n-radio-group
v-model:value="formValue.basicRegisterSwitch"
name="basicRegisterSwitch"
>
<n-space>
<n-radio :value="1">开启</n-radio>
<n-radio :value="0">关闭</n-radio>
</n-space>
</n-radio-group>
</n-form-item>
<n-form-item label="验证码开关" path="basicCaptchaSwitch">
<n-radio-group v-model:value="formValue.basicCaptchaSwitch" name="basicCaptchaSwitch">
<n-space>
<n-radio :value="1">开启</n-radio>
<n-radio :value="0">关闭</n-radio>
</n-space>
</n-radio-group>
</n-form-item>
<n-form-item label="网站开启访问" path="basicSystemOpen">
<n-switch
size="large"
v-model:value="formValue.basicSystemOpen"
@update:value="systemOpenChange"
/>
</n-form-item>
<n-form-item label="网站关闭提示" path="basicCloseText">
<n-input
v-model:value="formValue.basicCloseText"
type="textarea"
placeholder="请输入网站关闭提示"
/>
</n-form-item>
<n-form-item label="备案编号" path="basicIcpCode">
<n-input placeholder="请输入备案编号" v-model:value="formValue.basicIcpCode" />
</n-form-item>
<n-form-item label="版权所有" path="basicCopyright">
<n-input placeholder="版权所有" v-model:value="formValue.basicCopyright" />
</n-form-item>
<div>
<n-space>
<n-button type="primary" @click="formSubmit">保存更新</n-button>
</n-space>
</div>
</n-form>
</n-grid-item>
</n-grid>
</n-spin>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, unref, onMounted } from 'vue';
import { useDialog, useMessage } from 'naive-ui';
import { BasicUpload } from '@/components/Upload';
import { useGlobSetting } from '@/hooks/setting';
import { useUserStoreWidthOut } from '@/store/modules/user';
import componentSetting from '@/settings/componentSetting';
import { getConfig, updateConfig } from '@/api/sys/config';
const group = ref('basic');
const show = ref(false);
const useUserStore = useUserStoreWidthOut();
const globSetting = useGlobSetting();
const { uploadUrl } = globSetting;
const uploadHeaders = reactive({
Authorization: useUserStore.token,
});
const rules = {
basicName: {
required: true,
message: '请输入网站名称',
trigger: 'blur',
},
};
const formRef: any = ref(null);
const message = useMessage();
const dialog = useDialog();
const formValue = ref({
basicName: 'HotGo',
basicLogo: '',
basicIcpCode: '',
basicLoginCode: 0,
basicRegisterSwitch: 1,
basicCaptchaSwitch: 1,
basicCopyright: '© 2021 - 2023 HotGo All Rights Reserved.',
basicCloseText:
'网站维护中,暂时无法访问!本网站正在进行系统维护和技术升级,网站暂时无法访问,敬请谅解!',
basicSystemOpen: true,
});
function systemOpenChange(value) {
if (!value) {
dialog.warning({
title: '提示',
content: '您确定要关闭系统访问吗?该操作保存后立马生效,请慎重操作!',
positiveText: '确定',
negativeText: '取消',
onPositiveClick: () => {
// message.success('操作成功');
},
onNegativeClick: () => {
formValue.value.basicSystemOpen = true;
},
});
}
}
function formSubmit() {
formRef.value.validate((errors) => {
if (!errors) {
console.log('formValue.value:' + JSON.stringify(formValue.value));
updateConfig({ group: group.value, list: formValue.value })
.then((res) => {
console.log('res:' + JSON.stringify(res));
message.success('更新成功');
load();
})
.catch((error) => {
message.error(error.toString());
});
} else {
message.error('验证失败,请填写完整信息');
}
});
}
function resetForm() {
formRef.value.restoreValidation();
}
function uploadChange(list: string[]) {
// 单图模式,只需要第一个索引
if (list.length > 0) {
formValue.value.basicLogo = unref(list[0]);
} else {
formValue.value.basicLogo = unref('');
}
}
onMounted(() => {
load();
});
function load() {
show.value = true;
new Promise((_resolve, _reject) => {
getConfig({ group: group.value })
.then((res) => {
show.value = false;
// state.formValue.watermarkClarity = res;
formValue.value = res.list;
console.log('res:' + JSON.stringify(res));
})
.catch((error) => {
show.value = false;
message.error(error.toString());
});
});
}
</script>

View File

@@ -0,0 +1,179 @@
<template>
<div>
<n-spin :show="show" description="正在获取配置...">
<n-grid cols="2 s:2 m:2 l:2 xl:2 2xl:2" responsive="screen">
<n-grid-item>
<n-form :label-width="80" :model="formValue" :rules="rules" ref="formRef">
<n-form-item label="SMTP服务器" path="smtpHost">
<n-input v-model:value="formValue.smtpHost" placeholder="" />
<template #feedback> 错误的配置发送邮件会导致服务器超时</template>
</n-form-item>
<n-form-item label="SMTP端口" path="smtpPort">
<n-input v-model:value="formValue.smtpPort" placeholder="" />
<template #feedback> (不加密默认25,SSL默认465,TLS默认587)</template>
</n-form-item>
<n-form-item label="SMTP用户名" path="smtpUser">
<n-input v-model:value="formValue.smtpUser" placeholder="" />
<template #feedback>填写完整用户名</template>
</n-form-item>
<n-form-item label="SMTP密码" path="smtpPass">
<n-input v-model:value="formValue.smtpPass" placeholder="" />
<template #feedback>填写您的密码</template>
</n-form-item>
<n-form-item label="发件人名称" path="smtpSendName">
<n-input v-model:value="formValue.smtpSendName" placeholder="" />
</n-form-item>
<n-form-item label="管理员邮箱" path="smtpAdminMailbox">
<n-input v-model:value="formValue.smtpAdminMailbox" placeholder="" />
</n-form-item>
<n-form-item>
<n-button size="small" type="default" @click="sendTest">发送测试邮件</n-button>
</n-form-item>
<div>
<n-space>
<n-button type="primary" @click="formSubmit">保存更新</n-button>
</n-space>
</div>
</n-form>
</n-grid-item>
</n-grid>
</n-spin>
<n-modal
:block-scroll="false"
:mask-closable="false"
v-model:show="showModal"
:show-icon="false"
preset="dialog"
title="发送测试邮件"
>
<n-form
:model="formParams"
:rules="rules"
ref="formRef"
label-placement="left"
:label-width="80"
class="py-4"
>
<n-form-item label="接收邮箱" path="to">
<n-input placeholder="多个用;隔开" v-model:value="formParams.to" :required="true" />
</n-form-item>
</n-form>
<template #action>
<n-space>
<n-button @click="() => (showModal = false)">关闭</n-button>
<n-button type="info" :loading="formBtnLoading" @click="confirmForm">发送</n-button>
</n-space>
</template>
</n-modal>
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import { useMessage } from 'naive-ui';
import { getConfig, sendTestEmail, updateConfig } from '@/api/sys/config';
const group = ref('smtp');
const show = ref(false);
const showModal = ref(false);
const formBtnLoading = ref(false);
const formParams = ref({ to: '' });
const rules = {
smtpHost: {
required: true,
message: '请输入SMTP服务器',
trigger: 'blur',
},
};
const formRef: any = ref(null);
const message = useMessage();
const formValue = ref({
smtpHost: 'smtpdm.aliyun.com',
smtpPort: 25,
smtpUser: '',
smtpPass: '',
smtpSendName: 'HotGo',
smtpAdminMailbox: '',
});
function confirmForm(e) {
e.preventDefault();
formBtnLoading.value = true;
formRef.value.validate((errors) => {
if (!errors) {
console.log('formParams:' + JSON.stringify(formParams.value));
showModal.value = false;
sendTestEmail(formParams.value)
.then((_res) => {
message.success('发送成功');
})
.catch((error) => {
// message.error(error.toString());
});
} else {
message.error('请填写完整信息');
}
formBtnLoading.value = false;
});
}
function sendTest() {
showModal.value = true;
formBtnLoading.value = false;
}
function formSubmit() {
formRef.value.validate((errors) => {
if (!errors) {
console.log('formValue.value:' + JSON.stringify(formValue.value));
updateConfig({ group: group.value, list: formValue.value })
.then((res) => {
console.log('res:' + JSON.stringify(res));
message.success('更新成功');
load();
})
.catch((error) => {
message.error(error.toString());
});
} else {
message.error('验证失败,请填写完整信息');
}
});
}
onMounted(() => {
load();
});
function load() {
show.value = true;
new Promise((_resolve, _reject) => {
getConfig({ group: group.value })
.then((res) => {
show.value = false;
// state.formValue.watermarkClarity = res;
formValue.value = res.list;
console.log('res:' + JSON.stringify(res));
})
.catch((error) => {
show.value = false;
message.error(error.toString());
});
});
}
</script>

View File

@@ -0,0 +1,218 @@
<template>
<n-grid cols="2 s:2 m:2 l:3 xl:3 2xl:3" responsive="screen">
<n-grid-item>
<n-form :label-width="120" :model="formValue" :rules="rules" ref="formRef">
<n-form-item label="商品图片(大)">
<n-space align="center">
<span>宽度</span>
<n-input
v-model:value="formValue.bigWidth"
style="width: 80px"
placeholder="宽度像素"
/>
<span>高度</span>
<n-input
v-model:value="formValue.bigHeight"
style="width: 80px"
placeholder="高度像素"
/>
</n-space>
</n-form-item>
<n-form-item label="商品图片(小)">
<n-space align="center">
<span>宽度</span>
<n-input
v-model:value="formValue.smallWidth"
style="width: 80px"
placeholder="宽度像素"
/>
<span>高度</span>
<n-input
v-model:value="formValue.smallHeight"
style="width: 80px"
placeholder="高度像素"
/>
</n-space>
</n-form-item>
<n-form-item label="水印透明度" path="watermarkClarity">
<n-input-number
v-model:value="formValue.watermarkClarity"
:show-button="false"
placeholder="请输入水印透明度"
/>
</n-form-item>
<n-form-item label="水印图片" path="watermarkClarity">
<n-upload action="http://www.mocky.io/v2/5e4bafc63100007100d8b70f">
<n-button>上传文件</n-button>
</n-upload>
</n-form-item>
<n-form-item label="水印位置" path="watermarkPlace">
<n-select
placeholder="请选择价格精确方式"
:options="watermarkPlaceList"
v-model:value="formValue.watermarkPlace"
/>
</n-form-item>
<n-form-item label="价格精确位数" path="pricePreciseNum">
<n-select
placeholder="请选择价格精确位数"
:options="pricePreciseNumList"
v-model:value="formValue.pricePreciseNum"
/>
</n-form-item>
<n-form-item label="价格精确方式" path="pricePrecise">
<n-select
placeholder="请选择价格精确方式"
:options="pricePreciseList"
v-model:value="formValue.pricePrecise"
/>
</n-form-item>
<n-form-item label="前台显示市场价" path="isMarketPrice">
<n-switch size="large" v-model:value="formValue.isMarketPrice" />
</n-form-item>
<div>
<n-space>
<n-button type="primary" @click="formSubmit">更新显示信息</n-button>
</n-space>
</div>
</n-form>
</n-grid-item>
</n-grid>
</template>
<script lang="ts">
import { defineComponent, reactive, ref, toRefs } from 'vue';
import { useDialog, useMessage } from 'naive-ui';
const rules = {
name: {
required: true,
message: '请输入网站名称',
trigger: 'blur',
},
mobile: {
required: true,
message: '请输入联系电话',
trigger: 'input',
},
};
const watermarkPlaceList = [
{
label: '左上',
value: 1,
},
{
label: '右上',
value: 2,
},
{
label: '居中',
value: 3,
},
{
label: '右下',
value: 4,
},
];
const pricePreciseNumList = [
{
label: '2位',
value: 1,
},
{
label: '3位',
value: 2,
},
{
label: '4位',
value: 3,
},
];
const pricePreciseList = [
{
label: '四舍五入',
value: 1,
},
{
label: '向上取整',
value: 2,
},
{
label: '向下取整',
value: 3,
},
];
export default defineComponent({
setup() {
const formRef: any = ref(null);
const message = useMessage();
const dialog = useDialog();
const state = reactive({
formValue: {
bigWidth: '',
bigHeight: '',
smallWidth: '',
smallHeight: '',
watermarkClarity: null,
pricePrecise: 1,
isMarketPrice: true,
pricePreciseNum: null,
},
});
function systemOpenChange(value) {
if (!value) {
dialog.warning({
title: '提示',
content: '您确定要关闭系统访问吗?该操作立马生效,请慎重操作!',
positiveText: '确定',
negativeText: '取消',
onPositiveClick: () => {
message.success('操作成功');
},
onNegativeClick: () => {
state.formValue.systemOpen = true;
},
});
}
}
function formSubmit() {
formRef.value.validate((errors) => {
if (!errors) {
message.success('验证成功');
} else {
message.error('验证失败,请填写完整信息');
}
});
}
function resetForm() {
formRef.value.restoreValidation();
}
return {
formRef,
...toRefs(state),
pricePreciseList,
watermarkPlaceList,
pricePreciseNumList,
rules,
formSubmit,
resetForm,
systemOpenChange,
};
},
});
</script>

View File

@@ -0,0 +1,98 @@
<template>
<div>
<n-spin :show="show" description="正在获取配置...">
<n-grid cols="2 s:2 m:2 l:2 xl:2 2xl:2" responsive="screen">
<n-grid-item>
<n-form :label-width="80" :model="formValue" :rules="rules" ref="formRef">
<n-form-item label="默认主题" path="themeDarkTheme">
<n-input v-model:value="formValue.themeDarkTheme" placeholder="" />
<template #feedback> 可选'dark' 'light' </template>
</n-form-item>
<n-form-item label="默认系统主题" path="themeAppTheme">
<n-input v-model:value="formValue.themeAppTheme" placeholder="" />
<template #feedback> 默认#2d8cf0 </template>
</n-form-item>
<n-form-item label="默认侧边栏风格" path="themeNavTheme">
<n-input v-model:value="formValue.themeNavTheme" placeholder="" />
<template #feedback>可选'light' 'header-dark'</template>
</n-form-item>
<div>
<n-space>
<n-button type="primary" @click="formSubmit">保存更新</n-button>
</n-space>
</div>
</n-form>
</n-grid-item>
</n-grid>
</n-spin>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import { useMessage } from 'naive-ui';
import { getConfig, updateConfig } from '@/api/sys/config';
const group = ref('theme');
const show = ref(false);
const rules = {
themeDarkTheme: {
required: true,
message: '请输入默认主题',
trigger: 'blur',
},
};
const formRef: any = ref(null);
const message = useMessage();
const formValue = ref({
themeDarkTheme: 'dark',
themeAppTheme: '#2d8cf0',
themeNavTheme: 'dark',
});
function formSubmit() {
formRef.value.validate((errors) => {
if (!errors) {
console.log('formValue.value:' + JSON.stringify(formValue.value));
updateConfig({ group: group.value, list: formValue.value })
.then((res) => {
console.log('res:' + JSON.stringify(res));
message.success('更新成功');
load();
})
.catch((error) => {
message.error(error.toString());
});
} else {
message.error('验证失败,请填写完整信息');
}
});
}
onMounted(() => {
load();
});
function load() {
show.value = true;
new Promise((_resolve, _reject) => {
getConfig({ group: group.value })
.then((res) => {
show.value = false;
// state.formValue.watermarkClarity = res;
formValue.value = res.list;
console.log('res:' + JSON.stringify(res));
})
.catch((error) => {
show.value = false;
message.error(error.toString());
});
});
}
</script>

View File

@@ -0,0 +1,102 @@
<template>
<div>
<n-grid :x-gap="24">
<n-grid-item span="6">
<n-card :bordered="false" size="small" class="proCard">
<n-thing
class="thing-cell"
v-for="item in typeTabList"
:key="item.key"
:class="{ 'thing-cell-on': type === item.key }"
@click="switchType(item)"
>
<template #header>{{ item.name }}</template>
<template #description>{{ item.desc }}</template>
</n-thing>
</n-card>
</n-grid-item>
<n-grid-item span="18">
<n-card :bordered="false" size="small" :title="typeTitle" class="proCard">
<BasicSetting v-if="type === 1" />
<ThemeSetting v-if="type === 2" />
<RevealSetting v-if="type === 3" />
<EmailSetting v-if="type === 4" />
</n-card>
</n-grid-item>
</n-grid>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive, toRefs } from 'vue';
import BasicSetting from './BasicSetting.vue';
import RevealSetting from './RevealSetting.vue';
import EmailSetting from './EmailSetting.vue';
import ThemeSetting from './ThemeSetting.vue';
const typeTabList = [
{
name: '基本设置',
desc: '系统常规设置',
key: 1,
},
{
name: '主题设置',
desc: '系统主题设置',
key: 2,
},
// {
// name: '显示设置',
// desc: '系统显示设置',
// key: 3,
// },
{
name: '邮件设置',
desc: '系统邮件设置',
key: 4,
},
];
export default defineComponent({
components: { BasicSetting, RevealSetting, EmailSetting, ThemeSetting },
setup() {
const state = reactive({
type: 1,
typeTitle: '基本设置',
});
function switchType(e) {
state.type = e.key;
state.typeTitle = e.name;
}
return {
...toRefs(state),
switchType,
typeTabList,
};
},
});
</script>
<style lang="less" scoped>
.thing-cell {
margin: 0 -16px 10px;
padding: 5px 16px;
&:hover {
background: #f3f3f3;
cursor: pointer;
}
}
.thing-cell-on {
background: #f0faff;
color: #2d8cf0;
::v-deep(.n-thing-main .n-thing-header .n-thing-header__title) {
color: #2d8cf0;
}
&:hover {
background: #f0faff;
}
}
</style>