mirror of
https://gitee.com/niucloud-team/niucloud-admin.git
synced 2026-03-12 10:55:34 +00:00
up
This commit is contained in:
parent
b17198f1f4
commit
7412775c03
@ -157,7 +157,7 @@ UE.I18N['zh-cn'] = {
|
||||
'elementPathTip': "元素路径",
|
||||
'wordCountTip': "字数统计",
|
||||
'wordCountMsg': '{#count} / {#leave}',
|
||||
'wordOverFlowMsg': '<span style="color:red;">字数超出最大允许值,服务器可能拒绝保存!</span>',
|
||||
'wordOverFlowMsg': '<span style="color:red;">字数超出最大允许值!</span>',
|
||||
'ok': "确认",
|
||||
'cancel': "取消",
|
||||
'closeDialog': "关闭对话框",
|
||||
|
||||
@ -35,4 +35,9 @@ onMounted(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped>
|
||||
.el-page-header__header .el-page-header__left .el-page-header__content{
|
||||
font-size: 14px !important;
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -199,6 +199,12 @@ export function copyDiy(params: Record<string, any>) {
|
||||
return request.post(`diy/copy`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取自定义页面选择列表
|
||||
*/
|
||||
export function getPageLink(params: Record<string, any>) {
|
||||
return request.get(`diy/page_link`, { params })
|
||||
}
|
||||
/***************************************************** 主题风格 ****************************************************/
|
||||
|
||||
|
||||
@ -237,7 +243,7 @@ export function editTheme(params: Record<string, any>) {
|
||||
|
||||
/**
|
||||
* 删除配色
|
||||
* @param params
|
||||
* @param id
|
||||
*/
|
||||
export function deleteTheme(id: number) {
|
||||
return request.delete(`diy/theme/delete/${ id }`, { showSuccessMessage: true })
|
||||
|
||||
@ -393,7 +393,7 @@ export function memberRemark(params: Record<string, any>) {
|
||||
}
|
||||
/**
|
||||
* 检查打款进度
|
||||
* @param params
|
||||
* @param id
|
||||
*/
|
||||
export function memberCheck(id: number) {
|
||||
return request.put(`member/cash_out/check/${id}`, {}, { showSuccessMessage: true })
|
||||
|
||||
@ -81,7 +81,6 @@ export function getSmsLog(params: Record<string, any>) {
|
||||
|
||||
/**
|
||||
* 获取当前登录子账号
|
||||
* @param params
|
||||
*/
|
||||
export function getAccountIsLogin() {
|
||||
return request.get(`notice/niusms/config`)
|
||||
@ -105,7 +104,7 @@ export function registerAccount(params: Record<string, any>) {
|
||||
|
||||
/**
|
||||
* 获取当前登录子账号信息
|
||||
* @param params
|
||||
* @param username
|
||||
*/
|
||||
export function getAccountInfo(username: string) {
|
||||
return request.get(`notice/niusms/account/info/${username}`)
|
||||
@ -121,6 +120,7 @@ export function getTemplateList(params: Record<string, any>) {
|
||||
|
||||
/**
|
||||
* 获取签名列表
|
||||
* @param username
|
||||
* @param params
|
||||
*/
|
||||
export function getSignList(username: string, params: Record<string, any>) {
|
||||
@ -129,6 +129,7 @@ export function getSignList(username: string, params: Record<string, any>) {
|
||||
|
||||
/**
|
||||
* 添加签名
|
||||
* @param username
|
||||
* @param params
|
||||
*/
|
||||
export function addSign(username: string, params: Record<string, any>) {
|
||||
@ -137,6 +138,7 @@ export function addSign(username: string, params: Record<string, any>) {
|
||||
|
||||
/**
|
||||
* 删除签名
|
||||
* @param username
|
||||
* @param params
|
||||
*/
|
||||
export function deleteSign(username: string, params: Record<string, any>) {
|
||||
@ -145,6 +147,7 @@ export function deleteSign(username: string, params: Record<string, any>) {
|
||||
|
||||
/**
|
||||
* 更新子账号信息
|
||||
* @param username
|
||||
* @param params
|
||||
*/
|
||||
export function editAccount(username: string,params: Record<string, any>) {
|
||||
@ -153,6 +156,7 @@ export function editAccount(username: string,params: Record<string, any>) {
|
||||
|
||||
/**
|
||||
* 获取短信发送记录
|
||||
* @param username
|
||||
* @param params
|
||||
*/
|
||||
export function getSmsSendList(username: string, params: Record<string, any>) {
|
||||
@ -161,6 +165,7 @@ export function getSmsSendList(username: string, params: Record<string, any>) {
|
||||
|
||||
/**
|
||||
* 获取充值列表
|
||||
* @param username
|
||||
* @param params
|
||||
*/
|
||||
export function getSmsOrdersList(username: string, params: Record<string, any>) {
|
||||
@ -169,7 +174,6 @@ export function getSmsOrdersList(username: string, params: Record<string, any>)
|
||||
|
||||
/**
|
||||
* 获取套餐列表
|
||||
* @param params
|
||||
*/
|
||||
export function getSmsPackagesList() {
|
||||
return request.get(`notice/niusms/packages`)
|
||||
@ -177,7 +181,6 @@ export function getSmsPackagesList() {
|
||||
|
||||
/**
|
||||
* 获取图像验证码
|
||||
* @param params
|
||||
*/
|
||||
export function getSmsCaptcha() {
|
||||
return request.get(`notice/niusms/captcha`)
|
||||
@ -193,7 +196,6 @@ export function getSmsSend(params: Record<string, any>) {
|
||||
|
||||
/**
|
||||
* 添加签名配置项
|
||||
* @param params
|
||||
*/
|
||||
export function getSmsSignConfig() {
|
||||
return request.get(`notice/niusms/sign/report/config`)
|
||||
@ -201,7 +203,6 @@ export function getSmsSignConfig() {
|
||||
|
||||
/**
|
||||
* 模版报备配置项
|
||||
* @param params
|
||||
*/
|
||||
export function getTemplateReportConfig() {
|
||||
return request.get(`notice/niusms/template/report/config`)
|
||||
@ -209,6 +210,10 @@ export function getTemplateReportConfig() {
|
||||
|
||||
/**
|
||||
* 模版报备
|
||||
* @param sms_type
|
||||
* @param username
|
||||
* @param sms_type
|
||||
* @param username
|
||||
* @param params
|
||||
*/
|
||||
export function reportTemplate(sms_type: string, username: string, params: Record<string, any>) {
|
||||
@ -217,6 +222,10 @@ export function reportTemplate(sms_type: string, username: string, params: Recor
|
||||
|
||||
/**
|
||||
* 模版详情
|
||||
* @param sms_type
|
||||
* @param username
|
||||
* @param sms_type
|
||||
* @param username
|
||||
* @param params
|
||||
*/
|
||||
export function getreportTemplateInfo(sms_type: string, username: string,params: Record<string, any>) {
|
||||
@ -226,6 +235,7 @@ export function getreportTemplateInfo(sms_type: string, username: string,params:
|
||||
|
||||
/**
|
||||
* 充值下单
|
||||
* @param username
|
||||
* @param params
|
||||
*/
|
||||
export function smsOrderCreate(username: string, params: Record<string, any>) {
|
||||
@ -234,6 +244,7 @@ export function smsOrderCreate(username: string, params: Record<string, any>) {
|
||||
|
||||
/**
|
||||
* 获取支付信息
|
||||
* @param username
|
||||
* @param params
|
||||
*/
|
||||
export function getOrderPayInfo(username: string, params: Record<string, any>) {
|
||||
@ -242,6 +253,7 @@ export function getOrderPayInfo(username: string, params: Record<string, any>) {
|
||||
|
||||
/**
|
||||
* 获取订单详情
|
||||
* @param username
|
||||
* @param params
|
||||
*/
|
||||
export function getOrderInfo(username: string, params: Record<string, any>) {
|
||||
@ -250,6 +262,7 @@ export function getOrderInfo(username: string, params: Record<string, any>) {
|
||||
|
||||
/**
|
||||
* 获取支付状态
|
||||
* @param username
|
||||
* @param params
|
||||
*/
|
||||
export function getOrderPayStatus(username: string, params: Record<string, any>) {
|
||||
@ -258,6 +271,7 @@ export function getOrderPayStatus(username: string, params: Record<string, any>)
|
||||
|
||||
/**
|
||||
* 计算金额
|
||||
* @param username
|
||||
* @param params
|
||||
*/
|
||||
export function calculateOrderPay(username: string, params: Record<string, any>) {
|
||||
@ -274,7 +288,9 @@ export function enableNiusms(params: Record<string, any>) {
|
||||
|
||||
/**
|
||||
* 同步模版状态
|
||||
* @param params
|
||||
* @param username
|
||||
* @param sms_type
|
||||
* @param username
|
||||
*/
|
||||
export function templateSync(sms_type: string, username: string) {
|
||||
return request.get(`notice/niusms/template/sync/${sms_type}/${username}`)
|
||||
@ -282,6 +298,7 @@ export function templateSync(sms_type: string, username: string) {
|
||||
|
||||
/**
|
||||
* 重置密码
|
||||
* @param username
|
||||
* @param params
|
||||
*/
|
||||
export function resetPassword(username: string,params: Record<string, any>) {
|
||||
@ -290,7 +307,9 @@ export function resetPassword(username: string,params: Record<string, any>) {
|
||||
|
||||
/**
|
||||
* 清除模版报备
|
||||
* @param params
|
||||
* @param template_id
|
||||
* @param username
|
||||
* @param template_id
|
||||
*/
|
||||
export function clearTemplate(username: string,template_id: string) {
|
||||
return request.delete(`notice/niusms/template/${username}/${template_id}`)
|
||||
|
||||
@ -56,7 +56,6 @@ export function getPayRefundInfo(refund_no: string) {
|
||||
|
||||
/**
|
||||
* 获取退款状态字典
|
||||
* @param refund_no
|
||||
*/
|
||||
export function getRefundStatus() {
|
||||
return request.get(`pay/refund/status`)
|
||||
|
||||
@ -113,3 +113,7 @@ export function getPreviewPoster(params: Record<string, any>) {
|
||||
export function getPosterGenerate(params: Record<string, any>) {
|
||||
return request.get(`sys/poster/generate`, { params, showErrorMessage: false })
|
||||
}
|
||||
// 判断是否安装imagemagick扩展
|
||||
export function checkImagick() {
|
||||
return request.get(`sys/check_imagick`, { showErrorMessage: false })
|
||||
}
|
||||
@ -486,6 +486,15 @@ export function clearCronLog(params: Record<string, any>) {
|
||||
return request.put(`sys/schedule/log/clear`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置计划任务
|
||||
* @returns
|
||||
*/
|
||||
export function resetCron() {
|
||||
return request.post(`sys/schedule/reset`, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
|
||||
/***************************************************** 协议管理 ****************************************************/
|
||||
|
||||
/**
|
||||
|
||||
@ -19,6 +19,7 @@ export function getUpgradeTask() {
|
||||
/**
|
||||
* 升级
|
||||
* @param addon
|
||||
* @param params
|
||||
*/
|
||||
export function upgradeAddon(addon: string = '', params: Record<string, any> = {}) {
|
||||
return request.post(addon ? `upgrade/${ addon }` : 'upgrade', params)
|
||||
@ -137,3 +138,25 @@ export function performRecoveryTasks(params: Record<string, any>) {
|
||||
export function performBackupTasks(params: Record<string, any>) {
|
||||
return request.get("backup/task", params)
|
||||
}
|
||||
|
||||
/**
|
||||
* 连通测试
|
||||
* @param params
|
||||
*/
|
||||
export function connectTest(params: Record<string, any>) {
|
||||
return request.post("niucloud/build/connect_test", params)
|
||||
}
|
||||
/**
|
||||
* 保存服务器地址
|
||||
* @param params
|
||||
*/
|
||||
export function setLocalUrl(params: Record<string, any>) {
|
||||
return request.post("niucloud/build/set_local_url", params)
|
||||
}
|
||||
/**
|
||||
* 获取服务器地址
|
||||
* @param params
|
||||
*/
|
||||
export function getLocalUrl(params: Record<string, any>) {
|
||||
return request.get("niucloud/build/get_local_url", params)
|
||||
}
|
||||
|
||||
@ -21,6 +21,23 @@ export function getVerifyDetail(verifyCode: string) {
|
||||
return request.get(`verify/verify/${ verifyCode }`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取核销详情
|
||||
* @param verifyCode
|
||||
* @returns
|
||||
*/
|
||||
export function getVerifyDetailInfo(verifyCode: string) {
|
||||
return request.get(`verify/detail/${ verifyCode }`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 核销
|
||||
* @param verifyCode
|
||||
* @returns
|
||||
*/
|
||||
export function verify(verifyCode: string, params: Record<string, any>) {
|
||||
return request.post(`verify/verify/${ verifyCode }`,params,{ showSuccessMessage: true})
|
||||
}
|
||||
/***************************************************** 核销员 ****************************************************/
|
||||
|
||||
/**
|
||||
|
||||
BIN
admin/src/app/assets/images/goods_default.png
Normal file
BIN
admin/src/app/assets/images/goods_default.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
BIN
admin/src/app/assets/images/icon-addon-one.png
Normal file
BIN
admin/src/app/assets/images/icon-addon-one.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.7 KiB |
BIN
admin/src/app/assets/images/write.png
Normal file
BIN
admin/src/app/assets/images/write.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 481 B |
@ -5,7 +5,7 @@
|
||||
<div class="h-[50vh] flex flex-col" v-if="cloudBuildCheck && !cloudBuildTask">
|
||||
<!-- <el-scrollbar> -->
|
||||
<div class="bg-[#fff] my-3" v-if="cloudBuildCheck.dir">
|
||||
<div class="">
|
||||
<div>
|
||||
<p class="pl-[20px] ">{{ t('cloudbuild.dirPermission') }}</p>
|
||||
<div class="mt-[10px] mx-[20px] text-[14px] cursor-pointer text-primary flex items-center justify-between bg-[#EFF6FF] rounded-[4px] p-[10px]" @click="cloudBuildCheckDirFn">
|
||||
<div class="flex items-center">
|
||||
@ -14,7 +14,7 @@
|
||||
<div class="border-[1px] border-primary rounded-[3px] w-[72px] h-[26px] leading-[25px] text-center">立即查看</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="px-[20px] pt-[10px] text-[14px] el-table">
|
||||
<el-row class="py-[10px] items table-head-bg pl-[15px] mb-[10px]">
|
||||
<el-col :span="18">
|
||||
@ -66,7 +66,7 @@
|
||||
<!-- </el-scrollbar> -->
|
||||
</div>
|
||||
<div class="h-[45vh]" v-show="cloudBuildTask">
|
||||
<terminal ref="terminalRef" context="" :init-log="null" :show-header="false" :show-log-time="true" @exec-cmd="onExecCmd"/>
|
||||
<terminal ref="terminalRef" :name="`cloud-build-${terminalId}`" context="" :init-log="null" :show-header="false" :show-log-time="true" @exec-cmd="onExecCmd"/>
|
||||
</div>
|
||||
<div class="flex justify-end mt-[20px]" v-show="cloudBuildTask">
|
||||
<el-button @click="dialogCancel()" class="!w-[90px]">取消</el-button>
|
||||
@ -81,7 +81,7 @@
|
||||
<img src="@/app/assets/images/error_icon.png" alt="">
|
||||
</template>
|
||||
<template #extra>
|
||||
<el-scrollbar class="max-h-[150px] overflow-auto text-[15px] text-[#4F516D] mb-[15px] mt-[-15px]">
|
||||
<el-scrollbar class="max-h-[150px] !overflow-auto text-[15px] text-[#4F516D] mb-[15px] mt-[-15px]">
|
||||
{{errorInfo}}
|
||||
</el-scrollbar>
|
||||
<el-button @click="handleReturn" class="!w-[90px]">错误信息</el-button>
|
||||
@ -110,15 +110,16 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, h, watch ,computed} from 'vue'
|
||||
import { ref, h, watch, computed } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getCloudBuildLog, getCloudBuildTask, cloudBuild, clearCloudBuildTask, preBuildCheck } from '@/app/api/cloud'
|
||||
import { Terminal, TerminalFlash } from 'vue-web-terminal'
|
||||
import 'vue-web-terminal/lib/theme/dark.css'
|
||||
import { AnyObject } from "@/types/global"
|
||||
import { ElNotification, ElMessageBox } from "element-plus"
|
||||
import { AnyObject } from '@/types/global'
|
||||
import { ElNotification, ElMessageBox } from 'element-plus'
|
||||
|
||||
const showDialog = ref<boolean>(false)
|
||||
const terminalId = ref(Date.now());
|
||||
const cloudBuildTask = ref<null | AnyObject>(null)
|
||||
const active = ref('build')
|
||||
const cloudBuildCheck = ref<null | AnyObject>(null)
|
||||
@ -174,7 +175,7 @@ const getCloudBuildLogFn = () => {
|
||||
return
|
||||
}
|
||||
|
||||
const data = res.data.data ?? [];
|
||||
const data = res.data.data ?? []
|
||||
let error = ''
|
||||
|
||||
if (data[0] && data[0].length && showDialog.value) {
|
||||
@ -203,7 +204,7 @@ const getCloudBuildLogFn = () => {
|
||||
if (!cloudBuildLog.includes(item.action)) {
|
||||
terminalRef.value.pushMessage({ content: `${item.action}` })
|
||||
cloudBuildLog.push(item.action)
|
||||
|
||||
|
||||
if (item.code == 0) {
|
||||
error = item.msg
|
||||
terminalRef.value.pushMessage({ content: item.msg, class: 'error' })
|
||||
@ -243,8 +244,7 @@ const handleReturn = () => {
|
||||
closeType.value = 'success'
|
||||
}
|
||||
|
||||
|
||||
let notificationEl : any = null
|
||||
const notificationEl : any = null
|
||||
/**
|
||||
* 升级中任务提示
|
||||
*/
|
||||
@ -315,9 +315,9 @@ const onExecCmd = (key, command, success, failed, name) => {
|
||||
}
|
||||
|
||||
const makeIterator = (array: string[]) => {
|
||||
var nextIndex = 0
|
||||
let nextIndex = 0
|
||||
return {
|
||||
next() {
|
||||
next () {
|
||||
if ((nextIndex + 1) == array.length) {
|
||||
nextIndex = 0
|
||||
}
|
||||
@ -397,7 +397,8 @@ defineExpose({
|
||||
open,
|
||||
cloudBuildTask,
|
||||
loading,
|
||||
elNotificationClick
|
||||
elNotificationClick,
|
||||
getCloudBuildTaskFn
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@ -147,8 +147,7 @@ defineExpose({
|
||||
left: 125px;
|
||||
border-left-color: #dddddd;
|
||||
border-left-style: dashed;
|
||||
margin: 12px 0;
|
||||
margin-top: 24px;
|
||||
margin: 24px 0 12px;
|
||||
height: calc(100% - 24px - 12px);
|
||||
}
|
||||
|
||||
@ -201,7 +200,7 @@ defineExpose({
|
||||
|
||||
.time-dialog >>> .el-collapse-item__content {
|
||||
margin-top: 15px;
|
||||
padding-bottom: 0px !important;
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.time-dialog >>> .el-timeline-item__node--01 {
|
||||
|
||||
@ -130,8 +130,9 @@
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
<div class="h-[370px] mt-[30px]" v-show="showTerminal && upgradeTask && !errorDialog">
|
||||
<terminal ref="terminalRef" :context="upgradeTask ? upgradeTask.upgrade.app_key : ''" :init-log="null" :show-header="false" :show-log-time="true" @exec-cmd="onExecCmd" />
|
||||
<terminal ref="terminalRef" :name="`upgrade-${terminalId}`" :context="upgradeTask ? upgradeTask.upgrade.app_key : ''" :init-log="null" :show-header="false" :show-log-time="true" @exec-cmd="onExecCmd" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- 是否备份选择 -->
|
||||
<div class="flex flex-col" v-show="active == 'backup'">
|
||||
@ -155,18 +156,21 @@
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
<div class="mt-[50px]" v-show="errorDialog">
|
||||
<el-result icon="error" :title="t('升级失败')" :sub-title="errorMsg">
|
||||
<div class="mt-[20px] h-[370px]" v-show="errorDialog">
|
||||
<el-result icon="error" :title="t('升级失败')">
|
||||
<template #icon>
|
||||
<img src="@/app/assets/images/error_icon.png" alt="" />
|
||||
</template>
|
||||
<template #extra>
|
||||
<el-scrollbar class="max-h-[120px] !overflow-auto text-[15px] text-[#4F516D] mb-[15px] mt-[-15px]">
|
||||
{{errorMsg}}
|
||||
</el-scrollbar>
|
||||
<el-button @click="handleBack()" class="!w-[90px]">错误信息</el-button>
|
||||
<el-button @click="showDialog=false" type="primary" class="!w-[90px]">完成</el-button>
|
||||
</template>
|
||||
</el-result>
|
||||
</div>
|
||||
<div class="mt-[50px]" v-show="active == 'complete'">
|
||||
<div class="mt-[20px]" v-show="active == 'complete'">
|
||||
<el-result icon="success" :title="t('upgrade.upgradeSuccess')">
|
||||
<template #icon>
|
||||
<img src="@/app/assets/images/success_icon.png" alt="">
|
||||
@ -189,7 +193,7 @@
|
||||
<div class="dialog-footer">
|
||||
<!-- 查看升级内容 -->
|
||||
<el-button v-if="step == 1 && upgradeContent.content.length && isAllowUpgrade" @click="step = 2" type="primary">{{ t("upgrade.upgradeButton") }}</el-button>
|
||||
|
||||
<el-button type="primary" v-show="step == 2 && showTerminal && upgradeTask && !errorDialog" :loading="timeloading" class="!w-[140px]">已用时 {{ formatUpgradeDuration }}</el-button>
|
||||
<template v-if="step == 2 && active != 'complete'">
|
||||
<!-- <el-button v-if="active == 'content'" @click="showDialog = false">{{ t("return") }}</el-button>-->
|
||||
<el-button type="primary" :disabled="!is_pass" v-if="active == 'upgrade' && !upgradeTask" @click="() => { active = 'backup'; numberOfSteps = 1 }">{{ t("nextStep") }}</el-button>
|
||||
@ -225,10 +229,10 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, h, watch ,computed} from "vue"
|
||||
import { t } from "@/lang"
|
||||
import { getVersions } from "@/app/api/auth"
|
||||
import { getFrameworkNewVersion } from "@/app/api/module"
|
||||
import { ref, h, watch, computed } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getVersions } from '@/app/api/auth'
|
||||
import { getFrameworkNewVersion } from '@/app/api/module'
|
||||
import {
|
||||
getUpgradeContent,
|
||||
getUpgradeTask,
|
||||
@ -236,15 +240,16 @@ import {
|
||||
executeUpgrade,
|
||||
preUpgradeCheck,
|
||||
clearUpgradeTask, upgradeUserOperate
|
||||
} from "@/app/api/upgrade"
|
||||
import { Terminal, TerminalFlash } from "vue-web-terminal"
|
||||
import "vue-web-terminal/lib/theme/dark.css"
|
||||
import { AnyObject } from "@/types/global"
|
||||
import { ElNotification, ElMessage, ElMessageBox } from "element-plus"
|
||||
import Storage from "@/utils/storage"
|
||||
} from '@/app/api/upgrade'
|
||||
import { Terminal, TerminalFlash } from 'vue-web-terminal'
|
||||
import 'vue-web-terminal/lib/theme/dark.css'
|
||||
import { AnyObject } from '@/types/global'
|
||||
import { ElNotification, ElMessage, ElMessageBox } from 'element-plus'
|
||||
import Storage from '@/utils/storage'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const router = useRouter()
|
||||
const terminalId = ref(Date.now());
|
||||
const showDialog = ref<boolean>(false)
|
||||
const upgradeContent = ref<null | AnyObject>(null)
|
||||
const isAllowUpgrade = ref(true) // 是否允许升级
|
||||
@ -254,7 +259,7 @@ const step = ref(1)
|
||||
const upgradeCheck = ref<null | AnyObject>(null)
|
||||
const loading = ref(false)
|
||||
const terminalRef: any = ref(null)
|
||||
const emits = defineEmits(["complete", "cloudbuild"])
|
||||
const emits = defineEmits(['complete', 'cloudbuild'])
|
||||
const upgradeTipsShowDialog = ref<boolean>(false)
|
||||
let upgradeLog: any = []
|
||||
let errorLog: any = []
|
||||
@ -269,17 +274,18 @@ const upgradeOption = ref({
|
||||
// 升级步骤排除,backupCode 备份代码,backupSql 备份数据库
|
||||
const excludeSteps: any = ref([
|
||||
{
|
||||
name: "备份源码",
|
||||
code: "backupCode"
|
||||
name: '备份源码',
|
||||
code: 'backupCode'
|
||||
},
|
||||
{
|
||||
name: "备份数据库",
|
||||
code: "backupSql"
|
||||
name: '备份数据库',
|
||||
code: 'backupSql'
|
||||
}
|
||||
])
|
||||
/**
|
||||
* 查询升级任务
|
||||
*/
|
||||
const timeloading = ref(false)
|
||||
const showTerminal = ref(false)
|
||||
const upgradeStartTime = ref<number | null>(null)
|
||||
const upgradeDuration = ref(0) // 单位:秒
|
||||
@ -293,7 +299,7 @@ const getUpgradeTaskFn = () => {
|
||||
if (!upgradeContent.value) {
|
||||
upgradeContent.value = data.upgrade_content
|
||||
|
||||
if ( upgradeContent.value || !data.upgrade_content || !Array.isArray(data.upgrade_content.content)) {
|
||||
if (upgradeContent.value || !data.upgrade_content || !Array.isArray(data.upgrade_content.content)) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -320,8 +326,9 @@ const getUpgradeTaskFn = () => {
|
||||
}
|
||||
if (!upgradeTask.value) {
|
||||
showTerminal.value = true
|
||||
terminalRef.value.execute("clear")
|
||||
terminalRef.value.execute("开始升级")
|
||||
terminalRef.value.execute('clear')
|
||||
terminalRef.value.execute('开始升级')
|
||||
timeloading.value = true
|
||||
upgradeStartTime.value = Date.now()
|
||||
upgradeDuration.value = 0
|
||||
if (upgradeTimer) clearInterval(upgradeTimer)
|
||||
@ -334,7 +341,7 @@ const getUpgradeTaskFn = () => {
|
||||
|
||||
data.log.forEach((item) => {
|
||||
if (!upgradeLog.includes(item)) {
|
||||
terminalRef.value.pushMessage({ content: `${ item }` })
|
||||
terminalRef.value.pushMessage({ content: `${item}` })
|
||||
upgradeLog.push(item)
|
||||
}
|
||||
})
|
||||
@ -342,7 +349,7 @@ const getUpgradeTaskFn = () => {
|
||||
if (data.error) {
|
||||
data.error.forEach((item) => {
|
||||
if (!errorLog.includes(item)) {
|
||||
terminalRef.value.pushMessage({ content: item, class: "error" })
|
||||
terminalRef.value.pushMessage({ content: item, class: 'error' })
|
||||
errorLog.push(item)
|
||||
errorMsg.value = item
|
||||
}
|
||||
@ -353,28 +360,30 @@ const getUpgradeTaskFn = () => {
|
||||
clearInterval(upgradeTimer)
|
||||
upgradeTimer = null
|
||||
}
|
||||
timeloading.value = false
|
||||
}
|
||||
// 恢复完毕
|
||||
if (data.step == "restoreComplete") {
|
||||
if (data.step == 'restoreComplete') {
|
||||
flashInterval && clearInterval(flashInterval)
|
||||
return
|
||||
}
|
||||
// 升级完成
|
||||
if (data.step == "upgradeComplete") {
|
||||
active.value = "complete"
|
||||
if (data.step == 'upgradeComplete') {
|
||||
active.value = 'complete'
|
||||
showTerminal.value = false
|
||||
numberOfSteps.value = 4
|
||||
notificationEl && notificationEl.close()
|
||||
emits("complete")
|
||||
emits('complete')
|
||||
if (upgradeTimer) {
|
||||
clearInterval(upgradeTimer)
|
||||
upgradeTimer = null
|
||||
}
|
||||
timeloading.value = false
|
||||
clearUpgradeTask()
|
||||
return
|
||||
}
|
||||
numberOfSteps.value = 2
|
||||
active.value = "upgrade"
|
||||
active.value = 'upgrade'
|
||||
executeUpgradeFn()
|
||||
})
|
||||
}
|
||||
@ -382,13 +391,12 @@ const getUpgradeTaskFn = () => {
|
||||
getUpgradeTaskFn()
|
||||
const isBack = ref(false)
|
||||
const handleBack = () => {
|
||||
active.value = "upgrade"
|
||||
active.value = 'upgrade'
|
||||
isBack.value = true
|
||||
showTerminal.value = true
|
||||
errorDialog.value = false // 隐藏错误弹窗
|
||||
}
|
||||
|
||||
|
||||
const formatUpgradeDuration = computed(() => {
|
||||
const s = upgradeDuration.value
|
||||
const h = Math.floor(s / 3600)
|
||||
@ -426,12 +434,12 @@ let notificationEl: any = null
|
||||
*/
|
||||
const showElNotification = () => {
|
||||
notificationEl = ElNotification.success({
|
||||
title: t("warning"),
|
||||
title: t('warning'),
|
||||
dangerouslyUseHTMLString: true,
|
||||
message: h("div", {}, [t("upgrade.upgradingTips"), h("span", {
|
||||
class: "text-primary cursor-pointer",
|
||||
message: h('div', {}, [t('upgrade.upgradingTips'), h('span', {
|
||||
class: 'text-primary cursor-pointer',
|
||||
onClick: elNotificationClick
|
||||
}, [t("upgrade.clickView")])]),
|
||||
}, [t('upgrade.clickView')])]),
|
||||
duration: 0,
|
||||
showClose: false
|
||||
})
|
||||
@ -442,15 +450,15 @@ const elNotificationClick = () => {
|
||||
getUpgradeTaskFn()
|
||||
step.value = 2
|
||||
numberOfSteps.value = 3
|
||||
active.value = "upgrade"
|
||||
active.value = 'upgrade'
|
||||
notificationEl && notificationEl.close()
|
||||
}
|
||||
|
||||
const frameworkVersion = ref("")
|
||||
const frameworkVersion = ref('')
|
||||
getVersions().then((res) => {
|
||||
frameworkVersion.value = res.data.version.version
|
||||
})
|
||||
const newFrameworkVersion = ref("")
|
||||
const newFrameworkVersion = ref('')
|
||||
getFrameworkNewVersion().then(({ data }) => {
|
||||
newFrameworkVersion.value = data.last_version
|
||||
})
|
||||
@ -462,7 +470,7 @@ const is_pass = ref(false)
|
||||
const repeat = ref(false)
|
||||
const readyLoading = ref(false)
|
||||
|
||||
const handleUpgrade = async() => {
|
||||
const handleUpgrade = async () => {
|
||||
if (repeat.value) return
|
||||
repeat.value = true
|
||||
readyLoading.value = true
|
||||
@ -472,7 +480,7 @@ const handleUpgrade = async() => {
|
||||
await preUpgradeCheck(appKey).then(async ({ data }) => {
|
||||
upgradeCheck.value = data
|
||||
is_pass.value = data.is_pass
|
||||
active.value = "upgrade"
|
||||
active.value = 'upgrade'
|
||||
!upgradeTask.value ? (numberOfSteps.value = 0) : numberOfSteps.value
|
||||
upgradeTipsShowDialog.value = false
|
||||
showDialog.value = true
|
||||
@ -498,18 +506,18 @@ const upgradeAddonFn = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const open = (addonKey: string = "", callback = null) => {
|
||||
const open = (addonKey: string = '', callback = null) => {
|
||||
errorDialog.value = false // 隐藏错误弹窗
|
||||
if (upgradeTask.value) {
|
||||
ElMessage({ message: "已有正在执行中的升级任务", type: "error" })
|
||||
ElMessage({ message: '已有正在执行中的升级任务', type: 'error' })
|
||||
showDialog.value = true
|
||||
step.value = 2
|
||||
numberOfSteps.value = 3
|
||||
active.value = "upgrade"
|
||||
active.value = 'upgrade'
|
||||
if (callback) callback()
|
||||
} else {
|
||||
if (addonKey && frameworkVersion.value != newFrameworkVersion.value) {
|
||||
ElMessage({ message: "存在新版本框架,请先升级框架", type: "error" })
|
||||
ElMessage({ message: '存在新版本框架,请先升级框架', type: 'error' })
|
||||
if (callback) callback()
|
||||
return
|
||||
}
|
||||
@ -532,7 +540,7 @@ const open = (addonKey: string = "", callback = null) => {
|
||||
} else if (upgradeContent.value.content.length == failUpgradeCount) {
|
||||
isAllowUpgrade.value = false
|
||||
}
|
||||
if (Storage.get("upgradeTipsLock")) {
|
||||
if (Storage.get('upgradeTipsLock')) {
|
||||
handleUpgrade()
|
||||
} else {
|
||||
upgradeTipsShowDialog.value = true
|
||||
@ -551,19 +559,19 @@ const open = (addonKey: string = "", callback = null) => {
|
||||
let flashInterval: any = null
|
||||
const terminalFlash = new TerminalFlash()
|
||||
const onExecCmd = (key, command, success, failed, name) => {
|
||||
if (command == "开始升级") {
|
||||
if (command == '开始升级') {
|
||||
success(terminalFlash)
|
||||
const frames = makeIterator(["/", "——", "\\", "|"])
|
||||
const frames = makeIterator(['/', '——', '\\', '|'])
|
||||
flashInterval = setInterval(() => {
|
||||
terminalFlash.flush("> " + frames.next().value)
|
||||
terminalFlash.flush('> ' + frames.next().value)
|
||||
}, 150)
|
||||
}
|
||||
}
|
||||
|
||||
const makeIterator = (array: string[]) => {
|
||||
var nextIndex = 0
|
||||
let nextIndex = 0
|
||||
return {
|
||||
next() {
|
||||
next () {
|
||||
if (nextIndex + 1 == array.length) {
|
||||
nextIndex = 0
|
||||
}
|
||||
@ -573,11 +581,11 @@ const makeIterator = (array: string[]) => {
|
||||
}
|
||||
|
||||
const dialogClose = (done: () => {}) => {
|
||||
if (active.value == "upgrade" && upgradeTask.value && ['upgradeComplete', 'restoreComplete'].includes(upgradeTask.value.step) === false && !isBack.value) {
|
||||
ElMessageBox.confirm(t("upgrade.showDialogCloseTips"), t("warning"), {
|
||||
confirmButtonText: t("confirm"),
|
||||
cancelButtonText: t("cancel"),
|
||||
type: "warning"
|
||||
if (active.value == 'upgrade' && upgradeTask.value && ['upgradeComplete', 'restoreComplete'].includes(upgradeTask.value.step) === false && !isBack.value) {
|
||||
ElMessageBox.confirm(t('upgrade.showDialogCloseTips'), t('warning'), {
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
done()
|
||||
})
|
||||
@ -591,13 +599,12 @@ watch(
|
||||
() => {
|
||||
if (!showDialog.value) {
|
||||
clearUpgradeTaskFn()
|
||||
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const clearUpgradeTaskFn = () => {
|
||||
active.value = "upgrade"
|
||||
active.value = 'upgrade'
|
||||
loading.value = false
|
||||
upgradeTask.value = null
|
||||
isBack.value = false
|
||||
@ -625,16 +632,16 @@ const clearUpgradeTaskFn = () => {
|
||||
const cloudBuildError = (event: string) => {
|
||||
cloudBuildErrorTipsShowDialog.value = false
|
||||
switch (event) {
|
||||
case "local":
|
||||
case 'local':
|
||||
upgradeUserOperate(event).then(() => {
|
||||
getUpgradeTaskFn()
|
||||
})
|
||||
break
|
||||
case "retry":
|
||||
case 'retry':
|
||||
executeUpgradeFn()
|
||||
retrySecondInterval && clearInterval(retrySecondInterval)
|
||||
break
|
||||
case "rollback":
|
||||
case 'rollback':
|
||||
upgradeUserOperate(event).then(() => {
|
||||
getUpgradeTaskFn()
|
||||
})
|
||||
@ -643,13 +650,13 @@ const cloudBuildError = (event: string) => {
|
||||
}
|
||||
|
||||
const timeSplit = (str: string) => {
|
||||
const [date, time] = str.split(" ")
|
||||
const [hours, minutes] = time.split(":")
|
||||
return [date, `${ hours }:${ minutes }`]
|
||||
const [date, time] = str.split(' ')
|
||||
const [hours, minutes] = time.split(':')
|
||||
return [date, `${hours}:${minutes}`]
|
||||
}
|
||||
|
||||
const upgradeTipsConfirm = (isLock: boolean = false) => {
|
||||
isLock && Storage.set({ key: "upgradeTipsLock", data: isLock })
|
||||
isLock && Storage.set({ key: 'upgradeTipsLock', data: isLock })
|
||||
upgradeTipsShowDialog.value = false
|
||||
!isLock && (showDialog.value = true)
|
||||
}
|
||||
@ -810,8 +817,7 @@ defineExpose({
|
||||
left: 125px;
|
||||
border-left-color: #dddddd;
|
||||
border-left-style: dashed;
|
||||
margin: 12px 0;
|
||||
margin-top: 24px;
|
||||
margin: 24px 0 12px;
|
||||
height: calc(100% - 24px - 12px);
|
||||
}
|
||||
|
||||
@ -892,7 +898,7 @@ defineExpose({
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 46px;
|
||||
bottom: 0px;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
overflow: hidden;
|
||||
|
||||
@ -14,6 +14,14 @@
|
||||
"statusBarStyle": "导航栏样式",
|
||||
"statusBarSwitchTips": "此处控制当前页面导航栏是否显示",
|
||||
"bottomNavContent": "底部导航内容",
|
||||
"popWindowAds": "弹窗广告",
|
||||
"popAdsLink": "广告链接",
|
||||
"popAdsImage": "广告图",
|
||||
"popAdsType": "显示类型",
|
||||
"popAdsIsEnabled": "是否显示",
|
||||
"firstPop": "首次弹出",
|
||||
"popWindowCountTips": "建议上传图片大小:290px * 410px",
|
||||
"everyTimePops": "每次弹出",
|
||||
"diyPageTitle": "页面名称",
|
||||
"diyPageTitlePlaceholder": "请输入页面名称",
|
||||
"pageTitleTips": "页面名称用于后台显示",
|
||||
|
||||
@ -31,5 +31,11 @@
|
||||
"contactsTel": "联系电话",
|
||||
"contactsTelPlaceholder": "请输入联系电话",
|
||||
"logoPlaceholder": "建议图片尺寸:210*30像素;图片格式:jpg、png、jpeg。",
|
||||
"iconPlaceholder": "建议图片尺寸:100*100像素;图片格式:jpg、png、jpeg。"
|
||||
"iconPlaceholder": "建议图片尺寸:100*100像素;图片格式:jpg、png、jpeg。",
|
||||
"metaTitle": "Meta 标题",
|
||||
"MetaPlaceholder": "请输入Meta 标题",
|
||||
"metaDescription": "Meta 描述",
|
||||
"metaDescriptionPlaceholder": "请输入Meta描述",
|
||||
"metaKeywords": "Meta 关键字",
|
||||
"metaKeywordsPlaceholder": "请输入Meta关键字"
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<el-card class="box-card !border-none min-h-[300px]" shadow="never" v-loading="loading">
|
||||
<div v-if="!loading">
|
||||
<div class="title text-[16px] font-bold text-[#1D1F3A] mb-[30px]">授权信息</div>
|
||||
<div class="">
|
||||
<div>
|
||||
<div class="flex items-center">
|
||||
<div class="w-[92px] h-[92px] rounded-[10px] flex justify-center items-center mr-[20px]">
|
||||
<img src="@/app/assets/images/tools/authorize.png" class="w-[92px] h-[92px]" />
|
||||
|
||||
@ -83,6 +83,6 @@ const toLink = (item: any) => {
|
||||
}
|
||||
.app-item:hover{
|
||||
transition: 0.5s;
|
||||
box-shadow: 0px 2px 8px 0px rgba(0,0,0,0.1);
|
||||
box-shadow: 0 2px 8px 0 rgba(0,0,0,0.1);
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
<div class="flex flex-wrap plug-list pb-10 plug-large">
|
||||
<div class="cursor-pointer mt-[20px] mr-4 bg-[#f7f7f7]" v-for="(childItem,childIndex) in item.list" :key="childIndex" @click="toLink(childItem)">
|
||||
<div class="w-[264px] flex py-[20px] px-[17px] app-item relative">
|
||||
<el-image class="w-[40px] h-[40px] mr-[10px]" :src="img(childItem.icon)" fit="contain">
|
||||
<el-image class="w-[40px] h-[40px] mr-[10px] rounded-[6px] overflow-hidden" :src="img(childItem.icon)" fit="contain">
|
||||
<template #error>
|
||||
<div class="image-slot">
|
||||
<img class="w-[40px] h-[40px]" src="@/app/assets/images/index/app_default.png" />
|
||||
@ -65,7 +65,13 @@ getMarketingList()
|
||||
|
||||
const toLink = (item: any) => {
|
||||
if (item.url) {
|
||||
router.push(item.url)
|
||||
// 判断如果携带is_target=true就通过新窗口打开
|
||||
if (item.url.indexOf('is_target=true') != -1) {
|
||||
const url = router.resolve(item.url)
|
||||
window.open(url.href)
|
||||
} else {
|
||||
router.push(item.url)
|
||||
}
|
||||
} else {
|
||||
addonIndexRoute[item.key] && router.push({ name: addonIndexRoute[item.key] })
|
||||
}
|
||||
@ -83,6 +89,6 @@ const toLink = (item: any) => {
|
||||
}
|
||||
.app-item:hover{
|
||||
transition: 0.5s;
|
||||
box-shadow: 0px 2px 8px 0px rgba(0,0,0,0.1);
|
||||
box-shadow: 0 2px 8px 0 rgba(0,0,0,0.1);
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup async>
|
||||
import { ref, reactive, computed, watch, toRaw } from 'vue'
|
||||
import { ref, reactive, computed, watch, toRaw, nextTick } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { addRole, editRole, getRoleInfo } from '@/app/api/sys'
|
||||
@ -56,17 +56,18 @@ const menus = ref<Record<string, any>[]>([])
|
||||
getAuthMenus({ is_button: 0 }).then((res) => {
|
||||
menus.value = res.data
|
||||
})
|
||||
|
||||
// 全选
|
||||
const selectAll = ref(false)
|
||||
const checkStrictly = ref(false)
|
||||
const treeRef: Record<string, any> | null = ref(null)
|
||||
watch(selectAll, () => {
|
||||
if (selectAll.value) {
|
||||
treeRef.value.setCheckedNodes(toRaw(menus.value))
|
||||
} else {
|
||||
treeRef.value.setCheckedNodes([])
|
||||
}
|
||||
nextTick(() => {
|
||||
if (selectAll.value) {
|
||||
treeRef.value.setCheckedNodes(toRaw(menus.value))
|
||||
} else {
|
||||
treeRef.value.setCheckedNodes([])
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const handleCheckChange = debounce((e) => {
|
||||
@ -97,6 +98,7 @@ const collapseAll = (data:any) => {
|
||||
if (data[key].children && data[key].children.length > 0) collapseAll(data[key].children)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单数据
|
||||
*/
|
||||
|
||||
@ -2,30 +2,44 @@
|
||||
<el-dialog v-model="showDialog" :title="popTitle" width="500px" :destroy-on-close="true">
|
||||
<el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
|
||||
|
||||
<el-form-item :label="t('accountNumber')" prop="username">
|
||||
<el-input v-model.trim="formData.username" :placeholder="t('accountNumberPlaceholder')" clearable :disabled="formData.uid" class="input-width" maxlength="10" show-word-limit />
|
||||
<!-- <el-form-item :label="t('accountNumber')" v-if="!formData.uid" prop="uid">
|
||||
<el-select :model-value="uid" :placeholder="t('accountNumberPlaceholder')" class="input-width" filterable clearable :allow-create="true" @change="selectUser" :default-first-option="true">
|
||||
<el-option v-for="item in userList" :key="item.uid" :label="item.username" :value="item.uid">
|
||||
<div class="flex items-center">
|
||||
<el-avatar :src="img(item.head_img)" size="small" class="mr-[10px]" v-if="item.head_img" />
|
||||
<img src="@/app/assets/images/member_head.png" alt="" class="mr-[10px] w-[24px]" v-else>
|
||||
{{ item.username }}
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item> -->
|
||||
|
||||
<el-form-item :label="t('accountNumber')" prop="username" >
|
||||
<el-input v-model.trim="formData.username" :placeholder="t('accountNumberPlaceholder')" clearable :disabled="formData.uid" class="input-width" maxlength="20" show-word-limit />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('headImg')">
|
||||
<upload-image v-model="formData.head_img" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('userRealName')" prop="real_name">
|
||||
<el-input v-model.trim="formData.real_name" :placeholder="t('userRealNamePlaceholder')" :readonly="real_name_input" @click="real_name_input = false" @blur="real_name_input = true" clearable class="input-width" maxlength="10" show-word-limit />
|
||||
</el-form-item>
|
||||
<div v-if="!formData.uid">
|
||||
<el-form-item :label="t('password')" prop="password">
|
||||
<el-input v-model.trim="formData.password" :placeholder="t('passwordPlaceholder')" :readonly="password_input" @click="password_input = false" @blur="password_input = true" type="password" :show-password="true" clearable class="input-width" />
|
||||
<div v-if="needAddUserInfo">
|
||||
<el-form-item :label="t('headImg')">
|
||||
<upload-image v-model="formData.head_img" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('confirmPassword')" prop="confirm_password">
|
||||
<el-input v-model.trim="formData.confirm_password" :placeholder="t('confirmPasswordPlaceholder')" :readonly="confirm_password_input" @click="confirm_password_input = false" @blur="confirm_password_input = true" type="password" :show-password="true" clearable class="input-width" />
|
||||
<el-form-item :label="t('userRealName')" prop="real_name">
|
||||
<el-input v-model.trim="formData.real_name" :placeholder="t('userRealNamePlaceholder')" :readonly="real_name_input" @click="real_name_input = false" @blur="real_name_input = true" clearable class="input-width" maxlength="10" show-word-limit />
|
||||
</el-form-item>
|
||||
<div v-if="!formData.uid">
|
||||
<el-form-item :label="t('password')" prop="password">
|
||||
<el-input v-model.trim="formData.password" :placeholder="t('passwordPlaceholder')" :readonly="password_input" @click="password_input = false" @blur="password_input = true" type="password" :show-password="true" clearable class="input-width" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('confirmPassword')" prop="confirm_password">
|
||||
<el-input v-model.trim="formData.confirm_password" :placeholder="t('confirmPasswordPlaceholder')" :readonly="confirm_password_input" @click="confirm_password_input = false" @blur="confirm_password_input = true" type="password" :show-password="true" clearable class="input-width" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-form-item :label="t('userRoleName')" prop="role_ids" v-if="!formData.userrole.is_admin">
|
||||
<el-select v-model="formData.role_ids" :placeholder="t('userRolePlaceholder')" class="input-width" multiple collapse-tags collapse-tags-tooltip>
|
||||
<el-option :label="item.role_name" :value="item.role_id" v-for="(item, index) in roles" :key="index" />
|
||||
<el-option :label="item.role_name" :value="item.role_id" v-for="(item, index) in roles" :key="index" :disabled="item.disabled" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
@ -50,15 +64,35 @@
|
||||
import { ref, reactive, computed, toRaw } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { getUserInfo, addUser, editUser } from '@/app/api/user'
|
||||
import { getAllUserList,getUserInfo, addUser, editUser } from '@/app/api/user'
|
||||
import { allRole } from '@/app/api/sys'
|
||||
import { deepClone } from '@/utils/common'
|
||||
import { img, deepClone } from '@/utils/common'
|
||||
import { AnyObject } from '@/types/global'
|
||||
|
||||
const userList = ref<AnyObject>([])
|
||||
const uid = ref<number | string>('')
|
||||
|
||||
const selectUser = (value: any) => {
|
||||
uid.value = value
|
||||
if (typeof value == 'string') formData.username = value
|
||||
}
|
||||
|
||||
const getUserList = () => {
|
||||
getAllUserList({}).then(({ data }) => {
|
||||
userList.value = data
|
||||
}).catch()
|
||||
}
|
||||
getUserList()
|
||||
const real_name_input = ref(true)
|
||||
const password_input = ref(true)
|
||||
const confirm_password_input = ref(true)
|
||||
const needAddUserInfo = computed(() => {
|
||||
if (formData.uid || !uid.value || typeof uid.value == 'string') {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
const showDialog = ref(false)
|
||||
const loading = ref(false)
|
||||
@ -144,10 +178,10 @@ const confirm = async (formEl: FormInstance | undefined) => {
|
||||
|
||||
const data = deepClone(toRaw(formData))
|
||||
if (!formData.uid && typeof uid.value == 'number') data.uid = uid.value
|
||||
|
||||
save(data).then(res => {
|
||||
loading.value = false
|
||||
showDialog.value = false
|
||||
!formData.uid && getUserList()
|
||||
emit('complete')
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
|
||||
@ -67,7 +67,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getLogList ,logDestroy} from '@/app/api/user'
|
||||
import { getLogList, logDestroy } from '@/app/api/user'
|
||||
import UserLogDetail from '@/app/views/auth/components/user-log-detail.vue'
|
||||
import { FormInstance } from 'element-plus'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
@ -108,7 +108,6 @@ const router = useRouter()
|
||||
const pageName = route.meta.title
|
||||
|
||||
const activeName = ref('/channel/weapp')
|
||||
const active = ref(2)
|
||||
const qrCode = ref('')
|
||||
const weappConfig = ref({})
|
||||
|
||||
@ -121,6 +120,12 @@ const onShowGetWeappConfig = async () => {
|
||||
|
||||
onMounted(async () => {
|
||||
onShowGetWeappConfig()
|
||||
|
||||
document.addEventListener('visibilitychange', () => {
|
||||
if (document.visibilityState === 'visible') {
|
||||
onShowGetWeappConfig()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
|
||||
@ -96,7 +96,6 @@ const router = useRouter()
|
||||
const pageName = route.meta.title
|
||||
|
||||
const activeName = ref('/channel/wechat')
|
||||
const active = ref(2)
|
||||
const qrcode = ref('')
|
||||
const wechatConfig = ref({})
|
||||
const oplatformConfig = ref({})
|
||||
@ -110,6 +109,11 @@ const onShowGetWechatConfig = async () => {
|
||||
|
||||
onMounted(async () => {
|
||||
onShowGetWechatConfig()
|
||||
document.addEventListener('visibilitychange', () => {
|
||||
if (document.visibilityState === 'visible') {
|
||||
onShowGetWechatConfig()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
|
||||
@ -186,17 +186,17 @@ const waterfall = debounce(() => {
|
||||
const position = {}
|
||||
position.top = '0px'
|
||||
if (i % column == 0) {
|
||||
position.left = item.clientWidth * i + "px"
|
||||
position.left = item.clientWidth * i + 'px'
|
||||
} else {
|
||||
position.left = item.clientWidth * i + (i % column * 10) + "px"
|
||||
position.left = item.clientWidth * i + (i % column * 10) + 'px'
|
||||
}
|
||||
positions[i] = position
|
||||
heights[i] = item.clientHeight + 10
|
||||
} else {
|
||||
let minHeight = Math.min(...heights) // 找到第一列的最小高度
|
||||
let minIndex = heights.findIndex(item => item === minHeight) // 找到最小高度的索引
|
||||
let position = {}
|
||||
position.top = minHeight + 10 + "px"
|
||||
const minHeight = Math.min(...heights) // 找到第一列的最小高度
|
||||
const minIndex = heights.findIndex(item => item === minHeight) // 找到最小高度的索引
|
||||
const position = {}
|
||||
position.top = minHeight + 10 + 'px'
|
||||
position.left = positions[minIndex].left
|
||||
positions[i] = position
|
||||
heights[minIndex] += item.clientHeight + 10
|
||||
|
||||
@ -139,7 +139,8 @@ const formRules = reactive<FormRules>({
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (!formData.content.length) callback(new Error(t('contentPlaceholder')))
|
||||
callback()
|
||||
}, trigger: 'blur'
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
@ -46,21 +46,21 @@ const initialData = {
|
||||
value: '',
|
||||
tip: ''
|
||||
}
|
||||
let keyArr = []; // 存储现有颜色的key
|
||||
let type = ref('') // 区分编辑和添加
|
||||
let keyArr = [] // 存储现有颜色的key
|
||||
const type = ref('') // 区分编辑和添加
|
||||
const formData: Record<string, any> = reactive({ ...initialData })
|
||||
|
||||
const open = (option:any) => {
|
||||
keyArr = option.key;
|
||||
type.value = '';
|
||||
keyArr = option.key
|
||||
type.value = ''
|
||||
// 恢复默认值
|
||||
for(let key in formData){
|
||||
for (const key in formData) {
|
||||
formData[key] = ''
|
||||
}
|
||||
if(option.data && Object.keys(option.data).length){
|
||||
type.value = 'edit';
|
||||
Object.keys(formData).forEach((item,index)=>{
|
||||
formData[item] = option.data[item] ? option.data[item] : '';
|
||||
if (option.data && Object.keys(option.data).length) {
|
||||
type.value = 'edit'
|
||||
Object.keys(formData).forEach((item, index) => {
|
||||
formData[item] = option.data[item] ? option.data[item] : ''
|
||||
})
|
||||
}
|
||||
dialogThemeVisible.value = true
|
||||
@ -72,7 +72,7 @@ const formRef = ref<FormInstance>()
|
||||
const formRules = computed(() => {
|
||||
return {
|
||||
title: [
|
||||
{ required: true, message: "请输入颜色名称", trigger: 'blur' }
|
||||
{ required: true, message: '请输入颜色名称', trigger: 'blur' }
|
||||
],
|
||||
value: [
|
||||
{
|
||||
@ -80,15 +80,15 @@ const formRules = computed(() => {
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (!value) {
|
||||
callback('请输入颜色value值')
|
||||
} else{
|
||||
callback();
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
],
|
||||
label: [
|
||||
{ required: true, message: "请输入颜色key值", trigger: 'blur' },
|
||||
{ required: true, message: '请输入颜色key值', trigger: 'blur' },
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
const regex = /^[a-zA-Z0-9-]+$/
|
||||
@ -96,8 +96,8 @@ const formRules = computed(() => {
|
||||
callback('新增颜色key值与已存在颜色key值命名重复,请修改命名')
|
||||
} if (!regex.test(value)) {
|
||||
callback('颜色key值只能输入字母、数字和连字符')
|
||||
} else{
|
||||
callback();
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
@ -113,8 +113,8 @@ const confirmFn = async (formEl: FormInstance | undefined) => {
|
||||
confirmRepeat.value = true
|
||||
if (valid) {
|
||||
confirmRepeat.value = false
|
||||
emit('confirm', cloneDeep(formData));
|
||||
dialogThemeVisible.value = false;
|
||||
emit('confirm', cloneDeep(formData))
|
||||
dialogThemeVisible.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<el-form label-width="80px" class="px-[10px]" @submit.prevent>
|
||||
<el-form-item :label="t('selectStyle')" class="flex">
|
||||
<span class="text-primary flex-1 cursor-pointer" @click="showTitleStyle">{{ diyStore.editComponent.titleStyle.title }}</span>
|
||||
<el-icon>
|
||||
<el-icon @click="showTitleStyle" class="cursor-pointer">
|
||||
<ArrowRight />
|
||||
</el-icon>
|
||||
</el-form-item>
|
||||
@ -57,7 +57,7 @@
|
||||
<el-form-item :label="t('selectStyle')" class="flex">
|
||||
<span class="text-primary flex-1 cursor-pointer"
|
||||
@click="showBlockStyle">{{ diyStore.editComponent.blockStyle.title }}</span>
|
||||
<el-icon>
|
||||
<el-icon @click="showBlockStyle" class="cursor-pointer">
|
||||
<ArrowRight />
|
||||
</el-icon>
|
||||
</el-form-item>
|
||||
@ -271,8 +271,8 @@ diyStore.editComponent.list.forEach((item: any) => {
|
||||
const showTitleDialog = ref(false)
|
||||
|
||||
const showTitleStyle = () => {
|
||||
selectTitleStyle.title = diyStore.editComponent.titleStyle.title;
|
||||
selectTitleStyle.value = diyStore.editComponent.titleStyle.value;
|
||||
selectTitleStyle.title = diyStore.editComponent.titleStyle.title
|
||||
selectTitleStyle.value = diyStore.editComponent.titleStyle.value
|
||||
showTitleDialog.value = true
|
||||
}
|
||||
|
||||
@ -306,43 +306,43 @@ const selectTitleStyle = reactive({
|
||||
})
|
||||
|
||||
const changeTitleStyle = (item: any) => {
|
||||
selectTitleStyle.title = item.title;
|
||||
selectTitleStyle.value = item.value;
|
||||
selectTitleStyle.title = item.title
|
||||
selectTitleStyle.value = item.value
|
||||
}
|
||||
|
||||
const confirmTitleStyle = () => {
|
||||
diyStore.editComponent.titleStyle.title = selectTitleStyle.title;
|
||||
diyStore.editComponent.titleStyle.value = selectTitleStyle.value;
|
||||
initTitleStyle(diyStore.editComponent.titleStyle.value);
|
||||
diyStore.editComponent.titleStyle.title = selectTitleStyle.title
|
||||
diyStore.editComponent.titleStyle.value = selectTitleStyle.value
|
||||
initTitleStyle(diyStore.editComponent.titleStyle.value)
|
||||
showTitleDialog.value = false
|
||||
}
|
||||
|
||||
const initTitleStyle = (style) => {
|
||||
if (diyStore.editComponent.titleStyle.value == 'style-1') {
|
||||
diyStore.editComponent.titleColor = "#F91700";
|
||||
diyStore.editComponent.subTitle.textColor = "#FFFFFF";
|
||||
diyStore.editComponent.subTitle.startColor = "#FB792F";
|
||||
diyStore.editComponent.subTitle.endColor = "#F91700";
|
||||
diyStore.editComponent.titleColor = '#F91700'
|
||||
diyStore.editComponent.subTitle.textColor = '#FFFFFF'
|
||||
diyStore.editComponent.subTitle.startColor = '#FB792F'
|
||||
diyStore.editComponent.subTitle.endColor = '#F91700'
|
||||
} else if (diyStore.editComponent.titleStyle.value == 'style-2') {
|
||||
diyStore.editComponent.titleColor = "#F91700";
|
||||
diyStore.editComponent.subTitle.textColor = "#FFFFFF";
|
||||
diyStore.editComponent.subTitle.startColor = "#FB792F";
|
||||
diyStore.editComponent.subTitle.endColor = "#F91700";
|
||||
diyStore.editComponent.titleColor = '#F91700'
|
||||
diyStore.editComponent.subTitle.textColor = '#FFFFFF'
|
||||
diyStore.editComponent.subTitle.startColor = '#FB792F'
|
||||
diyStore.editComponent.subTitle.endColor = '#F91700'
|
||||
} else if (diyStore.editComponent.titleStyle.value == 'style-3') {
|
||||
diyStore.editComponent.titleColor = "#F91700";
|
||||
diyStore.editComponent.subTitle.textColor = "#FFFFFF";
|
||||
diyStore.editComponent.subTitle.startColor = "#FB792F";
|
||||
diyStore.editComponent.subTitle.endColor = "#F91700";
|
||||
diyStore.editComponent.titleColor = '#F91700'
|
||||
diyStore.editComponent.subTitle.textColor = '#FFFFFF'
|
||||
diyStore.editComponent.subTitle.startColor = '#FB792F'
|
||||
diyStore.editComponent.subTitle.endColor = '#F91700'
|
||||
} else if (diyStore.editComponent.titleStyle.value == 'style-4') {
|
||||
diyStore.editComponent.titleColor = "#FFFFFF";
|
||||
diyStore.editComponent.subTitle.textColor = "#333333";
|
||||
diyStore.editComponent.subTitle.startColor = "#FFFFFF";
|
||||
diyStore.editComponent.subTitle.endColor = "#FFFFFF";
|
||||
diyStore.editComponent.titleColor = '#FFFFFF'
|
||||
diyStore.editComponent.subTitle.textColor = '#333333'
|
||||
diyStore.editComponent.subTitle.startColor = '#FFFFFF'
|
||||
diyStore.editComponent.subTitle.endColor = '#FFFFFF'
|
||||
} else if (diyStore.editComponent.titleStyle.value == 'style-5') {
|
||||
diyStore.editComponent.titleColor = "";
|
||||
diyStore.editComponent.subTitle.textColor = "#999999";
|
||||
diyStore.editComponent.subTitle.startColor = "#FFFFFF";
|
||||
diyStore.editComponent.subTitle.endColor = "#FFFFFF";
|
||||
diyStore.editComponent.titleColor = ''
|
||||
diyStore.editComponent.subTitle.textColor = '#999999'
|
||||
diyStore.editComponent.subTitle.startColor = '#FFFFFF'
|
||||
diyStore.editComponent.subTitle.endColor = '#FFFFFF'
|
||||
}
|
||||
}
|
||||
|
||||
@ -382,178 +382,177 @@ const selectBlockStyle = reactive({
|
||||
})
|
||||
|
||||
const changeBlockStyle = (item: any) => {
|
||||
selectBlockStyle.title = item.title;
|
||||
selectBlockStyle.value = item.value;
|
||||
selectBlockStyle.title = item.title
|
||||
selectBlockStyle.value = item.value
|
||||
}
|
||||
|
||||
const confirmBlockStyle = () => {
|
||||
diyStore.editComponent.blockStyle.title = selectBlockStyle.title;
|
||||
diyStore.editComponent.blockStyle.value = selectBlockStyle.value;
|
||||
initBlockStyle(diyStore.editComponent.blockStyle.value);
|
||||
diyStore.editComponent.blockStyle.title = selectBlockStyle.title
|
||||
diyStore.editComponent.blockStyle.value = selectBlockStyle.value
|
||||
initBlockStyle(diyStore.editComponent.blockStyle.value)
|
||||
showListDialog.value = false
|
||||
}
|
||||
|
||||
const initBlockStyle = (style: any) => {
|
||||
if (style == 'style-1') {
|
||||
diyStore.editComponent.blockStyle.fontWeight = "normal";
|
||||
diyStore.editComponent.blockStyle.btnText = "normal";
|
||||
diyStore.editComponent.blockStyle.fontWeight = 'normal'
|
||||
diyStore.editComponent.blockStyle.btnText = 'normal'
|
||||
|
||||
diyStore.editComponent.list[0].title.textColor = "#303133";
|
||||
diyStore.editComponent.list[0].subTitle.textColor = "#999999";
|
||||
diyStore.editComponent.list[0].subTitle.startColor = "";
|
||||
diyStore.editComponent.list[0].subTitle.endColor = "";
|
||||
diyStore.editComponent.list[0].moreTitle.startColor = "#FEA715";
|
||||
diyStore.editComponent.list[0].moreTitle.endColor = "#FE1E00";
|
||||
diyStore.editComponent.list[0].listFrame.startColor = "#FFFAF5";
|
||||
diyStore.editComponent.list[0].listFrame.endColor = "#FFFFFF";
|
||||
diyStore.editComponent.list[0].title.textColor = '#303133'
|
||||
diyStore.editComponent.list[0].subTitle.textColor = '#999999'
|
||||
diyStore.editComponent.list[0].subTitle.startColor = ''
|
||||
diyStore.editComponent.list[0].subTitle.endColor = ''
|
||||
diyStore.editComponent.list[0].moreTitle.startColor = '#FEA715'
|
||||
diyStore.editComponent.list[0].moreTitle.endColor = '#FE1E00'
|
||||
diyStore.editComponent.list[0].listFrame.startColor = '#FFFAF5'
|
||||
diyStore.editComponent.list[0].listFrame.endColor = '#FFFFFF'
|
||||
|
||||
diyStore.editComponent.list[1].title.textColor = "#303133";
|
||||
diyStore.editComponent.list[1].subTitle.textColor = "#999999";
|
||||
diyStore.editComponent.list[1].subTitle.startColor = "";
|
||||
diyStore.editComponent.list[1].subTitle.endColor = "";
|
||||
diyStore.editComponent.list[1].moreTitle.startColor = "#FFBF50";
|
||||
diyStore.editComponent.list[1].moreTitle.endColor = "#FF9E03";
|
||||
diyStore.editComponent.list[1].listFrame.startColor = "#FFFAF5";
|
||||
diyStore.editComponent.list[1].listFrame.endColor = "#FFFFFF";
|
||||
diyStore.editComponent.list[1].title.textColor = '#303133'
|
||||
diyStore.editComponent.list[1].subTitle.textColor = '#999999'
|
||||
diyStore.editComponent.list[1].subTitle.startColor = ''
|
||||
diyStore.editComponent.list[1].subTitle.endColor = ''
|
||||
diyStore.editComponent.list[1].moreTitle.startColor = '#FFBF50'
|
||||
diyStore.editComponent.list[1].moreTitle.endColor = '#FF9E03'
|
||||
diyStore.editComponent.list[1].listFrame.startColor = '#FFFAF5'
|
||||
diyStore.editComponent.list[1].listFrame.endColor = '#FFFFFF'
|
||||
|
||||
diyStore.editComponent.list[2].title.textColor = "#303133";
|
||||
diyStore.editComponent.list[2].subTitle.textColor = "#999999";
|
||||
diyStore.editComponent.list[2].subTitle.startColor = "";
|
||||
diyStore.editComponent.list[2].subTitle.endColor = "";
|
||||
diyStore.editComponent.list[2].moreTitle.startColor = "#A2E792";
|
||||
diyStore.editComponent.list[2].moreTitle.endColor = "#49CD2D";
|
||||
diyStore.editComponent.list[2].listFrame.startColor = "#FFFAF5";
|
||||
diyStore.editComponent.list[2].listFrame.endColor = "#FFFFFF";
|
||||
|
||||
diyStore.editComponent.list[3].title.textColor = "#303133";
|
||||
diyStore.editComponent.list[3].subTitle.textColor = "#999999";
|
||||
diyStore.editComponent.list[3].subTitle.startColor = "";
|
||||
diyStore.editComponent.list[3].subTitle.endColor = "";
|
||||
diyStore.editComponent.list[3].moreTitle.startColor = "#4AC1FF";
|
||||
diyStore.editComponent.list[3].moreTitle.endColor = "#1D7CFF";
|
||||
diyStore.editComponent.list[3].listFrame.startColor = "#FFFAF5";
|
||||
diyStore.editComponent.list[3].listFrame.endColor = "#FFFFFF";
|
||||
diyStore.editComponent.list[2].title.textColor = '#303133'
|
||||
diyStore.editComponent.list[2].subTitle.textColor = '#999999'
|
||||
diyStore.editComponent.list[2].subTitle.startColor = ''
|
||||
diyStore.editComponent.list[2].subTitle.endColor = ''
|
||||
diyStore.editComponent.list[2].moreTitle.startColor = '#A2E792'
|
||||
diyStore.editComponent.list[2].moreTitle.endColor = '#49CD2D'
|
||||
diyStore.editComponent.list[2].listFrame.startColor = '#FFFAF5'
|
||||
diyStore.editComponent.list[2].listFrame.endColor = '#FFFFFF'
|
||||
|
||||
diyStore.editComponent.list[3].title.textColor = '#303133'
|
||||
diyStore.editComponent.list[3].subTitle.textColor = '#999999'
|
||||
diyStore.editComponent.list[3].subTitle.startColor = ''
|
||||
diyStore.editComponent.list[3].subTitle.endColor = ''
|
||||
diyStore.editComponent.list[3].moreTitle.startColor = '#4AC1FF'
|
||||
diyStore.editComponent.list[3].moreTitle.endColor = '#1D7CFF'
|
||||
diyStore.editComponent.list[3].listFrame.startColor = '#FFFAF5'
|
||||
diyStore.editComponent.list[3].listFrame.endColor = '#FFFFFF'
|
||||
} else if (style == 'style-2') {
|
||||
diyStore.editComponent.blockStyle.fontWeight = "normal";
|
||||
diyStore.editComponent.blockStyle.btnText = "normal";
|
||||
diyStore.editComponent.blockStyle.fontWeight = 'normal'
|
||||
diyStore.editComponent.blockStyle.btnText = 'normal'
|
||||
|
||||
diyStore.editComponent.blockStyle.fontWeight = "bold";
|
||||
diyStore.editComponent.blockStyle.btnText = "italics";
|
||||
diyStore.editComponent.blockStyle.fontWeight = 'bold'
|
||||
diyStore.editComponent.blockStyle.btnText = 'italics'
|
||||
|
||||
diyStore.editComponent.list[0].title.textColor = "#303133";
|
||||
diyStore.editComponent.list[0].subTitle.textColor = "#999999";
|
||||
diyStore.editComponent.list[0].subTitle.startColor = "";
|
||||
diyStore.editComponent.list[0].subTitle.endColor = "";
|
||||
diyStore.editComponent.list[0].moreTitle.startColor = "#FFC051";
|
||||
diyStore.editComponent.list[0].moreTitle.endColor = "#FF9C00";
|
||||
diyStore.editComponent.list[0].listFrame.startColor = "#FFF1DB";
|
||||
diyStore.editComponent.list[0].listFrame.endColor = "#FFFBF4";
|
||||
diyStore.editComponent.list[0].title.textColor = '#303133'
|
||||
diyStore.editComponent.list[0].subTitle.textColor = '#999999'
|
||||
diyStore.editComponent.list[0].subTitle.startColor = ''
|
||||
diyStore.editComponent.list[0].subTitle.endColor = ''
|
||||
diyStore.editComponent.list[0].moreTitle.startColor = '#FFC051'
|
||||
diyStore.editComponent.list[0].moreTitle.endColor = '#FF9C00'
|
||||
diyStore.editComponent.list[0].listFrame.startColor = '#FFF1DB'
|
||||
diyStore.editComponent.list[0].listFrame.endColor = '#FFFBF4'
|
||||
|
||||
diyStore.editComponent.list[1].title.textColor = "#303133";
|
||||
diyStore.editComponent.list[1].subTitle.textColor = "#999999";
|
||||
diyStore.editComponent.list[1].subTitle.startColor = "";
|
||||
diyStore.editComponent.list[1].subTitle.endColor = "";
|
||||
diyStore.editComponent.list[1].moreTitle.startColor = "#A4E894";
|
||||
diyStore.editComponent.list[1].moreTitle.endColor = "#45CC2A";
|
||||
diyStore.editComponent.list[1].listFrame.startColor = "#E6F6E2";
|
||||
diyStore.editComponent.list[1].listFrame.endColor = "#F5FDF3";
|
||||
diyStore.editComponent.list[1].title.textColor = '#303133'
|
||||
diyStore.editComponent.list[1].subTitle.textColor = '#999999'
|
||||
diyStore.editComponent.list[1].subTitle.startColor = ''
|
||||
diyStore.editComponent.list[1].subTitle.endColor = ''
|
||||
diyStore.editComponent.list[1].moreTitle.startColor = '#A4E894'
|
||||
diyStore.editComponent.list[1].moreTitle.endColor = '#45CC2A'
|
||||
diyStore.editComponent.list[1].listFrame.startColor = '#E6F6E2'
|
||||
diyStore.editComponent.list[1].listFrame.endColor = '#F5FDF3'
|
||||
|
||||
diyStore.editComponent.list[2].title.textColor = "#303133";
|
||||
diyStore.editComponent.list[2].subTitle.textColor = "#999999";
|
||||
diyStore.editComponent.list[2].subTitle.startColor = "";
|
||||
diyStore.editComponent.list[2].subTitle.endColor = "";
|
||||
diyStore.editComponent.list[2].moreTitle.startColor = "#4BC2FF";
|
||||
diyStore.editComponent.list[2].moreTitle.endColor = "#1F7DFF";
|
||||
diyStore.editComponent.list[2].listFrame.startColor = "#E2F6FF";
|
||||
diyStore.editComponent.list[2].listFrame.endColor = "#F2FAFF";
|
||||
diyStore.editComponent.list[2].title.textColor = '#303133'
|
||||
diyStore.editComponent.list[2].subTitle.textColor = '#999999'
|
||||
diyStore.editComponent.list[2].subTitle.startColor = ''
|
||||
diyStore.editComponent.list[2].subTitle.endColor = ''
|
||||
diyStore.editComponent.list[2].moreTitle.startColor = '#4BC2FF'
|
||||
diyStore.editComponent.list[2].moreTitle.endColor = '#1F7DFF'
|
||||
diyStore.editComponent.list[2].listFrame.startColor = '#E2F6FF'
|
||||
diyStore.editComponent.list[2].listFrame.endColor = '#F2FAFF'
|
||||
|
||||
diyStore.editComponent.list[3].title.textColor = "#303133";
|
||||
diyStore.editComponent.list[3].subTitle.textColor = "#999999";
|
||||
diyStore.editComponent.list[3].subTitle.startColor = "";
|
||||
diyStore.editComponent.list[3].subTitle.endColor = "";
|
||||
diyStore.editComponent.list[3].moreTitle.startColor = "#FB792F";
|
||||
diyStore.editComponent.list[3].moreTitle.endColor = "#F91700";
|
||||
diyStore.editComponent.list[3].listFrame.startColor = "#FFEAEA";
|
||||
diyStore.editComponent.list[3].listFrame.endColor = "#FFFCFB";
|
||||
diyStore.editComponent.list[3].title.textColor = '#303133'
|
||||
diyStore.editComponent.list[3].subTitle.textColor = '#999999'
|
||||
diyStore.editComponent.list[3].subTitle.startColor = ''
|
||||
diyStore.editComponent.list[3].subTitle.endColor = ''
|
||||
diyStore.editComponent.list[3].moreTitle.startColor = '#FB792F'
|
||||
diyStore.editComponent.list[3].moreTitle.endColor = '#F91700'
|
||||
diyStore.editComponent.list[3].listFrame.startColor = '#FFEAEA'
|
||||
diyStore.editComponent.list[3].listFrame.endColor = '#FFFCFB'
|
||||
} else if (style == 'style-3') {
|
||||
diyStore.editComponent.blockStyle.fontWeight = "normal";
|
||||
diyStore.editComponent.blockStyle.btnText = "normal";
|
||||
diyStore.editComponent.blockStyle.fontWeight = 'normal'
|
||||
diyStore.editComponent.blockStyle.btnText = 'normal'
|
||||
|
||||
diyStore.editComponent.list[0].title.textColor = "#FF1128";
|
||||
diyStore.editComponent.list[0].subTitle.textColor = "";
|
||||
diyStore.editComponent.list[0].subTitle.startColor = "";
|
||||
diyStore.editComponent.list[0].subTitle.endColor = "";
|
||||
diyStore.editComponent.list[0].moreTitle.startColor = "";
|
||||
diyStore.editComponent.list[0].moreTitle.endColor = "";
|
||||
diyStore.editComponent.list[0].listFrame.startColor = "";
|
||||
diyStore.editComponent.list[0].listFrame.endColor = "";
|
||||
diyStore.editComponent.list[0].title.textColor = '#FF1128'
|
||||
diyStore.editComponent.list[0].subTitle.textColor = ''
|
||||
diyStore.editComponent.list[0].subTitle.startColor = ''
|
||||
diyStore.editComponent.list[0].subTitle.endColor = ''
|
||||
diyStore.editComponent.list[0].moreTitle.startColor = ''
|
||||
diyStore.editComponent.list[0].moreTitle.endColor = ''
|
||||
diyStore.editComponent.list[0].listFrame.startColor = ''
|
||||
diyStore.editComponent.list[0].listFrame.endColor = ''
|
||||
|
||||
diyStore.editComponent.list[1].title.textColor = "#303133";
|
||||
diyStore.editComponent.list[1].subTitle.textColor = "";
|
||||
diyStore.editComponent.list[1].subTitle.startColor = "";
|
||||
diyStore.editComponent.list[1].subTitle.endColor = "";
|
||||
diyStore.editComponent.list[1].moreTitle.startColor = "";
|
||||
diyStore.editComponent.list[1].moreTitle.endColor = "";
|
||||
diyStore.editComponent.list[1].listFrame.startColor = "";
|
||||
diyStore.editComponent.list[1].listFrame.endColor = "";
|
||||
diyStore.editComponent.list[1].title.textColor = '#303133'
|
||||
diyStore.editComponent.list[1].subTitle.textColor = ''
|
||||
diyStore.editComponent.list[1].subTitle.startColor = ''
|
||||
diyStore.editComponent.list[1].subTitle.endColor = ''
|
||||
diyStore.editComponent.list[1].moreTitle.startColor = ''
|
||||
diyStore.editComponent.list[1].moreTitle.endColor = ''
|
||||
diyStore.editComponent.list[1].listFrame.startColor = ''
|
||||
diyStore.editComponent.list[1].listFrame.endColor = ''
|
||||
|
||||
diyStore.editComponent.list[2].title.textColor = "#303133";
|
||||
diyStore.editComponent.list[2].subTitle.textColor = "";
|
||||
diyStore.editComponent.list[2].subTitle.startColor = "";
|
||||
diyStore.editComponent.list[2].subTitle.endColor = "";
|
||||
diyStore.editComponent.list[2].moreTitle.startColor = "";
|
||||
diyStore.editComponent.list[2].moreTitle.endColor = "";
|
||||
diyStore.editComponent.list[2].listFrame.startColor = "";
|
||||
diyStore.editComponent.list[2].listFrame.endColor = "";
|
||||
diyStore.editComponent.list[2].title.textColor = '#303133'
|
||||
diyStore.editComponent.list[2].subTitle.textColor = ''
|
||||
diyStore.editComponent.list[2].subTitle.startColor = ''
|
||||
diyStore.editComponent.list[2].subTitle.endColor = ''
|
||||
diyStore.editComponent.list[2].moreTitle.startColor = ''
|
||||
diyStore.editComponent.list[2].moreTitle.endColor = ''
|
||||
diyStore.editComponent.list[2].listFrame.startColor = ''
|
||||
diyStore.editComponent.list[2].listFrame.endColor = ''
|
||||
|
||||
diyStore.editComponent.list[3].title.textColor = "#303133";
|
||||
diyStore.editComponent.list[3].subTitle.textColor = "";
|
||||
diyStore.editComponent.list[3].subTitle.startColor = "";
|
||||
diyStore.editComponent.list[3].subTitle.endColor = "";
|
||||
diyStore.editComponent.list[3].moreTitle.startColor = "";
|
||||
diyStore.editComponent.list[3].moreTitle.endColor = "";
|
||||
diyStore.editComponent.list[3].listFrame.startColor = "";
|
||||
diyStore.editComponent.list[3].listFrame.endColor = "";
|
||||
diyStore.editComponent.list[3].title.textColor = '#303133'
|
||||
diyStore.editComponent.list[3].subTitle.textColor = ''
|
||||
diyStore.editComponent.list[3].subTitle.startColor = ''
|
||||
diyStore.editComponent.list[3].subTitle.endColor = ''
|
||||
diyStore.editComponent.list[3].moreTitle.startColor = ''
|
||||
diyStore.editComponent.list[3].moreTitle.endColor = ''
|
||||
diyStore.editComponent.list[3].listFrame.startColor = ''
|
||||
diyStore.editComponent.list[3].listFrame.endColor = ''
|
||||
} else if (style == 'style-4') {
|
||||
diyStore.editComponent.blockStyle.fontWeight = "bold";
|
||||
diyStore.editComponent.blockStyle.btnText = "normal";
|
||||
diyStore.editComponent.blockStyle.fontWeight = 'bold'
|
||||
diyStore.editComponent.blockStyle.btnText = 'normal'
|
||||
|
||||
diyStore.editComponent.list[0].title.textColor = "#303133";
|
||||
diyStore.editComponent.list[0].subTitle.textColor = "#ED6E00";
|
||||
diyStore.editComponent.list[0].subTitle.startColor = "#FFE4D9";
|
||||
diyStore.editComponent.list[0].subTitle.endColor = "#FFE4D9";
|
||||
diyStore.editComponent.list[0].moreTitle.startColor = "";
|
||||
diyStore.editComponent.list[0].moreTitle.endColor = "";
|
||||
diyStore.editComponent.list[0].listFrame.startColor = "#FFAD4D";
|
||||
diyStore.editComponent.list[0].listFrame.endColor = "#F93D02";
|
||||
diyStore.editComponent.list[0].title.textColor = '#303133'
|
||||
diyStore.editComponent.list[0].subTitle.textColor = '#ED6E00'
|
||||
diyStore.editComponent.list[0].subTitle.startColor = '#FFE4D9'
|
||||
diyStore.editComponent.list[0].subTitle.endColor = '#FFE4D9'
|
||||
diyStore.editComponent.list[0].moreTitle.startColor = ''
|
||||
diyStore.editComponent.list[0].moreTitle.endColor = ''
|
||||
diyStore.editComponent.list[0].listFrame.startColor = '#FFAD4D'
|
||||
diyStore.editComponent.list[0].listFrame.endColor = '#F93D02'
|
||||
|
||||
diyStore.editComponent.list[1].title.textColor = "#303133";
|
||||
diyStore.editComponent.list[1].subTitle.textColor = "#2E59E9";
|
||||
diyStore.editComponent.list[1].subTitle.startColor = "#CAD7F8";
|
||||
diyStore.editComponent.list[1].subTitle.endColor = "#CAD7F8";
|
||||
diyStore.editComponent.list[1].moreTitle.startColor = "";
|
||||
diyStore.editComponent.list[1].moreTitle.endColor = "";
|
||||
diyStore.editComponent.list[1].listFrame.startColor = "#7CA7F4";
|
||||
diyStore.editComponent.list[1].listFrame.endColor = "#2B56E9";
|
||||
diyStore.editComponent.list[1].title.textColor = '#303133'
|
||||
diyStore.editComponent.list[1].subTitle.textColor = '#2E59E9'
|
||||
diyStore.editComponent.list[1].subTitle.startColor = '#CAD7F8'
|
||||
diyStore.editComponent.list[1].subTitle.endColor = '#CAD7F8'
|
||||
diyStore.editComponent.list[1].moreTitle.startColor = ''
|
||||
diyStore.editComponent.list[1].moreTitle.endColor = ''
|
||||
diyStore.editComponent.list[1].listFrame.startColor = '#7CA7F4'
|
||||
diyStore.editComponent.list[1].listFrame.endColor = '#2B56E9'
|
||||
|
||||
diyStore.editComponent.list[2].title.textColor = "#303133";
|
||||
diyStore.editComponent.list[2].subTitle.textColor = "#F62F55";
|
||||
diyStore.editComponent.list[2].subTitle.startColor = "#FCD6D9";
|
||||
diyStore.editComponent.list[2].subTitle.endColor = "#FCD6D9";
|
||||
diyStore.editComponent.list[2].moreTitle.startColor = "";
|
||||
diyStore.editComponent.list[2].moreTitle.endColor = "";
|
||||
diyStore.editComponent.list[2].listFrame.startColor = "#FF7F48";
|
||||
diyStore.editComponent.list[2].listFrame.endColor = "#EE335B";
|
||||
diyStore.editComponent.list[2].title.textColor = '#303133'
|
||||
diyStore.editComponent.list[2].subTitle.textColor = '#F62F55'
|
||||
diyStore.editComponent.list[2].subTitle.startColor = '#FCD6D9'
|
||||
diyStore.editComponent.list[2].subTitle.endColor = '#FCD6D9'
|
||||
diyStore.editComponent.list[2].moreTitle.startColor = ''
|
||||
diyStore.editComponent.list[2].moreTitle.endColor = ''
|
||||
diyStore.editComponent.list[2].listFrame.startColor = '#FF7F48'
|
||||
diyStore.editComponent.list[2].listFrame.endColor = '#EE335B'
|
||||
|
||||
diyStore.editComponent.list[3].title.textColor = "#303133";
|
||||
diyStore.editComponent.list[3].subTitle.textColor = "#139B3C";
|
||||
diyStore.editComponent.list[3].subTitle.startColor = "#D3F1DA";
|
||||
diyStore.editComponent.list[3].subTitle.endColor = "#D3F1DA";
|
||||
diyStore.editComponent.list[3].moreTitle.startColor = "";
|
||||
diyStore.editComponent.list[3].moreTitle.endColor = "";
|
||||
diyStore.editComponent.list[3].listFrame.startColor = "#90D48C";
|
||||
diyStore.editComponent.list[3].listFrame.endColor = "#299F4F";
|
||||
diyStore.editComponent.list[3].title.textColor = '#303133'
|
||||
diyStore.editComponent.list[3].subTitle.textColor = '#139B3C'
|
||||
diyStore.editComponent.list[3].subTitle.startColor = '#D3F1DA'
|
||||
diyStore.editComponent.list[3].subTitle.endColor = '#D3F1DA'
|
||||
diyStore.editComponent.list[3].moreTitle.startColor = ''
|
||||
diyStore.editComponent.list[3].moreTitle.endColor = ''
|
||||
diyStore.editComponent.list[3].listFrame.startColor = '#90D48C'
|
||||
diyStore.editComponent.list[3].listFrame.endColor = '#299F4F'
|
||||
}
|
||||
}
|
||||
|
||||
@ -562,17 +561,17 @@ const addItem = () => {
|
||||
id: diyStore.generateRandom(),
|
||||
title: {
|
||||
title: '标题',
|
||||
textColor: "#000000"
|
||||
textColor: '#000000'
|
||||
},
|
||||
subTitle: {
|
||||
text: '副标题',
|
||||
textColor: "#999999",
|
||||
textColor: '#999999',
|
||||
startColor: '',
|
||||
endColor: ''
|
||||
},
|
||||
listFrame: {
|
||||
startColor: "#4AC1FF",
|
||||
endColor: "#1D7CFF"
|
||||
startColor: '#4AC1FF',
|
||||
endColor: '#1D7CFF'
|
||||
},
|
||||
moreTitle: {
|
||||
text: '去看看',
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
<el-form label-width="100px" class="px-[10px]" @submit.prevent>
|
||||
<el-form-item :label="t('selectStyle')" class="flex">
|
||||
<span class="text-primary flex-1 cursor-pointer" @click="showSearchStyle">{{ diyStore.editComponent.search.styleName }}</span>
|
||||
<el-icon>
|
||||
<el-icon @click="showSearchStyle" class="cursor-pointer">
|
||||
<ArrowRight />
|
||||
</el-icon>
|
||||
</el-form-item>
|
||||
@ -348,7 +348,7 @@ diyStore.editComponent.verify = (index: number) => {
|
||||
res.message = t('carouselSearchHotWordTextPlaceholder')
|
||||
return res
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
diyStore.value[index].tab.list.forEach((item: any) => {
|
||||
if (item.text == '') {
|
||||
@ -361,7 +361,7 @@ diyStore.editComponent.verify = (index: number) => {
|
||||
// res.message = t('selectDiyPagePlaceholder')
|
||||
// return res
|
||||
// }
|
||||
});
|
||||
})
|
||||
|
||||
if (diyStore.value[index].swiper.control) {
|
||||
diyStore.value[index].swiper.list.forEach((item: any) => {
|
||||
@ -370,13 +370,13 @@ diyStore.editComponent.verify = (index: number) => {
|
||||
res.message = t('imageUrlTip')
|
||||
return res
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
/************** 搜索框样式选择-start ********************/
|
||||
/** ************ 搜索框样式选择-start ********************/
|
||||
const selectSearchStyle = reactive({
|
||||
title: diyStore.editComponent.search.styleName,
|
||||
value: diyStore.editComponent.search.style
|
||||
@ -386,18 +386,18 @@ const showSearchDialog = ref(false)
|
||||
|
||||
const showSearchStyle = () => {
|
||||
showSearchDialog.value = true
|
||||
selectSearchStyle.title = diyStore.editComponent.search.styleName;
|
||||
selectSearchStyle.value = diyStore.editComponent.search.style;
|
||||
selectSearchStyle.title = diyStore.editComponent.search.styleName
|
||||
selectSearchStyle.value = diyStore.editComponent.search.style
|
||||
}
|
||||
|
||||
const changeSearchStyle = (item: any) => {
|
||||
selectSearchStyle.title = item.title;
|
||||
selectSearchStyle.value = item.value;
|
||||
selectSearchStyle.title = item.title
|
||||
selectSearchStyle.value = item.value
|
||||
}
|
||||
|
||||
const confirmSearchStyle = () => {
|
||||
diyStore.editComponent.search.styleName = selectSearchStyle.title;
|
||||
diyStore.editComponent.search.style = selectSearchStyle.value;
|
||||
diyStore.editComponent.search.styleName = selectSearchStyle.title
|
||||
diyStore.editComponent.search.style = selectSearchStyle.value
|
||||
showSearchDialog.value = false
|
||||
}
|
||||
|
||||
@ -414,7 +414,7 @@ const searchStyleList = reactive([
|
||||
}
|
||||
])
|
||||
|
||||
/************** 搜索框样式选择-end ********************/
|
||||
/** ************ 搜索框样式选择-end ********************/
|
||||
|
||||
diyStore.editComponent.search.hotWord.list.forEach((item: any) => {
|
||||
if (!item.id) item.id = diyStore.generateRandom()
|
||||
@ -439,13 +439,13 @@ onMounted(() => {
|
||||
const addHotWordItem = () => {
|
||||
diyStore.editComponent.search.hotWord.list.push({
|
||||
id: diyStore.generateRandom(),
|
||||
text: '关键词',
|
||||
text: '关键词'
|
||||
})
|
||||
}
|
||||
|
||||
const tabClear = (index: any) => {
|
||||
diyStore.editComponent.tab.list[index].diy_id = 0;
|
||||
diyStore.editComponent.tab.list[index].diy_title = '';
|
||||
diyStore.editComponent.tab.list[index].diy_id = 0
|
||||
diyStore.editComponent.tab.list[index].diy_title = ''
|
||||
}
|
||||
|
||||
const addTabItem = () => {
|
||||
@ -539,24 +539,24 @@ const loadDiyPageList = (page: number = 1) => {
|
||||
...diyPageTable.searchParam
|
||||
}).then(res => {
|
||||
diyPageTable.loading = false
|
||||
let data = res.data.data;
|
||||
let newData: any = [];
|
||||
let isExistCount = 0;
|
||||
const data = res.data.data
|
||||
let newData: any = []
|
||||
let isExistCount = 0
|
||||
|
||||
// 排除当前编辑的微页面以及存在 置顶组件的数据
|
||||
if (diyStore.id) {
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
if (data[i].id == diyStore.id) {
|
||||
isExistCount++;
|
||||
isExistCount++
|
||||
} else {
|
||||
newData.push(data[i]);
|
||||
newData.push(data[i])
|
||||
}
|
||||
}
|
||||
} else {
|
||||
newData = cloneDeep(data); // 添加
|
||||
newData = cloneDeep(data) // 添加
|
||||
}
|
||||
if (isExistCount) {
|
||||
res.data.total = res.data.total - isExistCount;
|
||||
res.data.total = res.data.total - isExistCount
|
||||
}
|
||||
diyPageTable.data = newData
|
||||
diyPageTable.total = res.data.total
|
||||
@ -567,20 +567,20 @@ const loadDiyPageList = (page: number = 1) => {
|
||||
|
||||
// 选择微页面
|
||||
let currDiyPage: any = {}
|
||||
let currTabIndexForDiyPage = 0;
|
||||
let currTabIndexForDiyPage = 0
|
||||
const handleCurrentDiyPageChange = (val: string | any[]) => {
|
||||
currDiyPage = val
|
||||
}
|
||||
|
||||
const saveDiyPageId = () => {
|
||||
diyStore.editComponent.tab.list[currTabIndexForDiyPage].diy_id = currDiyPage.id;
|
||||
diyStore.editComponent.tab.list[currTabIndexForDiyPage].diy_title = currDiyPage.title;
|
||||
diyStore.editComponent.tab.list[currTabIndexForDiyPage].diy_id = currDiyPage.id
|
||||
diyStore.editComponent.tab.list[currTabIndexForDiyPage].diy_title = currDiyPage.title
|
||||
diyPageShowDialog.value = false
|
||||
}
|
||||
|
||||
const diyPageShowDialogOpen = (index: any) => {
|
||||
diyPageShowDialog.value = true
|
||||
currTabIndexForDiyPage = index;
|
||||
currTabIndexForDiyPage = index
|
||||
if (currDiyPage) {
|
||||
setTimeout(() => {
|
||||
diyPageTableRef.value!.setCurrentRow(currDiyPage)
|
||||
@ -620,7 +620,7 @@ const handleHeight = (isCalcHeight: boolean = false) => {
|
||||
diyStore.editComponent.swiper.list.forEach((item: any, index: number) => {
|
||||
const image = new Image()
|
||||
image.src = img(item.imageUrl)
|
||||
image.onload = async() => {
|
||||
image.onload = async () => {
|
||||
item.imgWidth = image.width
|
||||
item.imgHeight = image.height
|
||||
// 计算第一张图片高度
|
||||
|
||||
@ -122,7 +122,7 @@ templateList.value.forEach((item) => {
|
||||
})
|
||||
|
||||
const changeTemplateList = (data: any) => {
|
||||
selectTemplate.value = data;
|
||||
selectTemplate.value = data
|
||||
diyStore.editComponent.bottomPosition = data.className
|
||||
}
|
||||
|
||||
@ -134,7 +134,7 @@ const addImageAd = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const imageBoxRef = ref();
|
||||
const imageBoxRef = ref()
|
||||
diyStore.editComponent.list.forEach((item: any) => {
|
||||
if (!item.id) item.id = diyStore.generateRandom()
|
||||
})
|
||||
|
||||
@ -189,7 +189,7 @@ watch(
|
||||
diyStore.editComponent.list.forEach((item: any) => {
|
||||
const image = new Image()
|
||||
image.src = img(item.imageUrl)
|
||||
image.onload = async() => {
|
||||
image.onload = async () => {
|
||||
item.imgWidth = image.width
|
||||
item.imgHeight = image.height
|
||||
}
|
||||
@ -239,9 +239,9 @@ onMounted(() => {
|
||||
|
||||
const changePageCount = (value: any) => {
|
||||
if (value == '1') {
|
||||
diyStore.editComponent.showStyle = 'singleSlide';
|
||||
diyStore.editComponent.showStyle = 'singleSlide'
|
||||
} else if (value == '2') {
|
||||
diyStore.editComponent.showStyle = 'fixed';
|
||||
diyStore.editComponent.showStyle = 'fixed'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<el-form-item :label="t('selectStyle')" class="flex">
|
||||
<span class="text-primary flex-1 cursor-pointer"
|
||||
@click="showStyle">{{ diyStore.editComponent.styleName }}</span>
|
||||
<el-icon>
|
||||
<el-icon @click="showStyle" class="cursor-pointer">
|
||||
<ArrowRight />
|
||||
</el-icon>
|
||||
</el-form-item>
|
||||
@ -65,8 +65,8 @@ const showDialog = ref(false)
|
||||
|
||||
const showStyle = () => {
|
||||
showDialog.value = true
|
||||
selectStyle.title = diyStore.editComponent.styleName;
|
||||
selectStyle.value = diyStore.editComponent.style;
|
||||
selectStyle.title = diyStore.editComponent.styleName
|
||||
selectStyle.value = diyStore.editComponent.style
|
||||
}
|
||||
|
||||
const styleList = reactive([
|
||||
@ -98,36 +98,34 @@ const styleList = reactive([
|
||||
])
|
||||
|
||||
const changeStyle = (item: any) => {
|
||||
selectStyle.title = item.title;
|
||||
selectStyle.value = item.value;
|
||||
selectStyle.title = item.title
|
||||
selectStyle.value = item.value
|
||||
}
|
||||
|
||||
const confirmStyle = () => {
|
||||
diyStore.editComponent.styleName = selectStyle.title;
|
||||
diyStore.editComponent.style = selectStyle.value;
|
||||
initStyle(diyStore.editComponent.style);
|
||||
diyStore.editComponent.styleName = selectStyle.title
|
||||
diyStore.editComponent.style = selectStyle.value
|
||||
initStyle(diyStore.editComponent.style)
|
||||
showDialog.value = false
|
||||
}
|
||||
|
||||
|
||||
const initStyle = (style: any) => {
|
||||
if (style == 'style-1') {
|
||||
diyStore.editComponent.bottomRounded = 0;
|
||||
diyStore.editComponent.topRounded = 12;
|
||||
diyStore.editComponent.bottomRounded = 0
|
||||
diyStore.editComponent.topRounded = 12
|
||||
} else if (style == 'style-2') {
|
||||
diyStore.editComponent.bottomRounded = 0;
|
||||
diyStore.editComponent.topRounded = 12;
|
||||
diyStore.editComponent.bottomRounded = 0
|
||||
diyStore.editComponent.topRounded = 12
|
||||
} else if (style == 'style-3') {
|
||||
diyStore.editComponent.bottomRounded = 12;
|
||||
diyStore.editComponent.topRounded = 12;
|
||||
diyStore.editComponent.bottomRounded = 12
|
||||
diyStore.editComponent.topRounded = 12
|
||||
} else if (style == 'style-4') {
|
||||
diyStore.editComponent.bottomRounded = 12;
|
||||
diyStore.editComponent.topRounded = 12;
|
||||
diyStore.editComponent.bottomRounded = 12
|
||||
diyStore.editComponent.topRounded = 12
|
||||
} else if (style == 'style-5') {
|
||||
diyStore.editComponent.bottomRounded = 12;
|
||||
diyStore.editComponent.topRounded = 12;
|
||||
diyStore.editComponent.bottomRounded = 12
|
||||
diyStore.editComponent.topRounded = 12
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
defineExpose({})
|
||||
|
||||
@ -139,17 +139,17 @@ diyStore.editComponent.list.forEach((item: any) => {
|
||||
})
|
||||
|
||||
const changeStyle = (value: any) => {
|
||||
diyStore.editComponent.systemUrl = value;
|
||||
diyStore.editComponent.imgType = 'system';
|
||||
diyStore.editComponent.systemUrl = value
|
||||
diyStore.editComponent.imgType = 'system'
|
||||
}
|
||||
|
||||
watch(
|
||||
() => diyStore.editComponent.imageUrl,
|
||||
(newValue, oldValue) => {
|
||||
if (newValue) {
|
||||
diyStore.editComponent.imgType = 'diy';
|
||||
diyStore.editComponent.imgType = 'diy'
|
||||
} else {
|
||||
changeStyle('style_1');
|
||||
changeStyle('style_1')
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -158,7 +158,7 @@ const addNotice = () => {
|
||||
diyStore.editComponent.list.push({
|
||||
id: diyStore.generateRandom(),
|
||||
text: '公告',
|
||||
link: { name: '' },
|
||||
link: { name: '' }
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
<!-- 表单布局 页面设置 -->
|
||||
<slot name="content"></slot>
|
||||
|
||||
<div class="edit-attr-item-wrap">
|
||||
<div class="edit-attr-item-wrap" v-if="diyStore.global.topStatusBar.control">
|
||||
<h3 class="mb-[10px]">{{ t('statusBarContent') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]" @submit.prevent>
|
||||
<el-form-item :label="t('topStatusBarNav')" class="display-block">
|
||||
@ -56,11 +56,11 @@
|
||||
</template>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="edit-attr-item-wrap">
|
||||
<div class="edit-attr-item-wrap" v-if="diyStore.global.bottomTabBar.control">
|
||||
<h3 class="mb-[10px]">{{ t('bottomNavContent') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('tabbar')" class="display-block">
|
||||
<el-switch v-model="diyStore.global.bottomTabBarSwitch" />
|
||||
<el-switch v-model="diyStore.global.bottomTabBar.isShow" />
|
||||
<div class="text-sm text-gray-400">{{ t('tabbarSwitchTips') }}</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
@ -145,7 +145,7 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="edit-attr-item-wrap">
|
||||
<div class="edit-attr-item-wrap" v-if="diyStore.global.topStatusBar.control">
|
||||
<h3 class="mb-[10px]">{{ t('statusBarStyle') }}</h3>
|
||||
<el-form label-width="115px" class="px-[10px]">
|
||||
<el-form-item :label="t('topStatusBarBgColor')" class="display-block">
|
||||
@ -187,7 +187,7 @@ watch(
|
||||
// 设置图片宽高
|
||||
const image = new Image()
|
||||
image.src = img(diyStore.global.bgUrl)
|
||||
image.onload = async() => {
|
||||
image.onload = async () => {
|
||||
diyStore.global.imgWidth = image.width
|
||||
diyStore.global.imgHeight = image.height
|
||||
}
|
||||
@ -201,7 +201,7 @@ watch(
|
||||
// 改变页面的左右边距时,更新所有组件的数值
|
||||
const inputBoth = (value: any) => {
|
||||
diyStore.value.forEach((item, index) => {
|
||||
item.margin.both = value;
|
||||
item.margin.both = value
|
||||
})
|
||||
}
|
||||
|
||||
@ -217,7 +217,7 @@ const showStyle = () => {
|
||||
showDialog.value = true
|
||||
}
|
||||
|
||||
const selectStyle = ref("style-1")
|
||||
const selectStyle = ref('style-1')
|
||||
const changeStyle = () => {
|
||||
switch (selectStyle.value) {
|
||||
case 'style-1':
|
||||
@ -240,7 +240,7 @@ const changeStyle = () => {
|
||||
const selectImg = (url: any) => {
|
||||
const image = new Image()
|
||||
image.src = img(url)
|
||||
image.onload = async() => {
|
||||
image.onload = async () => {
|
||||
diyStore.global.popWindow.imgWidth = image.width
|
||||
diyStore.global.popWindow.imgHeight = image.height
|
||||
}
|
||||
|
||||
@ -74,7 +74,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import useDiyStore from '@/stores/modules/diy'
|
||||
import { img } from '@/utils/common'
|
||||
@ -330,6 +330,10 @@ const handleHeight = (isCalcHeight: boolean = false) => {
|
||||
})
|
||||
}
|
||||
|
||||
watch(() => diyStore.editComponent.list, () => {
|
||||
handleHeight(true)
|
||||
}, { deep: true })
|
||||
|
||||
defineExpose({})
|
||||
</script>
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<el-form-item :label="t('selectStyle')" class="flex">
|
||||
<span class="text-primary flex-1 cursor-pointer"
|
||||
@click="showStyle">{{ diyStore.editComponent.styleName }}</span>
|
||||
<el-icon>
|
||||
<el-icon @click="showStyle" class="cursor-pointer">
|
||||
<ArrowRight />
|
||||
</el-icon>
|
||||
</el-form-item>
|
||||
|
||||
@ -406,6 +406,17 @@ initPage({
|
||||
template.value = data.template;
|
||||
diyStore.isDefault = data.is_default
|
||||
diyStore.pageMode = data.mode
|
||||
if (data.global) {
|
||||
for (const key in data.global) {
|
||||
if(data.global[key]) {
|
||||
for (const childKey in data.global[key]) {
|
||||
diyStore.global[key][childKey] = data.global[key][childKey]
|
||||
}
|
||||
}else{
|
||||
diyStore.global[key] = data.global[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
if (data.value) {
|
||||
const sources = JSON.parse(data.value)
|
||||
diyStore.global = sources.global
|
||||
@ -472,7 +483,7 @@ initPage({
|
||||
}
|
||||
}
|
||||
|
||||
if(repeat) {
|
||||
if (repeat) {
|
||||
setDomain()
|
||||
}
|
||||
|
||||
|
||||
@ -127,10 +127,10 @@
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, computed } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getApps,getDiyPageList, deleteDiyPage, getDiyTemplate, editDiyPageShare, setUseDiyPage,copyDiy } from '@/app/api/diy'
|
||||
import { getApps, getDiyPageList, deleteDiyPage, getDiyTemplate, editDiyPageShare, setUseDiyPage, copyDiy } from '@/app/api/diy'
|
||||
import { ElMessageBox, FormInstance } from 'element-plus'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { setTablePageStorage,getTablePageStorage } from "@/utils/common";
|
||||
import { setTablePageStorage, getTablePageStorage } from '@/utils/common'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
@ -177,10 +177,10 @@ const addEvent = async (formEl: FormInstance | undefined) => {
|
||||
}
|
||||
|
||||
// 获取自定义页面类型
|
||||
const loadDiyTemplate = (addon = '')=> {
|
||||
getDiyTemplate({mode: '', addon}).then(res => {
|
||||
for (let key in pageType) {
|
||||
delete pageType[key];
|
||||
const loadDiyTemplate = (addon = '') => {
|
||||
getDiyTemplate({ mode: '', addon }).then(res => {
|
||||
for (const key in pageType) {
|
||||
delete pageType[key]
|
||||
}
|
||||
|
||||
for (const key in res.data) {
|
||||
@ -189,21 +189,21 @@ const loadDiyTemplate = (addon = '')=> {
|
||||
})
|
||||
}
|
||||
|
||||
loadDiyTemplate();
|
||||
loadDiyTemplate()
|
||||
|
||||
const apps: any = reactive({}) // 应用插件列表
|
||||
|
||||
getApps({}).then(res=>{
|
||||
if(res.data){
|
||||
getApps({}).then(res => {
|
||||
if (res.data) {
|
||||
for (const key in res.data) {
|
||||
apps[key] = res.data[key];
|
||||
apps[key] = res.data[key]
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
// 根据所属插件,查询页面类型
|
||||
const handleSelectAddonChange = (value: any) => {
|
||||
diyPageTableData.searchParam.type = '';
|
||||
diyPageTableData.searchParam.type = ''
|
||||
loadDiyTemplate(value)
|
||||
}
|
||||
|
||||
@ -236,13 +236,13 @@ const loadDiyPageList = (page: number = 1) => {
|
||||
diyPageTableData.loading = false
|
||||
diyPageTableData.data = res.data.data
|
||||
diyPageTableData.total = res.data.total
|
||||
setTablePageStorage(diyPageTableData.page, diyPageTableData.limit, diyPageTableData.searchParam);
|
||||
setTablePageStorage(diyPageTableData.page, diyPageTableData.limit, diyPageTableData.searchParam)
|
||||
}).catch(() => {
|
||||
diyPageTableData.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
loadDiyPageList(getTablePageStorage(diyPageTableData.searchParam).page);
|
||||
loadDiyPageList(getTablePageStorage(diyPageTableData.searchParam).page)
|
||||
|
||||
// 编辑自定义页面
|
||||
const editEvent = (data: any) => {
|
||||
@ -255,7 +255,7 @@ const editEvent = (data: any) => {
|
||||
|
||||
// 设为使用
|
||||
const setUse = (id: any) => {
|
||||
setUseDiyPage({id}).then(() => {
|
||||
setUseDiyPage({ id }).then(() => {
|
||||
loadDiyPageList()
|
||||
})
|
||||
}
|
||||
@ -273,7 +273,7 @@ const copyEvent = (id: any) => {
|
||||
if (repeat.value) return
|
||||
repeat.value = true
|
||||
|
||||
copyDiy({id: id}).then((res: any) => {
|
||||
copyDiy({ id }).then((res: any) => {
|
||||
if (res.code == 1) {
|
||||
loadDiyPageList()
|
||||
}
|
||||
@ -307,7 +307,7 @@ const toPreview = (data: any) => {
|
||||
query: {
|
||||
page: data.type_page + '?id=' + data.id
|
||||
}
|
||||
});
|
||||
})
|
||||
window.open(url.href)
|
||||
}
|
||||
|
||||
@ -335,10 +335,12 @@ const shareFormRef = ref<FormInstance>()
|
||||
const openShare = async (row: any) => {
|
||||
shareFormId.value = row.id
|
||||
sharePage.value = row.title
|
||||
const share = row.share ? JSON.parse(row.share) : {
|
||||
wechat: { title: '', desc: '', url: '' },
|
||||
weapp: { title: '', url: '' }
|
||||
}
|
||||
const share = row.share
|
||||
? JSON.parse(row.share)
|
||||
: {
|
||||
wechat: { title: '', desc: '', url: '' },
|
||||
weapp: { title: '', url: '' }
|
||||
}
|
||||
if (share) {
|
||||
shareFormData.wechat = share.wechat
|
||||
shareFormData.weapp = share.weapp
|
||||
|
||||
@ -94,7 +94,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, watch, computed } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getDiyRouteAppList,getDiyTemplate, getDiyRouteList, getDiyRouteInfo, editDiyRouteShare } from '@/app/api/diy'
|
||||
import { getDiyRouteAppList, getDiyTemplate, getDiyRouteList, getDiyRouteInfo, editDiyRouteShare } from '@/app/api/diy'
|
||||
import { ElMessage, FormInstance } from 'element-plus'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { useClipboard } from '@vueuse/core'
|
||||
@ -118,7 +118,7 @@ const diyRouteTableData = reactive({
|
||||
data: [],
|
||||
searchParam: {
|
||||
title: '',
|
||||
addon_name:''
|
||||
addon_name: ''
|
||||
}
|
||||
})
|
||||
|
||||
@ -133,13 +133,13 @@ getDomain()
|
||||
|
||||
const apps: any = reactive({}) // 应用插件列表
|
||||
|
||||
getDiyRouteAppList().then(res=> {
|
||||
getDiyRouteAppList().then(res => {
|
||||
if (res.data) {
|
||||
for (const key in res.data) {
|
||||
apps[key] = res.data[key];
|
||||
apps[key] = res.data[key]
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
const getDiyRouteListFn = () => {
|
||||
getDiyRouteList({}).then(res => {
|
||||
@ -148,10 +148,10 @@ const getDiyRouteListFn = () => {
|
||||
loadDiyRouteList(diyRouteTableData.page)
|
||||
}).catch(() => {
|
||||
diyRouteTableData.loading = false
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
getDiyRouteListFn();
|
||||
getDiyRouteListFn()
|
||||
|
||||
/**
|
||||
* 获取自定义路由列表
|
||||
@ -160,21 +160,21 @@ const loadDiyRouteList = (page: number = 1) => {
|
||||
diyRouteTableData.page = page
|
||||
|
||||
const tempData = cloneDeep(diyRouteList.value)
|
||||
const data: any = [];
|
||||
const data: any = []
|
||||
|
||||
// 筛选条件
|
||||
for (let i = 0; i < tempData.length; i++) {
|
||||
let isAdd = true;
|
||||
let isAdd = true
|
||||
if (diyRouteTableData.searchParam.title && tempData[i].title.indexOf(diyRouteTableData.searchParam.title) == -1) {
|
||||
isAdd = false;
|
||||
isAdd = false
|
||||
}
|
||||
|
||||
if (diyRouteTableData.searchParam.addon_name && tempData[i].addon_info && tempData[i].addon_info.key != diyRouteTableData.searchParam.addon_name) {
|
||||
isAdd = false;
|
||||
isAdd = false
|
||||
}
|
||||
|
||||
if (isAdd) {
|
||||
data.push(tempData[i]);
|
||||
data.push(tempData[i])
|
||||
}
|
||||
}
|
||||
|
||||
@ -271,10 +271,12 @@ const openShare = async (row: any) => {
|
||||
|
||||
shareFormId.value = row.id
|
||||
sharePage.value = row.title
|
||||
const share = row.share ? JSON.parse(row.share) : {
|
||||
wechat: { title: '', desc: '', url: '' },
|
||||
weapp: { title: '', url: '' }
|
||||
}
|
||||
const share = row.share
|
||||
? JSON.parse(row.share)
|
||||
: {
|
||||
wechat: { title: '', desc: '', url: '' },
|
||||
weapp: { title: '', url: '' }
|
||||
}
|
||||
if (share) {
|
||||
shareFormData.wechat = share.wechat
|
||||
shareFormData.weapp = share.weapp
|
||||
|
||||
@ -79,7 +79,7 @@ import { ref, onMounted, nextTick } from 'vue'
|
||||
import useDiyStore from '@/stores/modules/diy'
|
||||
import Sortable from 'sortablejs'
|
||||
import { range } from 'lodash-es'
|
||||
import { ElMessage } from "element-plus";
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const diyStore = useDiyStore()
|
||||
diyStore.editComponent.ignore = ['componentBgUrl'] // 忽略公共属性
|
||||
@ -87,21 +87,21 @@ diyStore.editComponent.ignore = ['componentBgUrl'] // 忽略公共属性
|
||||
// 组件验证
|
||||
diyStore.editComponent.verify = (index: number) => {
|
||||
const res = { code: true, message: '' }
|
||||
let pass = true;
|
||||
let pass = true
|
||||
for (let i = 0; i < diyStore.value[index].options.length; i++) {
|
||||
if (!diyStore.value[index].options[i].text) {
|
||||
res.code = false;
|
||||
res.message = t('optionPlaceholder');
|
||||
pass = false;
|
||||
break;
|
||||
res.code = false
|
||||
res.message = t('optionPlaceholder')
|
||||
pass = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (!pass) return res;
|
||||
if (!pass) return res
|
||||
|
||||
let uniqueOptions = uniqueByKey(diyStore.value[index].options, 'text')
|
||||
const uniqueOptions = uniqueByKey(diyStore.value[index].options, 'text')
|
||||
if (uniqueOptions.length != diyStore.value[index].options.length) {
|
||||
res.code = false;
|
||||
res.code = false
|
||||
res.message = t('errorTipsOne')
|
||||
}
|
||||
return res
|
||||
@ -117,11 +117,11 @@ const addOption = () => {
|
||||
diyStore.editComponent.options.push({
|
||||
id: diyStore.generateRandom(),
|
||||
text: '选项' + (diyStore.editComponent.options.length + 1)
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
const removeOption = (index: any) => {
|
||||
diyStore.editComponent.options.splice(index, 1);
|
||||
diyStore.editComponent.options.splice(index, 1)
|
||||
}
|
||||
|
||||
// 批量添加选项
|
||||
@ -131,39 +131,39 @@ const batchAddOptions = () => {
|
||||
return {
|
||||
id: diyStore.generateRandom(),
|
||||
text: option.trim()
|
||||
};
|
||||
}).filter((option: any) => option.text !== '');
|
||||
}
|
||||
}).filter((option: any) => option.text !== '')
|
||||
|
||||
// 去除重复的选项
|
||||
const uniqueNewOptions = uniqueByKey(newOptions, 'text');
|
||||
const uniqueNewOptions = uniqueByKey(newOptions, 'text')
|
||||
|
||||
// 过滤掉已存在的选项
|
||||
const filteredNewOptions = uniqueNewOptions.filter((newOption: any) =>
|
||||
!diyStore.editComponent.options.some((existingOption: any) => existingOption.text === newOption.text)
|
||||
);
|
||||
)
|
||||
|
||||
// 如果有新的选项,添加到选项列表中
|
||||
if (filteredNewOptions.length > 0) {
|
||||
diyStore.editComponent.options.push(...filteredNewOptions);
|
||||
diyStore.editComponent.options.push(...filteredNewOptions)
|
||||
} else {
|
||||
ElMessage({
|
||||
message: t('errorTipsTwo'),
|
||||
type: "error",
|
||||
});
|
||||
type: 'error'
|
||||
})
|
||||
}
|
||||
|
||||
optionsValue.value = '';
|
||||
visible.value = false;
|
||||
optionsValue.value = ''
|
||||
visible.value = false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 数组去重
|
||||
const uniqueByKey = (arr: any, key: any) => {
|
||||
const seen = new Set();
|
||||
const seen = new Set()
|
||||
return arr.filter((item: any) => {
|
||||
const serializedKey = JSON.stringify(item[key]);
|
||||
return seen.has(serializedKey) ? false : seen.add(serializedKey);
|
||||
});
|
||||
const serializedKey = JSON.stringify(item[key])
|
||||
return seen.has(serializedKey) ? false : seen.add(serializedKey)
|
||||
})
|
||||
}
|
||||
|
||||
const formCheckboxRef = ref()
|
||||
|
||||
@ -110,7 +110,7 @@ diyStore.editComponent.verify = (index: number) => {
|
||||
let starTime = diyStore.value[index].field.default.start.date
|
||||
let endTime = diyStore.value[index].field.default.end.date
|
||||
|
||||
let today = new Date()
|
||||
const today = new Date()
|
||||
const hours = String(today.getHours()).padStart(2, '0')
|
||||
const minutes = String(today.getMinutes()).padStart(2, '0')
|
||||
|
||||
@ -162,8 +162,8 @@ const disabledEndDate = (time: Date) => {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
let today = new Date()
|
||||
let endDate = new Date()
|
||||
const today = new Date()
|
||||
const endDate = new Date()
|
||||
endDate.setDate(endDate.getDate() + 7) // 设置日期为7天后的日期
|
||||
|
||||
if (diyStore.editComponent.field.default.start.timestamp) {
|
||||
@ -176,16 +176,16 @@ onMounted(() => {
|
||||
diyStore.editComponent.field.default.end.timestamp = parseInt(endDate.getTime() / 1000)
|
||||
}
|
||||
|
||||
let year = today.getFullYear()
|
||||
let month = String(today.getMonth() + 1).padStart(2, '0')
|
||||
let day = String(today.getDate()).padStart(2, '0')
|
||||
const year = today.getFullYear()
|
||||
const month = String(today.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(today.getDate()).padStart(2, '0')
|
||||
|
||||
const hours = String(today.getHours()).padStart(2, '0')
|
||||
const minutes = String(today.getMinutes()).padStart(2, '0')
|
||||
dateFormat.format1 = `${ year }年${ month }月${ day }日`
|
||||
dateFormat.format2 = `${ year }-${ month }-${ day }`
|
||||
dateFormat.format3 = `${ year }/${ month }/${ day }`
|
||||
dateFormat.format4 = `${ year }-${ month }-${ day } ${ hours }:${ minutes }`
|
||||
dateFormat.format1 = `${year}年${month}月${day}日`
|
||||
dateFormat.format2 = `${year}-${month}-${day}`
|
||||
dateFormat.format3 = `${year}/${month}/${day}`
|
||||
dateFormat.format4 = `${year}-${month}-${day} ${hours}:${minutes}`
|
||||
})
|
||||
|
||||
// 开始日期选择器
|
||||
@ -193,7 +193,7 @@ const startDateChange = (date) => {
|
||||
diyStore.editComponent.field.default.start.date = date
|
||||
diyStore.editComponent.field.default.start.timestamp = timeTurnTimeStamp(date)
|
||||
|
||||
let endDate = new Date(date)
|
||||
const endDate = new Date(date)
|
||||
endDate.setDate(endDate.getDate() + 7)
|
||||
diyStore.editComponent.field.default.end.date = endDate.toISOString().split('T')[0]
|
||||
diyStore.editComponent.field.default.end.timestamp = parseInt(endDate.getTime() / 1000)
|
||||
|
||||
@ -68,30 +68,30 @@ const dateFormat: any = reactive({
|
||||
format2: '',
|
||||
format3: '',
|
||||
format4: ''
|
||||
});
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
// 初始赋值当天日期
|
||||
const today = new Date();
|
||||
const today = new Date()
|
||||
if (!diyStore.editComponent.field.default.date) {
|
||||
diyStore.editComponent.field.default.date = today.toISOString().split('T')[0];
|
||||
diyStore.editComponent.field.default.timestamp = today.getTime() / 1000;
|
||||
diyStore.editComponent.field.default.date = today.toISOString().split('T')[0]
|
||||
diyStore.editComponent.field.default.timestamp = today.getTime() / 1000
|
||||
}
|
||||
let year = today.getFullYear();
|
||||
let month = String(today.getMonth() + 1).padStart(2, '0');
|
||||
let day = String(today.getDate()).padStart(2, '0');
|
||||
const year = today.getFullYear()
|
||||
const month = String(today.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(today.getDate()).padStart(2, '0')
|
||||
|
||||
const hours = String(today.getHours()).padStart(2, '0');
|
||||
const minutes = String(today.getMinutes()).padStart(2, '0');
|
||||
dateFormat.format1 = `${ year }年${ month }月${ day }日`;
|
||||
dateFormat.format2 = `${ year }-${ month }-${ day }`;
|
||||
dateFormat.format3 = `${ year }/${ month }/${ day }`;
|
||||
dateFormat.format4 = `${ year }-${ month }-${ day } ${ hours }:${ minutes }`;
|
||||
});
|
||||
const hours = String(today.getHours()).padStart(2, '0')
|
||||
const minutes = String(today.getMinutes()).padStart(2, '0')
|
||||
dateFormat.format1 = `${year}年${month}月${day}日`
|
||||
dateFormat.format2 = `${year}-${month}-${day}`
|
||||
dateFormat.format3 = `${year}/${month}/${day}`
|
||||
dateFormat.format4 = `${year}-${month}-${day} ${hours}:${minutes}`
|
||||
})
|
||||
|
||||
const dateChange = (date: any) => {
|
||||
diyStore.editComponent.field.default.date = date;
|
||||
diyStore.editComponent.field.default.timestamp = timeTurnTimeStamp(date);
|
||||
diyStore.editComponent.field.default.date = date
|
||||
diyStore.editComponent.field.default.timestamp = timeTurnTimeStamp(date)
|
||||
}
|
||||
|
||||
defineExpose({})
|
||||
|
||||
@ -94,10 +94,10 @@ diyStore.editComponent.verify = (index: number) => {
|
||||
const res = { code: true, message: '' }
|
||||
if (diyStore.value[index].field.default) {
|
||||
if (isNaN(diyStore.value[index].field.default) || !regExp.digit.test(diyStore.value[index].field.default)) {
|
||||
res.code = false;
|
||||
res.message = t('defaultErrorTips');
|
||||
res.code = false
|
||||
res.message = t('defaultErrorTips')
|
||||
} else if (diyStore.value[index].field.default < 0) {
|
||||
res.code = false;
|
||||
res.code = false
|
||||
res.message = t('defaultMustZeroTips')
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ import { ref, onMounted, nextTick } from 'vue'
|
||||
import useDiyStore from '@/stores/modules/diy'
|
||||
import Sortable from 'sortablejs'
|
||||
import { range } from 'lodash-es'
|
||||
import { ElMessage } from "element-plus";
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const diyStore = useDiyStore()
|
||||
diyStore.editComponent.ignore = ['componentBgUrl'] // 忽略公共属性
|
||||
@ -107,22 +107,22 @@ diyStore.editComponent.ignore = ['componentBgUrl'] // 忽略公共属性
|
||||
// 组件验证
|
||||
diyStore.editComponent.verify = (index: number) => {
|
||||
const res = { code: true, message: '' }
|
||||
let pass = true;
|
||||
let pass = true
|
||||
for (let i = 0; i < diyStore.value[index].options.length; i++) {
|
||||
if (!diyStore.value[index].options[i].text) {
|
||||
res.code = false;
|
||||
res.message = t('optionPlaceholder');
|
||||
pass = false;
|
||||
break;
|
||||
res.code = false
|
||||
res.message = t('optionPlaceholder')
|
||||
pass = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (!pass) return res;
|
||||
if (!pass) return res
|
||||
|
||||
let uniqueOptions = uniqueByKey(diyStore.value[index].options, 'text')
|
||||
const uniqueOptions = uniqueByKey(diyStore.value[index].options, 'text')
|
||||
|
||||
if (uniqueOptions.length != diyStore.value[index].options.length) {
|
||||
res.code = false;
|
||||
res.code = false
|
||||
res.message = t('errorTipsOne')
|
||||
}
|
||||
return res
|
||||
@ -138,11 +138,11 @@ const addOption = () => {
|
||||
diyStore.editComponent.options.push({
|
||||
id: diyStore.generateRandom(),
|
||||
text: '选项' + (diyStore.editComponent.options.length + 1)
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
const removeOption = (index: any) => {
|
||||
diyStore.editComponent.options.splice(index, 1);
|
||||
diyStore.editComponent.options.splice(index, 1)
|
||||
}
|
||||
|
||||
const batchAddOptions = () => {
|
||||
@ -151,39 +151,39 @@ const batchAddOptions = () => {
|
||||
return {
|
||||
id: diyStore.generateRandom(),
|
||||
text: option.trim()
|
||||
};
|
||||
}).filter((option: any) => option.text !== '');
|
||||
}
|
||||
}).filter((option: any) => option.text !== '')
|
||||
|
||||
// 去除重复的选项
|
||||
const uniqueNewOptions = uniqueByKey(newOptions, 'text');
|
||||
const uniqueNewOptions = uniqueByKey(newOptions, 'text')
|
||||
|
||||
// 过滤掉已存在的选项
|
||||
const filteredNewOptions = uniqueNewOptions.filter(newOption =>
|
||||
!diyStore.editComponent.options.some(existingOption => existingOption.text === newOption.text)
|
||||
);
|
||||
)
|
||||
|
||||
// 如果有新的选项,添加到选项列表中
|
||||
if (filteredNewOptions.length > 0) {
|
||||
diyStore.editComponent.options.push(...filteredNewOptions);
|
||||
diyStore.editComponent.options.push(...filteredNewOptions)
|
||||
} else {
|
||||
ElMessage({
|
||||
message: t('errorTipsTwo'),
|
||||
type: "warning",
|
||||
});
|
||||
type: 'warning'
|
||||
})
|
||||
}
|
||||
|
||||
optionsValue.value = '';
|
||||
visible.value = false;
|
||||
optionsValue.value = ''
|
||||
visible.value = false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 数组去重
|
||||
const uniqueByKey = (arr: any, key: any) => {
|
||||
const seen = new Set();
|
||||
const seen = new Set()
|
||||
return arr.filter((item: any) => {
|
||||
const serializedKey = JSON.stringify(item[key]);
|
||||
return seen.has(serializedKey) ? false : seen.add(serializedKey);
|
||||
});
|
||||
const serializedKey = JSON.stringify(item[key])
|
||||
return seen.has(serializedKey) ? false : seen.add(serializedKey)
|
||||
})
|
||||
}
|
||||
|
||||
const formRadioRef = ref()
|
||||
|
||||
@ -87,9 +87,9 @@ diyStore.editComponent.ignore = ['componentBgUrl'] // 忽略公共属性
|
||||
// 单选
|
||||
const btnPositionChangeFn = (e) => {
|
||||
if (e == 'hover_screen_bottom') {
|
||||
diyStore.editComponent.margin.bottom = 0;
|
||||
diyStore.editComponent.margin.both = 0;
|
||||
diyStore.editComponent.margin.top = 0;
|
||||
diyStore.editComponent.margin.bottom = 0
|
||||
diyStore.editComponent.margin.both = 0
|
||||
diyStore.editComponent.margin.top = 0
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,14 +97,14 @@ const btnPositionChangeFn = (e) => {
|
||||
diyStore.editComponent.verify = (index: number) => {
|
||||
const res = { code: true, message: '' }
|
||||
if (diyStore.value[index].submitBtn.text == '') {
|
||||
res.code = false;
|
||||
res.message = t('submitBtnNamePlaceholder');
|
||||
return res;
|
||||
res.code = false
|
||||
res.message = t('submitBtnNamePlaceholder')
|
||||
return res
|
||||
}
|
||||
if (diyStore.value[index].resetBtn.text == '') {
|
||||
res.code = false;
|
||||
res.message = t('resetBtnNamePlaceholder');
|
||||
return res;
|
||||
res.code = false
|
||||
res.message = t('resetBtnNamePlaceholder')
|
||||
return res
|
||||
}
|
||||
|
||||
return res
|
||||
|
||||
@ -166,7 +166,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { t } from '@/lang'
|
||||
import Sortable from 'sortablejs'
|
||||
import { ref, watch, onMounted, nextTick ,reactive, computed} from 'vue'
|
||||
import { ref, watch, onMounted, nextTick, reactive, computed } from 'vue'
|
||||
import useDiyStore from '@/stores/modules/diy'
|
||||
import { range } from 'lodash-es'
|
||||
const diyStore = useDiyStore()
|
||||
@ -221,7 +221,7 @@ const addOption = (item) => {
|
||||
id: generateId(),
|
||||
name: item.label,
|
||||
type: item.value, // 列类型
|
||||
value: '' // 默认值(可选)
|
||||
value: '' // 默认值(可选)
|
||||
}
|
||||
|
||||
// 如果是单选项,初始化 options
|
||||
@ -233,11 +233,11 @@ const addOption = (item) => {
|
||||
}
|
||||
// 如果是日期,初始化 dateFormat
|
||||
if (item.value === 'date') {
|
||||
newColumn.dateFormat = 'YYYY年M月D日' // 默认日期格式
|
||||
newColumn.dateFormat = 'YYYY年M月D日' // 默认日期格式
|
||||
}
|
||||
// 如果是地址,初始化 addressFormat
|
||||
if (item.value === 'address') {
|
||||
newColumn.addressFormat = 'province/city/district/address' // 默认日期格式
|
||||
newColumn.addressFormat = 'province/city/district/address' // 默认日期格式
|
||||
}
|
||||
|
||||
diyStore.editComponent.columnList.push(newColumn)
|
||||
@ -247,7 +247,6 @@ const removeOption = (index: number) => {
|
||||
diyStore.editComponent.columnList.splice(index, 1)
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
// nextTick(() => {
|
||||
// if (diyStore.editComponent.columnList.length < 2) return;
|
||||
@ -266,8 +265,7 @@ onMounted(() => {
|
||||
// }
|
||||
// })
|
||||
// })
|
||||
console.log(diyStore.editComponent.columnList);
|
||||
|
||||
console.log(diyStore.editComponent.columnList)
|
||||
})
|
||||
|
||||
const activeColumn = ref<any>({}) // 真正数据(原始数据,不动它)
|
||||
@ -284,31 +282,31 @@ const dateFormat: any = reactive({
|
||||
format2: '',
|
||||
format3: '',
|
||||
format4: ''
|
||||
});
|
||||
})
|
||||
|
||||
const openRadioDialog = (item, index) => {
|
||||
activeRadioIndex.value = index // 记录当前列的下标,方便确定时更新
|
||||
activeColumn.value = item
|
||||
activeColumnTemp.value = JSON.parse(JSON.stringify(item)) // 深拷贝,避免联动
|
||||
if(item.type == 'radio'){
|
||||
if (item.type == 'radio') {
|
||||
if (!activeColumnTemp.value.options) activeColumnTemp.value.options = []
|
||||
radioDialogVisible.value = true
|
||||
// nextTick(() => initRadioSortable()) // 拖拽初始化
|
||||
}else if(item.type == 'date'){
|
||||
} else if (item.type == 'date') {
|
||||
// 初始赋值当天日期
|
||||
const today = new Date();
|
||||
let year = today.getFullYear();
|
||||
let month = String(today.getMonth() + 1).padStart(2, '0');
|
||||
let day = String(today.getDate()).padStart(2, '0');
|
||||
const today = new Date()
|
||||
const year = today.getFullYear()
|
||||
const month = String(today.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(today.getDate()).padStart(2, '0')
|
||||
|
||||
const hours = String(today.getHours()).padStart(2, '0');
|
||||
const minutes = String(today.getMinutes()).padStart(2, '0');
|
||||
dateFormat.format1 = `${ year }年${ month }月${ day }日`;
|
||||
dateFormat.format2 = `${ year }-${ month }-${ day }`;
|
||||
dateFormat.format3 = `${ year }/${ month }/${ day }`;
|
||||
dateFormat.format4 = `${ year }-${ month }-${ day } ${ hours }:${ minutes }`;
|
||||
radioDialogVisible.value = true
|
||||
} else if(item.type == 'address'){
|
||||
const hours = String(today.getHours()).padStart(2, '0')
|
||||
const minutes = String(today.getMinutes()).padStart(2, '0')
|
||||
dateFormat.format1 = `${year}年${month}月${day}日`
|
||||
dateFormat.format2 = `${year}-${month}-${day}`
|
||||
dateFormat.format3 = `${year}/${month}/${day}`
|
||||
dateFormat.format4 = `${year}-${month}-${day} ${hours}:${minutes}`
|
||||
radioDialogVisible.value = true
|
||||
} else if (item.type == 'address') {
|
||||
radioDialogVisible.value = true
|
||||
}
|
||||
}
|
||||
@ -329,7 +327,7 @@ const openRadioDialog = (item, index) => {
|
||||
// }
|
||||
|
||||
const handleDialogConfirm = () => {
|
||||
console.log(activeColumnTemp.value);
|
||||
console.log(activeColumnTemp.value)
|
||||
|
||||
diyStore.editComponent.columnList[activeRadioIndex.value] = JSON.parse(JSON.stringify(activeColumnTemp.value)) // 同步副本到原数据
|
||||
radioDialogVisible.value = false // 关闭弹窗
|
||||
@ -351,11 +349,11 @@ const removeOptionItem = (index: number) => {
|
||||
|
||||
// 数组去重
|
||||
const uniqueByKey = (arr: any, key: any) => {
|
||||
const seen = new Set();
|
||||
const seen = new Set()
|
||||
return arr.filter((item: any) => {
|
||||
const serializedKey = JSON.stringify(item[key]);
|
||||
return seen.has(serializedKey) ? false : seen.add(serializedKey);
|
||||
});
|
||||
const serializedKey = JSON.stringify(item[key])
|
||||
return seen.has(serializedKey) ? false : seen.add(serializedKey)
|
||||
})
|
||||
}
|
||||
// 批量添加
|
||||
const batchAddOptions = () => {
|
||||
@ -364,36 +362,31 @@ const batchAddOptions = () => {
|
||||
return {
|
||||
id: diyStore.generateRandom(),
|
||||
label: option.trim()
|
||||
};
|
||||
}).filter((option: any) => option.label !== '');
|
||||
}
|
||||
}).filter((option: any) => option.label !== '')
|
||||
|
||||
// 去除重复的选项
|
||||
const uniqueNewOptions = uniqueByKey(newOptions, 'label');
|
||||
const uniqueNewOptions = uniqueByKey(newOptions, 'label')
|
||||
|
||||
// 过滤掉已存在的选项
|
||||
const filteredNewOptions = uniqueNewOptions.filter(newOption =>
|
||||
!activeColumnTemp.value.options.some(existingOption => existingOption.label === newOption.label)
|
||||
);
|
||||
)
|
||||
|
||||
// 如果有新的选项,添加到选项列表中
|
||||
if (filteredNewOptions.length > 0) {
|
||||
activeColumnTemp.value.options.push(...filteredNewOptions);
|
||||
activeColumnTemp.value.options.push(...filteredNewOptions)
|
||||
} else {
|
||||
ElMessage({
|
||||
message: t('errorTipsTwo'),
|
||||
type: "warning",
|
||||
});
|
||||
type: 'warning'
|
||||
})
|
||||
}
|
||||
|
||||
optionsValue.value = '';
|
||||
visible.value = false;
|
||||
optionsValue.value = ''
|
||||
visible.value = false
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
defineExpose({})
|
||||
|
||||
|
||||
@ -91,18 +91,18 @@ diyStore.editComponent.ignore = ['componentBgUrl'] // 忽略公共属性
|
||||
// 组件验证
|
||||
diyStore.editComponent.verify = (index: number) => {
|
||||
const res = { code: true, message: '' }
|
||||
let starTime = diyStore.value[index].field.default.start.date;
|
||||
let endTime = diyStore.value[index].field.default.end.date;
|
||||
let starTime = diyStore.value[index].field.default.start.date
|
||||
let endTime = diyStore.value[index].field.default.end.date
|
||||
|
||||
const today = new Date();
|
||||
const hours = String(today.getHours()).padStart(2, '0');
|
||||
const minutes = String(today.getMinutes()).padStart(2, '0');
|
||||
const today = new Date()
|
||||
const hours = String(today.getHours()).padStart(2, '0')
|
||||
const minutes = String(today.getMinutes()).padStart(2, '0')
|
||||
|
||||
if (diyStore.editComponent.start.timeWay == 'current') {
|
||||
starTime = `${ hours }:${ minutes }`;
|
||||
starTime = `${hours}:${minutes}`
|
||||
}
|
||||
if (diyStore.editComponent.end.timeWay == 'current') {
|
||||
endTime = `${ hours }:${ minutes }`;
|
||||
endTime = `${hours}:${minutes}`
|
||||
}
|
||||
|
||||
if (diyStore.editComponent.start.defaultControl && starTime == '') {
|
||||
@ -125,51 +125,51 @@ diyStore.editComponent.verify = (index: number) => {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const today = new Date();
|
||||
const hours = String(today.getHours()).padStart(2, '0');
|
||||
const minutes = String(today.getMinutes()).padStart(2, '0');
|
||||
const today = new Date()
|
||||
const hours = String(today.getHours()).padStart(2, '0')
|
||||
const minutes = String(today.getMinutes()).padStart(2, '0')
|
||||
|
||||
if (!diyStore.editComponent.field.default.start.date) {
|
||||
diyStore.editComponent.field.default.start.date = `${ hours }:${ minutes }`;
|
||||
diyStore.editComponent.field.default.start.timestamp = timeInvertSecond(`${ hours }:${ minutes }`);
|
||||
diyStore.editComponent.field.default.start.date = `${hours}:${minutes}`
|
||||
diyStore.editComponent.field.default.start.timestamp = timeInvertSecond(`${hours}:${minutes}`)
|
||||
}
|
||||
if (!diyStore.editComponent.field.default.end.date) {
|
||||
let endDate = new Date();
|
||||
endDate.setHours(today.getHours(), today.getMinutes() + 10, 0, 0); // 在当前时间基础上加 10 分钟
|
||||
const endHours = String(endDate.getHours()).padStart(2, '0');
|
||||
const endMinutes = String(endDate.getMinutes()).padStart(2, '0');
|
||||
const endDate = new Date()
|
||||
endDate.setHours(today.getHours(), today.getMinutes() + 10, 0, 0) // 在当前时间基础上加 10 分钟
|
||||
const endHours = String(endDate.getHours()).padStart(2, '0')
|
||||
const endMinutes = String(endDate.getMinutes()).padStart(2, '0')
|
||||
|
||||
diyStore.editComponent.field.default.end.date = `${ endHours }:${ endMinutes }`;
|
||||
diyStore.editComponent.field.default.end.timestamp = timeInvertSecond(`${ endHours }:${ endMinutes }`);
|
||||
diyStore.editComponent.field.default.end.date = `${endHours}:${endMinutes}`
|
||||
diyStore.editComponent.field.default.end.timestamp = timeInvertSecond(`${endHours}:${endMinutes}`)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
// 开始时间选择器
|
||||
const startTimePickerChange = (e) => {
|
||||
diyStore.editComponent.field.default.start.timestamp = timeInvertSecond(e);
|
||||
diyStore.editComponent.field.default.start.timestamp = timeInvertSecond(e)
|
||||
|
||||
const startTimeArr = e.split(":");
|
||||
const date = new Date();
|
||||
date.setHours(parseInt(startTimeArr[0]), parseInt(startTimeArr[1]), 0, 0);
|
||||
date.setMinutes(date.getMinutes() + 10);
|
||||
const updatedEndTime = `${ String(date.getHours()).padStart(2, '0') }:${ String(date.getMinutes()).padStart(2, '0') }`;
|
||||
diyStore.editComponent.field.default.end.date = updatedEndTime;
|
||||
diyStore.editComponent.field.default.end.timestamp = timeInvertSecond(updatedEndTime);
|
||||
const startTimeArr = e.split(':')
|
||||
const date = new Date()
|
||||
date.setHours(parseInt(startTimeArr[0]), parseInt(startTimeArr[1]), 0, 0)
|
||||
date.setMinutes(date.getMinutes() + 10)
|
||||
const updatedEndTime = `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`
|
||||
diyStore.editComponent.field.default.end.date = updatedEndTime
|
||||
diyStore.editComponent.field.default.end.timestamp = timeInvertSecond(updatedEndTime)
|
||||
}
|
||||
|
||||
// 结束时间选择器
|
||||
const endTimePickerChange = (e) => {
|
||||
diyStore.editComponent.field.default.end.timestamp = timeInvertSecond(e);
|
||||
diyStore.editComponent.field.default.end.timestamp = timeInvertSecond(e)
|
||||
}
|
||||
|
||||
const disabledHours = () => {
|
||||
let timeArr = diyStore.editComponent.field.default.start.date.split(":")
|
||||
return makeRange(0, timeArr[0]);
|
||||
const timeArr = diyStore.editComponent.field.default.start.date.split(':')
|
||||
return makeRange(0, timeArr[0])
|
||||
}
|
||||
|
||||
const disabledMinutes = (hour: number) => {
|
||||
let timeArr = diyStore.editComponent.field.default.start.date.split(":")
|
||||
return makeRange(0, timeArr[1]);
|
||||
const timeArr = diyStore.editComponent.field.default.start.date.split(':')
|
||||
return makeRange(0, timeArr[1])
|
||||
}
|
||||
|
||||
const makeRange = (start: number, end: number) => {
|
||||
@ -181,18 +181,18 @@ const makeRange = (start: number, end: number) => {
|
||||
}
|
||||
|
||||
const timeInvertSecond = (time: any) => {
|
||||
let arr = time.split(":");
|
||||
let num = 0;
|
||||
const arr = time.split(':')
|
||||
let num = 0
|
||||
if (arr[0]) {
|
||||
num += arr[0] * 60 * 60;
|
||||
num += arr[0] * 60 * 60
|
||||
}
|
||||
if (arr[1]) {
|
||||
num += arr[1] * 60;
|
||||
num += arr[1] * 60
|
||||
}
|
||||
if (arr[2]) {
|
||||
num += arr[2];
|
||||
num += arr[2]
|
||||
}
|
||||
return num;
|
||||
return num
|
||||
}
|
||||
|
||||
defineExpose({})
|
||||
|
||||
@ -56,31 +56,31 @@ diyStore.editComponent.verify = (index: number) => {
|
||||
onMounted(() => {
|
||||
// 初始赋值当天时间
|
||||
if (!diyStore.editComponent.field.default) {
|
||||
const today = new Date();
|
||||
const hours = String(today.getHours()).padStart(2, '0');
|
||||
const minutes = String(today.getMinutes()).padStart(2, '0');
|
||||
diyStore.editComponent.field.default = `${ hours }:${ minutes }`;
|
||||
const today = new Date()
|
||||
const hours = String(today.getHours()).padStart(2, '0')
|
||||
const minutes = String(today.getMinutes()).padStart(2, '0')
|
||||
diyStore.editComponent.field.default = `${hours}:${minutes}`
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
const changeDateDefaultControl = (val: any) => {
|
||||
if (val) {
|
||||
const today = new Date();
|
||||
const hours = String(today.getHours()).padStart(2, '0');
|
||||
const minutes = String(today.getMinutes()).padStart(2, '0');
|
||||
diyStore.editComponent.field.default = `${ hours }:${ minutes }`;
|
||||
const today = new Date()
|
||||
const hours = String(today.getHours()).padStart(2, '0')
|
||||
const minutes = String(today.getMinutes()).padStart(2, '0')
|
||||
diyStore.editComponent.field.default = `${hours}:${minutes}`
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => diyStore.editComponent.timeWay,
|
||||
(newVal) => {
|
||||
const today = new Date();
|
||||
const hours = String(today.getHours()).padStart(2, '0');
|
||||
const minutes = String(today.getMinutes()).padStart(2, '0');
|
||||
diyStore.editComponent.field.default = `${ hours }:${ minutes }`;
|
||||
const today = new Date()
|
||||
const hours = String(today.getHours()).padStart(2, '0')
|
||||
const minutes = String(today.getMinutes()).padStart(2, '0')
|
||||
diyStore.editComponent.field.default = `${hours}:${minutes}`
|
||||
}
|
||||
);
|
||||
)
|
||||
|
||||
defineExpose({})
|
||||
|
||||
|
||||
@ -39,7 +39,7 @@
|
||||
import { reactive, ref, nextTick } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getFormType, getDiyFormSelectPageList } from '@/app/api/diy_form'
|
||||
import { FormInstance, ElMessage } from "element-plus";
|
||||
import { FormInstance, ElMessage } from 'element-plus'
|
||||
|
||||
const prop = defineProps({
|
||||
formId: {
|
||||
@ -52,7 +52,7 @@ const formType: any = reactive({}) // 表单类型
|
||||
|
||||
const searchFormRef = ref<FormInstance>()
|
||||
|
||||
const tableRef = ref();
|
||||
const tableRef = ref()
|
||||
|
||||
const tableData: any = reactive({
|
||||
page: 1,
|
||||
@ -102,8 +102,8 @@ const loadList = (page: number = 1) => {
|
||||
// 获取万能表单类型
|
||||
const loadFormType = (addon = '') => {
|
||||
getFormType({}).then(res => {
|
||||
for (let key in formType) {
|
||||
delete formType[key];
|
||||
for (const key in formType) {
|
||||
delete formType[key]
|
||||
}
|
||||
|
||||
for (const key in res.data) {
|
||||
@ -112,7 +112,7 @@ const loadFormType = (addon = '') => {
|
||||
})
|
||||
}
|
||||
|
||||
loadFormType();
|
||||
loadFormType()
|
||||
loadList()
|
||||
|
||||
const handleCheckChange = (isSelect: any, row: any) => {
|
||||
@ -147,14 +147,14 @@ const getData = () => {
|
||||
if (selectData.form_id == 0) {
|
||||
ElMessage({
|
||||
type: 'warning',
|
||||
message: `${ t('formSelectContentTips') }`
|
||||
message: `${t('formSelectContentTips')}`
|
||||
})
|
||||
return;
|
||||
return
|
||||
}
|
||||
return {
|
||||
name: 'DIY_FORM',
|
||||
title: selectData.page_title,
|
||||
url: `/app/pages/index/diy_form?form_id=${ selectData.form_id }`,
|
||||
url: `/app/pages/index/diy_form?form_id=${selectData.form_id}`,
|
||||
action: '',
|
||||
formId: selectData.form_id
|
||||
}
|
||||
|
||||
@ -746,7 +746,7 @@ const initLoad = () => {
|
||||
|
||||
// 验证表单组件公共属性
|
||||
const verifyFormComponent = () => {
|
||||
for (var i = 0; i < diyStore.value.length; i++) {
|
||||
for (let i = 0; i < diyStore.value.length; i++) {
|
||||
try {
|
||||
if (diyStore.value[i].componentType == 'diy_form' && diyStore.value[i].componentName != 'FormSubmit' && diyStore.value[i].field.name == '') {
|
||||
diyStore.changeCurrentIndex(i, diyStore.value[i])
|
||||
|
||||
@ -176,10 +176,10 @@
|
||||
import { reactive, ref, computed } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getFormType, getApps, getDiyFormPageList, deleteDiyForm, editDiyFormShare, editFormStatus, copyForm } from '@/app/api/diy_form'
|
||||
import { FormInstance, ElMessage, ElMessageBox } from "element-plus";
|
||||
import { FormInstance, ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { setTablePageStorage,getTablePageStorage } from "@/utils/common";
|
||||
import { img } from '@/utils/common'
|
||||
import { setTablePageStorage, getTablePageStorage, img } from '@/utils/common'
|
||||
|
||||
import recordsDetail from '@/app/views/diy_form/records.vue'
|
||||
import formSubmitPopup from '@/app/views/diy_form/components/form-submit-popup.vue'
|
||||
import formWritePopup from '@/app/views/diy_form/components/form-write-popup.vue'
|
||||
@ -198,12 +198,12 @@ const formData = reactive({
|
||||
type: ''
|
||||
})
|
||||
|
||||
//详情
|
||||
// 详情
|
||||
const recordsDetailDialog: Record<string, any> | null = ref(null)
|
||||
const detailEvent=(row: any)=>{
|
||||
let data = {form_id: row.form_id};
|
||||
recordsDetailDialog.value.setFormData(data);
|
||||
recordsDetailDialog.value.showDialog = true;
|
||||
const detailEvent = (row: any) => {
|
||||
const data = { form_id: row.form_id }
|
||||
recordsDetailDialog.value.setFormData(data)
|
||||
recordsDetailDialog.value.showDialog = true
|
||||
}
|
||||
|
||||
// 表单验证规则
|
||||
@ -223,7 +223,7 @@ const dialogVisible = ref(false)
|
||||
const addEvent = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
|
||||
await formEl.validate(async(valid) => {
|
||||
await formEl.validate(async (valid) => {
|
||||
if (valid) {
|
||||
const query = { type: formData.type } // , title: formData.title
|
||||
const url = router.resolve({
|
||||
@ -250,10 +250,10 @@ const showClick = (row: any) => {
|
||||
}
|
||||
|
||||
// 获取万能表单类型
|
||||
const loadFormType = (addon = '')=> {
|
||||
const loadFormType = (addon = '') => {
|
||||
getFormType({}).then(res => {
|
||||
for (let key in formType) {
|
||||
delete formType[key];
|
||||
for (const key in formType) {
|
||||
delete formType[key]
|
||||
}
|
||||
|
||||
for (const key in res.data) {
|
||||
@ -263,7 +263,7 @@ const loadFormType = (addon = '')=> {
|
||||
})
|
||||
}
|
||||
|
||||
loadFormType();
|
||||
loadFormType()
|
||||
|
||||
const apps: any = reactive({}) // 应用插件列表
|
||||
|
||||
@ -278,7 +278,7 @@ const apps: any = reactive({}) // 应用插件列表
|
||||
|
||||
// 根据所属插件,查询表单类型
|
||||
const handleSelectAddonChange = (value: any) => {
|
||||
diyFormTableData.searchParam.type = '';
|
||||
diyFormTableData.searchParam.type = ''
|
||||
loadFormType(value)
|
||||
}
|
||||
|
||||
@ -311,16 +311,16 @@ const loadDiyFormList = (page: number = 1) => {
|
||||
diyFormTableData.loading = false
|
||||
diyFormTableData.data = res.data.data
|
||||
diyFormTableData.total = res.data.total
|
||||
setTablePageStorage(diyFormTableData.page, diyFormTableData.limit, diyFormTableData.searchParam);
|
||||
setTablePageStorage(diyFormTableData.page, diyFormTableData.limit, diyFormTableData.searchParam)
|
||||
}).catch(() => {
|
||||
diyFormTableData.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
loadDiyFormList(getTablePageStorage(diyFormTableData.searchParam).page);
|
||||
loadDiyFormList(getTablePageStorage(diyFormTableData.searchParam).page)
|
||||
|
||||
const selectType = (index: number) => {
|
||||
formData.type = index.toString();
|
||||
formData.type = index.toString()
|
||||
}
|
||||
|
||||
const resetForm = (formEl: FormInstance | undefined) => {
|
||||
@ -350,7 +350,7 @@ const copyEvent = (id: any) => {
|
||||
if (repeat.value) return
|
||||
repeat.value = true
|
||||
|
||||
copyForm({form_id: id}).then((res: any) => {
|
||||
copyForm({ form_id: id }).then((res: any) => {
|
||||
if (res.code == 1) {
|
||||
loadDiyFormList()
|
||||
}
|
||||
@ -377,74 +377,74 @@ const deleteEvent = (form_id: number) => {
|
||||
})
|
||||
}
|
||||
// 批量复选框
|
||||
const toggleCheckbox = ref();
|
||||
const toggleCheckbox = ref()
|
||||
|
||||
// 复选框中间状态
|
||||
const isIndeterminate = ref(false);
|
||||
const isIndeterminate = ref(false)
|
||||
|
||||
// 监听批量复选框事件
|
||||
const toggleChange = (value: any) => {
|
||||
isIndeterminate.value = false;
|
||||
diyFormListTableRef.value.toggleAllSelection();
|
||||
};
|
||||
isIndeterminate.value = false
|
||||
diyFormListTableRef.value.toggleAllSelection()
|
||||
}
|
||||
|
||||
const diyFormListTableRef = ref();
|
||||
const diyFormListTableRef = ref()
|
||||
|
||||
// 选中数据
|
||||
const multipleSelection: any = ref([]);
|
||||
const multipleSelection: any = ref([])
|
||||
|
||||
// 监听表格单行选中
|
||||
const handleSelectionChange = (val: []) => {
|
||||
multipleSelection.value = val;
|
||||
multipleSelection.value = val
|
||||
|
||||
toggleCheckbox.value = false;
|
||||
toggleCheckbox.value = false
|
||||
if (
|
||||
multipleSelection.value.length > 0 &&
|
||||
multipleSelection.value.length < diyFormTableData.data.length
|
||||
) {
|
||||
isIndeterminate.value = true;
|
||||
isIndeterminate.value = true
|
||||
} else {
|
||||
isIndeterminate.value = false;
|
||||
isIndeterminate.value = false
|
||||
}
|
||||
|
||||
if (multipleSelection.value.length == diyFormTableData.data.length) {
|
||||
toggleCheckbox.value = true;
|
||||
toggleCheckbox.value = true
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 批量删除
|
||||
const batchDeleteForms = () => {
|
||||
if (multipleSelection.value.length == 0) {
|
||||
ElMessage({
|
||||
type: "warning",
|
||||
message: `${t("batchEmptySelectedFormsTips")}`,
|
||||
});
|
||||
return;
|
||||
type: 'warning',
|
||||
message: `${t('batchEmptySelectedFormsTips')}`
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
ElMessageBox.confirm(t("batchFormsDeleteTips"), t("warning"), {
|
||||
confirmButtonText: t("confirm"),
|
||||
cancelButtonText: t("cancel"),
|
||||
type: "warning",
|
||||
ElMessageBox.confirm(t('batchFormsDeleteTips'), t('warning'), {
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
if (repeat.value) return;
|
||||
repeat.value = true;
|
||||
if (repeat.value) return
|
||||
repeat.value = true
|
||||
|
||||
const form_ids: any = [];
|
||||
const form_ids: any = []
|
||||
multipleSelection.value.forEach((item: any) => {
|
||||
form_ids.push(item.form_id);
|
||||
});
|
||||
form_ids.push(item.form_id)
|
||||
})
|
||||
|
||||
deleteDiyForm({
|
||||
form_ids: form_ids,
|
||||
form_ids
|
||||
}).then(() => {
|
||||
loadDiyFormList();
|
||||
repeat.value = false;
|
||||
loadDiyFormList()
|
||||
repeat.value = false
|
||||
}).catch(() => {
|
||||
repeat.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
repeat.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 跳转去预览
|
||||
const toPreview = (data: any) => {
|
||||
@ -453,7 +453,7 @@ const toPreview = (data: any) => {
|
||||
query: {
|
||||
page: '/app/pages/index/diy_form?form_id=' + data.form_id
|
||||
}
|
||||
});
|
||||
})
|
||||
window.open(url.href)
|
||||
}
|
||||
|
||||
@ -509,16 +509,15 @@ const shareEvent = async (formEl: FormInstance | undefined) => {
|
||||
const spreadPopupRef = ref(null)
|
||||
|
||||
const spreadEvent = (data: any) => {
|
||||
const pagePath = "/app/pages/index/diy_form"
|
||||
const columnName = "form_id"
|
||||
const columnValue = data.form_id
|
||||
const title = "表单推广"
|
||||
const folder = "diy_form"
|
||||
|
||||
spreadPopupRef.value?.show(pagePath, columnName, columnValue, title,folder)
|
||||
const pagePath = '/app/pages/index/diy_form'
|
||||
const paramsArr = [
|
||||
{ name: 'form_id', value: data.form_id },
|
||||
];
|
||||
const title = '表单推广'
|
||||
const folder = 'diy_form'
|
||||
spreadPopupRef.value?.show(pagePath, paramsArr, title, folder);
|
||||
}
|
||||
|
||||
|
||||
// 表单提交成功页弹出框
|
||||
const formSubmitPopupRef: any = ref(null)
|
||||
|
||||
@ -545,7 +544,7 @@ const handleExportClose = (val) => {
|
||||
}
|
||||
|
||||
const diyFormDetailData: any = reactive({
|
||||
form_id: 0,
|
||||
form_id: 0
|
||||
})
|
||||
const exportEvent = (data: any) => {
|
||||
diyFormDetailData.form_id = data.form_id
|
||||
|
||||
@ -181,7 +181,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, defineAsyncComponent } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getDiyFormFieldsList, getDiyFormFieldStat, getFormRecords,getFormRecordsInfo,deleteFormRecords,getFormRecordsMember} from '@/app/api/diy_form'
|
||||
import { getDiyFormFieldsList, getDiyFormFieldStat, getFormRecords, getFormRecordsInfo, deleteFormRecords, getFormRecordsMember } from '@/app/api/diy_form'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { img } from '@/utils/common'
|
||||
import { ElMessageBox, FormInstance } from 'element-plus'
|
||||
@ -195,7 +195,7 @@ const searchFormDiyFormRef = ref<FormInstance>()
|
||||
const searchFormDiyMemberRef = ref<FormInstance>()
|
||||
const searchFormDiyFieldsRef = ref<FormInstance>()
|
||||
const handleClose = (done: () => void) => {
|
||||
showDialog.value = false;
|
||||
showDialog.value = false
|
||||
}
|
||||
|
||||
const formData = reactive({
|
||||
@ -220,7 +220,7 @@ const getDiyFormFieldsListFn = (form_id: any) => {
|
||||
order: 'field_id',
|
||||
sort: 'asc'
|
||||
}).then((res: any) => {
|
||||
formFieldsList.value = res.data;
|
||||
formFieldsList.value = res.data
|
||||
})
|
||||
}
|
||||
|
||||
@ -230,7 +230,7 @@ const getDiyFormFieldStatFn = (form_id: any) => {
|
||||
getDiyFormFieldStat({
|
||||
form_id
|
||||
}).then((res: any) => {
|
||||
formFieldsStat.value = res.data;
|
||||
formFieldsStat.value = res.data
|
||||
})
|
||||
}
|
||||
|
||||
@ -238,7 +238,7 @@ const modules: any = import.meta.glob('@/**/*.vue')
|
||||
const formDetail = ref([])
|
||||
|
||||
const formDetailEvent = (row: any) => {
|
||||
getFormRecordsInfo(row.record_id).then((res:any)=>{
|
||||
getFormRecordsInfo(row.record_id).then((res:any) => {
|
||||
formDetail.value = res.data.value
|
||||
dialogVisible.value = true
|
||||
})
|
||||
@ -257,7 +257,7 @@ const deleteEvent = (row: any) => {
|
||||
record_id: row.record_id,
|
||||
form_id: row.form_id
|
||||
}).then(() => {
|
||||
initData();
|
||||
initData()
|
||||
})
|
||||
})
|
||||
}
|
||||
@ -273,7 +273,7 @@ const resetFormMember = (formEl: FormInstance | undefined) => {
|
||||
getFormRecordsMemberFn()
|
||||
}
|
||||
|
||||
const loadFormRecordsListFn= (page: number = 1)=> {
|
||||
const loadFormRecordsListFn = (page: number = 1) => {
|
||||
formData.loading = true
|
||||
formData.page = page
|
||||
getFormRecords({
|
||||
@ -284,7 +284,7 @@ const loadFormRecordsListFn= (page: number = 1)=> {
|
||||
formData.loading = false
|
||||
formData.data = res.data.data
|
||||
formData.data.forEach((item: any) => {
|
||||
for (let key: any in item.recordsFieldList) {
|
||||
for (const key: any in item.recordsFieldList) {
|
||||
if (modules[item.recordsFieldList[key].detailComponent]) {
|
||||
item.recordsFieldList[key].detailComponent && (item.recordsFieldList[key].detailComponent = defineAsyncComponent(modules[item.recordsFieldList[key].detailComponent]))
|
||||
}
|
||||
@ -315,32 +315,32 @@ const getFormRecordsMemberFn = (page: number = 1) => {
|
||||
limit: formMemberList.limit,
|
||||
...formMemberList.searchParam
|
||||
}).then((res: any) => {
|
||||
formMemberList.data = res.data.data;
|
||||
formMemberList.total = res.total;
|
||||
formMemberList.loading = false;
|
||||
formMemberList.data = res.data.data
|
||||
formMemberList.total = res.total
|
||||
formMemberList.loading = false
|
||||
}).catch((error) => {
|
||||
formMemberList.loading = false;
|
||||
formMemberList.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
//查看会员详情
|
||||
// 查看会员详情
|
||||
const detailEvent = (member_id:number) => {
|
||||
let routeData = router.resolve(`/member/detail?id=${ member_id }`)
|
||||
window.open(routeData.href, ' blank');
|
||||
const routeData = router.resolve(`/member/detail?id=${member_id}`)
|
||||
window.open(routeData.href, ' blank')
|
||||
}
|
||||
|
||||
const setFormData = async (row: any = null) => {
|
||||
formId.value = row.form_id;
|
||||
formData.searchParam.form_id = row.form_id;
|
||||
formMemberList.searchParam.form_id = row.form_id;
|
||||
formId.value = row.form_id
|
||||
formData.searchParam.form_id = row.form_id
|
||||
formMemberList.searchParam.form_id = row.form_id
|
||||
|
||||
getDiyFormFieldsListFn(row.form_id);
|
||||
initData();
|
||||
getDiyFormFieldsListFn(row.form_id)
|
||||
initData()
|
||||
}
|
||||
|
||||
const initData = () => {
|
||||
getFormRecordsMemberFn();
|
||||
getDiyFormFieldStatFn(formId.value);
|
||||
getFormRecordsMemberFn()
|
||||
getDiyFormFieldStatFn(formId.value)
|
||||
loadFormRecordsListFn()
|
||||
}
|
||||
|
||||
|
||||
@ -45,7 +45,7 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('memberInfo')" prop="keywords">
|
||||
<el-input v-model.trim="orderTableData.searchParam.keywords" class="w-[240px]"
|
||||
<el-input v-model.trim="orderTableData.searchParam.keywords" class="!w-[230px]"
|
||||
:placeholder="t('memberInfoPlaceholder')" />
|
||||
</el-form-item>
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-drawer v-model="showDialog" title="退款详情" direction="rtl" :before-close="handleClose" class="member-detail-drawer">
|
||||
<el-drawer v-model="showDialog" title="退款详情" direction="rtl" :before-close="handleClose" size="1300px">
|
||||
<div class="main-container" v-loading="loading">
|
||||
<div class="relative" v-if="formData">
|
||||
<div class="flex mb-[20px] justify-between text-[15px]">
|
||||
@ -152,8 +152,4 @@ defineExpose({
|
||||
setFormData
|
||||
})
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.member-detail-drawer{
|
||||
width: 1300px !important;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@ -62,7 +62,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getPayRefundPages ,getRefundStatus} from '@/app/api/pay'
|
||||
import { getPayRefundPages, getRefundStatus } from '@/app/api/pay'
|
||||
import { useRoute } from 'vue-router'
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import refundDetail from '@/app/views/finance/components/refund-detail.vue'
|
||||
@ -114,9 +114,9 @@ const handleMessage = () => {
|
||||
}
|
||||
const refundDetailDialog: Record<string, any> | null = ref(null)
|
||||
const infoEvent = (res:any) => {
|
||||
let data = {no: res.refund_no};
|
||||
refundDetailDialog.value.setFormData(data);
|
||||
refundDetailDialog.value.showDialog = true;
|
||||
const data = { no: res.refund_no }
|
||||
refundDetailDialog.value.setFormData(data)
|
||||
refundDetailDialog.value.showDialog = true
|
||||
}
|
||||
|
||||
const resetForm = (formEl: FormInstance | undefined) => {
|
||||
|
||||
@ -132,7 +132,7 @@ const toAppStore = () => {
|
||||
}
|
||||
|
||||
.app-item {
|
||||
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.18);
|
||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.18);
|
||||
}
|
||||
.app-item:hover .app-item-head{
|
||||
background-color: #FDF4EF;
|
||||
|
||||
@ -83,11 +83,10 @@ setLayout('decorate')
|
||||
getUrl().then((res: any) => {
|
||||
wapUrl.value = res.data.wap_url
|
||||
|
||||
let repeat = true; // 防重复执行
|
||||
let repeat = true // 防重复执行
|
||||
|
||||
// 开发模式下执行
|
||||
if (import.meta.env.MODE == 'development') {
|
||||
|
||||
wapDomain.value = res.data.wap_domain
|
||||
|
||||
// env文件配置过wap域名
|
||||
@ -105,10 +104,9 @@ getUrl().then((res: any) => {
|
||||
}
|
||||
}
|
||||
|
||||
if(repeat) {
|
||||
if (repeat) {
|
||||
setDomain()
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
const save = () => {
|
||||
@ -134,7 +132,7 @@ const setDomain = () => {
|
||||
wapImage.value = url
|
||||
})
|
||||
|
||||
const send = ()=>{
|
||||
const send = () => {
|
||||
timeIframe.value = new Date().getTime()
|
||||
postMessage()
|
||||
}
|
||||
@ -143,17 +141,17 @@ const setDomain = () => {
|
||||
send()
|
||||
|
||||
// 如果同步发送消息的 uni-app没有接收到回应,则定时发送消息
|
||||
let sendCount = 0;
|
||||
let timeInterVal = setInterval(()=>{
|
||||
let sendCount = 0
|
||||
const timeInterVal = setInterval(() => {
|
||||
// 接收 uni-app 发送的消息 或者 发送50次后未响应,则停止发送
|
||||
if(uniAppLoadStatus.value || sendCount >= 50){
|
||||
if (uniAppLoadStatus.value || sendCount >= 50) {
|
||||
clearInterval(timeInterVal)
|
||||
return
|
||||
}
|
||||
|
||||
send()
|
||||
sendCount++;
|
||||
},200)
|
||||
sendCount++
|
||||
}, 200)
|
||||
|
||||
// 如果10秒内加载不出来,则需要配置域名
|
||||
setTimeout(() => {
|
||||
@ -168,17 +166,17 @@ const uniAppLoadStatus = ref(false) // uni-app 加载状态,true:加载完
|
||||
window.addEventListener('message', (event) => {
|
||||
try {
|
||||
let data = {
|
||||
type :''
|
||||
};
|
||||
if(typeof event.data == 'string') {
|
||||
type: ''
|
||||
}
|
||||
if (typeof event.data == 'string') {
|
||||
data = JSON.parse(event.data)
|
||||
}else if(typeof event.data == 'object') {
|
||||
} else if (typeof event.data == 'object') {
|
||||
data = event.data
|
||||
}
|
||||
if (data.type && ['appOnLaunch', 'appOnReady'].indexOf(data.type) != -1) {
|
||||
loadingDev.value = false
|
||||
loadingIframe.value = true
|
||||
let loadTime = new Date().getTime()
|
||||
const loadTime = new Date().getTime()
|
||||
uniAppLoadStatus.value = true // 加载完成
|
||||
difference.value = loadTime - timeIframe.value
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@
|
||||
<el-image class="w-[54px] h-[54px]" :src="row.icon" fit="contain">
|
||||
<template #error>
|
||||
<div class="flex items-center w-full h-full">
|
||||
<img class="max-w-full max-h-full" src="@/app/assets/images/icon-addon.png" alt="" />
|
||||
<img class="max-w-full max-h-full" src="@/app/assets/images/icon-addon-one.png" alt="" />
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
@ -351,7 +351,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-show="installStep == 1 && !errorDialog" class="h-[50vh] mt-[20px]">
|
||||
<terminal ref="terminalRef" :context="currAddon" :init-log="null" :show-header="false" :show-log-time="true" @exec-cmd="onExecCmd" />
|
||||
<terminal ref="terminalRef" :name="`install-${terminalId}`" :context="currAddon" :init-log="null" :show-header="false" :show-log-time="true" @exec-cmd="onExecCmd" />
|
||||
</div>
|
||||
<div v-show="installStep == 2" class="h-[50vh] mt-[20px] flex flex-col">
|
||||
<!-- <el-result icon="success" :title="t('addonInstallSuccess')"></el-result> -->
|
||||
@ -375,12 +375,15 @@
|
||||
</template>
|
||||
</el-result>
|
||||
</div>
|
||||
<div class="mt-[50px]" v-show="errorDialog">
|
||||
<el-result icon="error" :title="t('安装失败')" :sub-title="errorMsg">
|
||||
<div class="h-[50vh] mt-[20px] flex flex-col" v-show="errorDialog">
|
||||
<el-result icon="error" :title="t('安装失败')">
|
||||
<template #icon>
|
||||
<img src="@/app/assets/images/error_icon.png" alt="">
|
||||
</template>
|
||||
<template #extra>
|
||||
<el-scrollbar class="max-h-[120px] !overflow-auto text-[15px] text-[#4F516D] mb-[15px] mt-[-15px]">
|
||||
{{errorMsg}}
|
||||
</el-scrollbar>
|
||||
<el-button @click="handleBack()" v-if="installType=='cloud'" class="!w-[90px]">错误信息</el-button>
|
||||
<el-button @click="installShowDialog=false" type="primary" class="!w-[90px]">完成</el-button>
|
||||
</template>
|
||||
@ -500,6 +503,7 @@ import UpgradeLog from '@/app/components/upgrade-log/index.vue'
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const terminalId = ref(Date.now());
|
||||
const activeName = ref(storage.get('storeActiveName') || 'installed')
|
||||
const upgradeRef = ref(null)
|
||||
const cloudBuildRef = ref(null)
|
||||
|
||||
@ -49,7 +49,7 @@ const formData = ref({
|
||||
continue_sign: 0,
|
||||
continue_tag: guid(),
|
||||
receive_limit: 1,
|
||||
receive_num: 0,
|
||||
receive_num: 0
|
||||
})
|
||||
|
||||
const value = computed({
|
||||
@ -101,7 +101,7 @@ const formRules = reactive<FormRules>({
|
||||
} else if (Number(value) > Number(props.sign_period)) {
|
||||
callback(t('continueSignMustLessThanSignPeriod')) // 添加这个校验
|
||||
} else {
|
||||
callback();
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-drawer v-model="showDialog" title="核销记录详情" direction="rtl" :before-close="handleClose" class="member-detail-drawer">
|
||||
<el-drawer v-model="showDialog" title="核销记录详情" direction="rtl" :before-close="handleClose" size="1300px">
|
||||
<div class="main-container" v-loading="loading">
|
||||
<el-tabs v-model="activeName" class="pb-[10px]" @tab-change="handleClick">
|
||||
<el-tab-pane label="核销信息" name="verifyInfo" />
|
||||
@ -28,7 +28,7 @@
|
||||
<div class="flex items-center mt-[15px]">
|
||||
<span class="text-[14px] w-[130px] text-right mr-[20px]">{{ t('核销人员') }}</span>
|
||||
<span class="text-[14px] text-[#666666]">
|
||||
{{ verifyData.member ? verifyData.member.nickname : '--' }}
|
||||
{{ (verifyData.is_admin == 1 ? '后台核销' : verifyData.member?.nickname) || '--' }}
|
||||
</span>
|
||||
</div>
|
||||
</el-col>
|
||||
@ -147,7 +147,7 @@ const getVerifyDetailFn = async () => {
|
||||
|
||||
const setFormData = async (row: any = null) => {
|
||||
code = row.code;
|
||||
getVerifyDetailFn();
|
||||
await getVerifyDetailFn();
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
@ -156,8 +156,4 @@ defineExpose({
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.member-detail-drawer{
|
||||
width: 1300px !important;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
|
||||
<el-form :inline="true" :model="memberSignListTableData.searchParam" ref="searchFormRef">
|
||||
<el-form-item :label="t('memberInfo')" prop="keywords">
|
||||
<el-input v-model.trim="memberSignListTableData.searchParam.keywords" class="w-[240px]" :placeholder="t('memberInfoPlaceholder')" />
|
||||
<el-input v-model.trim="memberSignListTableData.searchParam.keywords" class="!w-[230px]" :placeholder="t('memberInfoPlaceholder')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('createTime')" prop="create_time">
|
||||
<el-date-picker v-model="memberSignListTableData.searchParam.create_time" type="datetimerange" value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="t('startDate')" :end-placeholder="t('endDate')" />
|
||||
|
||||
@ -39,15 +39,17 @@
|
||||
<template #empty>
|
||||
<span>{{ !recordTable.loading ? t('emptyData') : '' }}</span>
|
||||
</template>
|
||||
|
||||
<el-table-column prop="code" :show-overflow-tooltip="true" :label="t('verifyCode')" align="left" min-width="150" />
|
||||
<el-table-column prop="type_name" :label="t('verifyType')" align="left" min-width="150" />
|
||||
<el-table-column :label="t('verifyTime')" min-width="180" align="center" :show-overflow-tooltip="true">
|
||||
<el-table-column :label="t('verifyTime')" min-width="180" align="left" :show-overflow-tooltip="true">
|
||||
<template #default="{ row }">
|
||||
{{ row.create_time || '' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="member.nickname" :label="t('verifyer')" min-width="180" align="center">
|
||||
<el-table-column prop="type_name" :label="t('verifyType')" align="left" min-width="150" />
|
||||
<el-table-column prop="code" :show-overflow-tooltip="true" :label="t('verifyCode')" align="left" min-width="150" />
|
||||
<el-table-column :label="t('verifyer')" min-width="180" align="center">
|
||||
<template #default="{ row }">
|
||||
{{ row.is_admin == 1 ? '后台核销' : row.member?.nickname }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('operation')" align="right" fixed="right" width="100">
|
||||
<template #default="{ row }">
|
||||
@ -89,7 +91,7 @@ const recordTable = reactive({
|
||||
data: [],
|
||||
searchParam: {
|
||||
code: '',
|
||||
type: '',
|
||||
type: route.query.type || '',
|
||||
verifier_member_id: '',
|
||||
create_time: []
|
||||
}
|
||||
|
||||
130
admin/src/app/views/marketing/verify_index.vue
Normal file
130
admin/src/app/views/marketing/verify_index.vue
Normal file
@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<div class="main-container min-h-[300px]">
|
||||
<div class="">
|
||||
<el-card class="box-card mt-[10px]!border-none table-search-wrap" shadow="never">
|
||||
<div class="flex p-[10px] items-end">
|
||||
<div class="flex items-center w-[500px] h-[45px] border-[2px] border-primary rounded-l-lg">
|
||||
<span class="h-[15px] ml-[10px] pr-[10px] border-r-[1px] border-[#DEE1E7] leading-[1]">
|
||||
<img class="w-[15px]" src="@/app/assets/images/write.png" />
|
||||
</span>
|
||||
<input class="w-[400px] h-[40px] outline-none pl-[10px] text-[18px] bg-transparent"
|
||||
v-model="verifycode" />
|
||||
</div>
|
||||
<div class="bg-primary h-[45px] flex items-center px-[20px] rounded-[10px] ml-[10px] text-[#fff] cursor-pointer"
|
||||
@click="handelVerify">
|
||||
<span>{{ t("核销") }}</span>
|
||||
</div>
|
||||
<div class="bg-primary h-[45px] flex items-center px-[20px] rounded-[10px] ml-[10px] text-[#fff] cursor-pointer"
|
||||
@click="router.push('/marketing/verify')">
|
||||
<span>{{ t("核销记录") }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</el-card>
|
||||
</div>
|
||||
<el-dialog v-model="showDialog" :title="t('核销')" width="500px" :destroy-on-close="true">
|
||||
<div>
|
||||
<h3 class="panel-title !text-sm">{{ t('核销信息') }}</h3>
|
||||
<div class="flex items-center mt-[15px]">
|
||||
<span class="text-[14px] w-[130px] text-right mr-[20px]">{{ t('核销码') }}</span>
|
||||
<span class="text-[14px] text-[#666666]">
|
||||
{{verifycode}}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center mt-[15px]">
|
||||
<span class="text-[14px] w-[130px] text-right mr-[20px]">{{ t('核销类型') }}</span>
|
||||
<span class="text-[14px] text-[#666666]">
|
||||
{{ verifyInfo.type_name }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center mt-[15px]" v-for="(item,index) in verifyInfo.fixed" :key="index">
|
||||
<span class="text-[14px] w-[130px] text-right mr-[20px]">{{ item.title }}</span>
|
||||
<span class="text-[14px] text-[#666666]">
|
||||
{{ item.value }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="box-card mt-[15px] !border-none" shadow="never" v-for="(item,index) in verifyContentData.diy" :key="index">
|
||||
<h3 class="panel-title !text-sm">{{ item.title }}</h3>
|
||||
|
||||
<div class="flex items-center mt-[15px]" v-for="(subItem,subIndex) in item.list" :key="subIndex">
|
||||
<span class="text-[14px] w-[130px] text-right mr-[20px]">{{ subItem.title }}</span>
|
||||
<span class="text-[14px] text-[#666666]">
|
||||
{{ subItem.value }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-[15px]">
|
||||
<h3 class="panel-title !text-sm">{{ t('商品信息') }}</h3>
|
||||
<el-table :data="verifyGoodsList" size="large">
|
||||
<el-table-column :label="t('商品名称')" align="left" width="300">
|
||||
<template #default="{ row }">
|
||||
<div class="flex">
|
||||
<div class="flex items-center shrink-0">
|
||||
<el-image v-if="row.cover" class="w-[50px] h-[50px] mr-[10rpx]" :src="img(row.cover)" fit="contain">
|
||||
<template #error>
|
||||
<div class="image-slot">
|
||||
<img class="w-[50px] h-[50px] mr-[10rpx]" src="@/app/assets/images/goods_default.png" />
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
<img v-else class="w-[50px] h-[50px] mr-[10rpx]" src="@/app/assets/images/goods_default.png" fit="contain" />
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<p class="multi-hidden text-[14px]">{{ row.name }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="num" :label="t('数量')" min-width="50" align="right" />
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button type="primary" @click="verifyCode">{{ t("confirm") }}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang='ts' setup>
|
||||
import { ref } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import {img} from '@/utils/common'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { getVerifyDetailInfo ,verify} from '@/app/api/verify'
|
||||
|
||||
const router = useRouter()
|
||||
const loading = ref(false)
|
||||
const verifycode = ref('')
|
||||
const verifyInfo = ref<any>([])
|
||||
const verifyContentData: any = ref({})
|
||||
const verifyGoodsList: any = ref([])
|
||||
const showDialog = ref(false)
|
||||
const handelVerify = () => {
|
||||
if (verifycode.value == '') return
|
||||
getVerifyDetailInfo(verifycode.value).then((res) => {
|
||||
showDialog.value = true
|
||||
verifyInfo.value = res.data
|
||||
verifyContentData.value = res.data.value.content || {}
|
||||
verifyGoodsList.value = res.data.value.list || []
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
const isSubmit = ref(false)
|
||||
const verifyCode = () => {
|
||||
if (verifycode.value == '') return
|
||||
if (isSubmit.value) return
|
||||
isSubmit.value = true
|
||||
verify(verifycode.value).then(() => {
|
||||
showDialog.value = false
|
||||
isSubmit.value = false
|
||||
}).catch(() => {
|
||||
isSubmit.value = false
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@ -46,7 +46,7 @@
|
||||
<el-form :inline="true" :model="memberAccountLogTableData.searchParam" ref="searchFormRef">
|
||||
|
||||
<el-form-item :label="t('memberInfo')" prop="keywords">
|
||||
<el-input v-model.trim="memberAccountLogTableData.searchParam.keywords" class="w-[240px]" :placeholder="t('memberInfoPlaceholder')" />
|
||||
<el-input v-model.trim="memberAccountLogTableData.searchParam.keywords" class="!w-[200px]" :placeholder="t('memberInfoPlaceholder')" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('balanceType')" prop="balance_type">
|
||||
@ -257,9 +257,9 @@ checkBalanceInfo()
|
||||
const balanceStatus = ref([])
|
||||
const checkBalanceStatus = () => {
|
||||
getBalanceStatus().then(res => {
|
||||
for (var i in res.data) {
|
||||
for (const i in res.data) {
|
||||
if (i == 'balance' || i == 'money') {
|
||||
balanceStatus.value.push({ 'name': res.data[i], 'type': i })
|
||||
balanceStatus.value.push({ name: res.data[i], type: i })
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -55,7 +55,7 @@
|
||||
<el-card class="box-card !border-none mb-[10px] table-search-wrap" shadow="never">
|
||||
<el-form :inline="true" :model="memberAccountLogTableData.searchParam" ref="searchFormRef">
|
||||
<el-form-item :label="t('memberInfo')" prop="keywords">
|
||||
<el-input v-model.trim="memberAccountLogTableData.searchParam.keywords" class="w-[240px]" :placeholder="t('memberInfoPlaceholder')" />
|
||||
<el-input v-model.trim="memberAccountLogTableData.searchParam.keywords" class="!w-[200px]" :placeholder="t('memberInfoPlaceholder')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('fromType')" prop="from_type">
|
||||
<el-select v-model="memberAccountLogTableData.searchParam.from_type" clearable :placeholder="t('fromTypePlaceholder')" class="input-width">
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('mobile')" prop="mobile">
|
||||
<el-input v-model.trim="formData.mobile" clearable :placeholder="t('mobilePlaceholder')" @keyup="filterNumber($event)" class="input-width" />
|
||||
<el-input v-model.trim="formData.mobile" clearable :placeholder="t('mobilePlaceholder')" maxlength="11" @keyup="filterNumber($event)" class="input-width" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('nickname')">
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-drawer v-model="showDialog" :title="popTitle" direction="rtl" :before-close="handleClose" class="member-detail-drawer">
|
||||
<el-drawer v-model="showDialog" :title="popTitle" direction="rtl" :before-close="handleClose" class="member-detail-drawer" size="1300px">
|
||||
<div class="main-container" v-loading="loading">
|
||||
<div class="bg-page py-[20px] pr-[30px] relative flex">
|
||||
<div class="member-info w-[250px]">
|
||||
@ -375,17 +375,20 @@ const getMemberInfoFn = async (bool=false) => {
|
||||
Object.keys(data).forEach((item) => {
|
||||
formData[item] = data[item]
|
||||
})
|
||||
|
||||
if(!data.member_label_array){
|
||||
formData.member_label_array =[]
|
||||
formData.member_label_name=''
|
||||
}
|
||||
if (formData?.member_label_array && Object.keys(formData.member_label_array)?.length) {
|
||||
formData.member_label = Object.values(formData.member_label_array).map((item: any, index) => {
|
||||
return item.label_id
|
||||
})
|
||||
|
||||
|
||||
formData.member_label_name = Object.values(formData.member_label_array).map((item: any, index) => {
|
||||
return item.label_name
|
||||
})
|
||||
}
|
||||
loading.value = false
|
||||
loading.value = false
|
||||
} else {
|
||||
loading.value = false
|
||||
}
|
||||
@ -397,7 +400,7 @@ const getMemberInfoFn = async (bool=false) => {
|
||||
const setFormData = async (row: any = null) => {
|
||||
id = row.id;
|
||||
Object.assign(formData, initialFormData)
|
||||
getMemberInfoFn(true);
|
||||
await getMemberInfoFn(true);
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
@ -406,8 +409,4 @@ defineExpose({
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.member-detail-drawer{
|
||||
width: 1300px !important;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<el-dialog v-model="showDialog" :title="title || t('updateMember')" width="500px" :destroy-on-close="true">
|
||||
|
||||
<el-form :model="saveData" label-width="90px" :rules="formRules" ref="formRef" class="page-form" v-loading="loading">
|
||||
<el-form :model="saveData" label-width="90px" :rules="formRules" ref="formRef" class="page-form" @submit.prevent v-loading="loading">
|
||||
<el-form-item :label="t('headimg')" v-if="type == 'headimg'">
|
||||
<upload-image v-model="saveData.headimg" />
|
||||
</el-form-item>
|
||||
@ -23,7 +23,7 @@
|
||||
<el-form-item :label="t('sex')" v-if="type == 'sex'">
|
||||
<el-select v-model="saveData.sex" clearable :placeholder="t('sexPlaceholder')" class="input-width">
|
||||
<el-option :label="item['name']" :value="item['id']" v-for="(item,index) in sexSelectData" :key="index" />
|
||||
</el-select>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('memberLabel')" v-if="type == 'member_label'">
|
||||
<el-select v-model="saveData.member_label" multiple collapse-tags :placeholder="t('memberLabelPlaceholder')" class="input-width">
|
||||
@ -33,7 +33,7 @@
|
||||
<div v-if="type == 'member_level'">
|
||||
<el-form-item :label="t('memberLevelUpdate')" prop="member_level">
|
||||
<el-select v-model="saveData.member_level" :placeholder="t('memberLevelPlaceholder')" clearable class="input-width">
|
||||
<el-option :label="t('memberLevelPlaceholder')" :value="0" />
|
||||
<!-- <el-option :label="t('memberLevelPlaceholder')" :value="0" /> -->
|
||||
<el-option :label="item['level_name']" :value="item['level_id']" v-for="(item,index) in levelSelectData" :key="index"/>
|
||||
</el-select>
|
||||
<div class="text-sm text-gray-400">{{ t('memberLevelUpdateTips') }}</div>
|
||||
@ -56,7 +56,7 @@ import { ref, reactive, computed } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { deepClone } from '@/utils/common'
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { editMemberDetail, getMemberLabelAll, getMemberLevelAll,memberBatchModify } from '@/app/api/member'
|
||||
import { editMemberDetail, getMemberLabelAll, getMemberLevelAll, memberBatchModify } from '@/app/api/member'
|
||||
import Test from '@/utils/test'
|
||||
|
||||
// 修改类型
|
||||
@ -99,34 +99,34 @@ const formRules = computed(() => {
|
||||
return {
|
||||
mobile: [
|
||||
{
|
||||
validator(rule, value, callback) {
|
||||
validator (rule, value, callback) {
|
||||
// 允许为空,直接通过验证
|
||||
if (!value) return callback();
|
||||
|
||||
// 非空值时,验证手机号格式
|
||||
const reg = /^1[3-9]\d{9}$/;
|
||||
if (!reg.test(value)) {
|
||||
callback(new Error('请输入正确的手机号'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
if (!value) return callback()
|
||||
|
||||
// 非空值时,验证手机号格式
|
||||
const reg = /^1[3-9]\d{9}$/
|
||||
if (!reg.test(value)) {
|
||||
callback(new Error('请输入正确的手机号'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
id_card:[
|
||||
id_card: [
|
||||
{
|
||||
validator(rule, value, callback) {
|
||||
validator (rule, value, callback) {
|
||||
// 允许为空,直接通过验证
|
||||
if (!value) return callback();
|
||||
if (!value) return callback()
|
||||
|
||||
// 非空值时,验证身份证号格式
|
||||
const reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
|
||||
if (!reg.test(value)) {
|
||||
callback(new Error('请输入正确的身份证号'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
// 非空值时,验证身份证号格式
|
||||
const reg = /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/
|
||||
if (!reg.test(value)) {
|
||||
callback(new Error('请输入正确的身份证号'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
@ -171,10 +171,10 @@ const confirm = async (formEl: FormInstance | undefined) => {
|
||||
if (repeat.value) return
|
||||
repeat.value = true
|
||||
|
||||
let val = saveData[type.value];
|
||||
if(type.value == 'member_label'){
|
||||
let val = saveData[type.value]
|
||||
if (type.value == 'member_label') {
|
||||
// 将saveData[type.value]中的值,转换为字符串
|
||||
val = saveData[type.value] && saveData[type.value].length ? deepClone(saveData[type.value]).join(',').split(',') : '';
|
||||
val = saveData[type.value] && saveData[type.value].length ? deepClone(saveData[type.value]).join(',').split(',') : ''
|
||||
}
|
||||
|
||||
const data = ref({
|
||||
@ -204,19 +204,18 @@ const setDialogType = async (row: any = null) => {
|
||||
saveData[type.value] = row.data[type.value]
|
||||
if (type.value == 'member_label' && saveData[type.value]) {
|
||||
saveData[type.value].forEach((item: any, index: any) => {
|
||||
let isExist = false;
|
||||
let isExist = false
|
||||
for (let i = 0; i < labelSelectData.value.length; i++) {
|
||||
if (labelSelectData.value[i].label_id == item) {
|
||||
isExist = true;
|
||||
break;
|
||||
isExist = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (isExist) {
|
||||
saveData[type.value][index] = Number.parseFloat(item)
|
||||
} else {
|
||||
saveData[type.value].splice(index, 1); // 删除不存在的id
|
||||
saveData[type.value].splice(index, 1) // 删除不存在的id
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
loading.value = false
|
||||
@ -229,9 +228,9 @@ const batchInfo = ref({
|
||||
ids: [],
|
||||
where: {}
|
||||
})
|
||||
const batchSetDialogType = (data)=>{
|
||||
const batchSetDialogType = (data) => {
|
||||
loading.value = true
|
||||
type.value =data.type
|
||||
type.value = data.type
|
||||
method.value = data.method
|
||||
batchInfo.value.is_all = data.data.is_all
|
||||
batchInfo.value.ids = data.data.ids
|
||||
@ -249,14 +248,14 @@ const batchSetConfirm = async (formEl: FormInstance | undefined) => {
|
||||
if (repeat.value) return
|
||||
repeat.value = true
|
||||
|
||||
let val = saveData[type.value];
|
||||
if(type.value == 'member_label'){
|
||||
val = saveData[type.value] && saveData[type.value].length ? deepClone(saveData[type.value]).join(',').split(',') : '';
|
||||
let val = saveData[type.value]
|
||||
if (type.value == 'member_label') {
|
||||
val = saveData[type.value] && saveData[type.value].length ? deepClone(saveData[type.value]).join(',').split(',') : ''
|
||||
}
|
||||
|
||||
const data = ref({
|
||||
is_all: batchInfo.value.is_all,
|
||||
member_ids:batchInfo.value.ids,
|
||||
member_ids: batchInfo.value.ids,
|
||||
where: batchInfo.value.where,
|
||||
field: type.value,
|
||||
value: val
|
||||
|
||||
@ -48,9 +48,9 @@
|
||||
|
||||
<div class="mt-[10px]">
|
||||
<div class="mb-[10px] flex items-center">
|
||||
<el-dropdown class="mr-[20px] !text-primary">
|
||||
<el-dropdown class="mr-[20px] !text-primary w-[125px]">
|
||||
<span class="el-dropdown-link">
|
||||
<span>{{ currentSelectMode === 'all' ? t('全选所有页') : t('全选当前页')}}</span>({{ selectedCount }})
|
||||
<span>{{ currentSelectMode === 'all' ? t('全选所有页') : t('全选当前页')}}</span>(<span class="text-center inline-block">{{ selectedCount }}</span>)
|
||||
<el-icon>
|
||||
<arrow-down />
|
||||
</el-icon>
|
||||
|
||||
@ -386,7 +386,7 @@ const back = () => {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.member-info {
|
||||
left: 0px
|
||||
left: 0
|
||||
}
|
||||
|
||||
.member-info-item {
|
||||
|
||||
@ -35,7 +35,7 @@
|
||||
<el-card class="box-card !border-none mb-[10px] table-search-wrap" shadow="never">
|
||||
<el-form :inline="true" :model="memberAccountLogTableData.searchParam" ref="searchFormRef">
|
||||
<el-form-item :label="t('memberInfo')" prop="keywords">
|
||||
<el-input v-model.trim="memberAccountLogTableData.searchParam.keywords" class="w-[240px]" :placeholder="t('memberInfoPlaceholder')" />
|
||||
<el-input v-model.trim="memberAccountLogTableData.searchParam.keywords" class="!w-[200px]" :placeholder="t('memberInfoPlaceholder')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('fromType')" prop="from_type">
|
||||
<el-select v-model="memberAccountLogTableData.searchParam.from_type" clearable :placeholder="t('fromTypePlaceholder')" class="input-width">
|
||||
|
||||
@ -13,18 +13,18 @@ const prop = defineProps({
|
||||
})
|
||||
|
||||
const data = computed(() => {
|
||||
return prop.value;
|
||||
return prop.value
|
||||
})
|
||||
|
||||
const componentStyle = computed(() => {
|
||||
var style = '';
|
||||
style += `background-color: ${ prop.value.bgColor };`;
|
||||
style += `width: ${ prop.value.width }px;height: ${ prop.value.height }px;`;
|
||||
let box: any = document.getElementById(prop.value.id)
|
||||
let style = ''
|
||||
style += `background-color: ${prop.value.bgColor};`
|
||||
style += `width: ${prop.value.width}px;height: ${prop.value.height}px;`
|
||||
const box: any = document.getElementById(prop.value.id)
|
||||
if (box) {
|
||||
style += `width:${ box.offsetWidth }px;height:${ box.offsetHeight }px;`;
|
||||
style += `width:${box.offsetWidth}px;height:${box.offsetHeight}px;`
|
||||
}
|
||||
return style;
|
||||
return style
|
||||
})
|
||||
|
||||
defineExpose({})
|
||||
|
||||
@ -16,28 +16,28 @@ const prop = defineProps({
|
||||
})
|
||||
|
||||
const data = computed(() => {
|
||||
return prop.value;
|
||||
return prop.value
|
||||
})
|
||||
|
||||
const componentStyle = computed(() => {
|
||||
var style = '';
|
||||
style += `font-size: ${ prop.value.fontSize }px;color: ${ prop.value.fontColor };line-height: ${ prop.value.lineHeight + prop.value.fontSize }px;`;
|
||||
let style = ''
|
||||
style += `font-size: ${prop.value.fontSize}px;color: ${prop.value.fontColor};line-height: ${prop.value.lineHeight + prop.value.fontSize}px;`
|
||||
if (prop.value.x == 'left' || prop.value.x == 'center' || prop.value.x == 'right') {
|
||||
style += `text-align: ${ prop.value.x };`;
|
||||
style += `text-align: ${prop.value.x};`
|
||||
}
|
||||
if (prop.value.weight) {
|
||||
style += `font-weight: bold;`;
|
||||
style += 'font-weight: bold;'
|
||||
}
|
||||
if (!prop.value.fontFamily || prop.value.fontFamily == 'static/font/SourceHanSansCN-Regular.ttf') {
|
||||
style += `font-family: poster_default_font;`;
|
||||
if (!prop.value.fontFamily || prop.value.fontFamily == 'static/font/PingFang-Medium.ttf') {
|
||||
style += 'font-family: poster_default_font;'
|
||||
}
|
||||
let box: any = document.getElementById(prop.value.id)
|
||||
const box: any = document.getElementById(prop.value.id)
|
||||
if (box) {
|
||||
style += `width:${ box.offsetWidth }px;height:${ box.offsetHeight }px;`;
|
||||
style += `width:${box.offsetWidth}px;height:${box.offsetHeight}px;`
|
||||
} else {
|
||||
style += `width:${ prop.value.width }px;height:${ prop.value.height }px;`;
|
||||
style += `width:${prop.value.width}px;height:${prop.value.height}px;`
|
||||
}
|
||||
return style;
|
||||
return style
|
||||
})
|
||||
|
||||
defineExpose({})
|
||||
|
||||
@ -16,28 +16,28 @@ const prop = defineProps({
|
||||
})
|
||||
|
||||
const data = computed(() => {
|
||||
return prop.value;
|
||||
return prop.value
|
||||
})
|
||||
|
||||
const componentStyle = computed(() => {
|
||||
var style = '';
|
||||
style += `font-size: ${ prop.value.fontSize }px;color: ${ prop.value.fontColor };line-height: ${ prop.value.lineHeight + prop.value.fontSize }px;`;
|
||||
let style = ''
|
||||
style += `font-size: ${prop.value.fontSize}px;color: ${prop.value.fontColor};line-height: ${prop.value.lineHeight + prop.value.fontSize}px;`
|
||||
if (prop.value.x == 'left' || prop.value.x == 'center' || prop.value.x == 'right') {
|
||||
style += `text-align: ${ prop.value.x };`;
|
||||
style += `text-align: ${prop.value.x};`
|
||||
}
|
||||
if (prop.value.weight) {
|
||||
style += `font-weight: bold;`;
|
||||
style += 'font-weight: bold;'
|
||||
}
|
||||
if (!prop.value.fontFamily || prop.value.fontFamily == 'static/font/SourceHanSansCN-Regular.ttf') {
|
||||
style += `font-family: poster_default_font;`;
|
||||
if (!prop.value.fontFamily || prop.value.fontFamily == 'static/font/PingFang-Medium.ttf') {
|
||||
style += 'font-family: poster_default_font;'
|
||||
}
|
||||
let box: any = document.getElementById(prop.value.id)
|
||||
const box: any = document.getElementById(prop.value.id)
|
||||
if (box) {
|
||||
style += `width:${ box.offsetWidth }px;height:${ box.offsetHeight }px;`;
|
||||
style += `width:${box.offsetWidth}px;height:${box.offsetHeight}px;`
|
||||
} else {
|
||||
style += `width:${ prop.value.width }px;height:${ prop.value.height }px;`;
|
||||
style += `width:${prop.value.width}px;height:${prop.value.height}px;`
|
||||
}
|
||||
return style;
|
||||
return style
|
||||
})
|
||||
|
||||
defineExpose({})
|
||||
|
||||
@ -16,16 +16,16 @@ const prop = defineProps({
|
||||
})
|
||||
|
||||
const data = computed(() => {
|
||||
return prop.value;
|
||||
return prop.value
|
||||
})
|
||||
|
||||
const componentStyle = computed(() => {
|
||||
var style = '';
|
||||
style += `width: ${ prop.value.width }px;`;
|
||||
let style = ''
|
||||
style += `width: ${prop.value.width}px;`
|
||||
if (prop.value.shape == 'circle') {
|
||||
style += `border-radius: 50%; overflow: hidden;`;
|
||||
style += 'border-radius: 50%; overflow: hidden;'
|
||||
}
|
||||
return style;
|
||||
return style
|
||||
})
|
||||
|
||||
defineExpose({})
|
||||
|
||||
@ -17,13 +17,13 @@ const prop = defineProps({
|
||||
})
|
||||
|
||||
const data = computed(() => {
|
||||
return prop.value;
|
||||
return prop.value
|
||||
})
|
||||
|
||||
const componentStyle = computed(() => {
|
||||
var style = '';
|
||||
style += `width: ${ prop.value.width }px;`;
|
||||
return style;
|
||||
let style = ''
|
||||
style += `width: ${prop.value.width}px;`
|
||||
return style
|
||||
})
|
||||
|
||||
defineExpose({})
|
||||
|
||||
@ -16,28 +16,28 @@ const prop = defineProps({
|
||||
})
|
||||
|
||||
const data = computed(() => {
|
||||
return prop.value;
|
||||
return prop.value
|
||||
})
|
||||
|
||||
const componentStyle = computed(() => {
|
||||
var style = '';
|
||||
style += `font-size: ${ prop.value.fontSize }px;color: ${ prop.value.fontColor };line-height: ${ prop.value.lineHeight + prop.value.fontSize }px;`;
|
||||
let style = ''
|
||||
style += `font-size: ${prop.value.fontSize}px;color: ${prop.value.fontColor};line-height: ${prop.value.lineHeight + prop.value.fontSize}px;`
|
||||
if (prop.value.x == 'left' || prop.value.x == 'center' || prop.value.x == 'right') {
|
||||
style += `text-align: ${ prop.value.x };`;
|
||||
style += `text-align: ${prop.value.x};`
|
||||
}
|
||||
if (prop.value.weight) {
|
||||
style += `font-weight: bold;`;
|
||||
style += 'font-weight: bold;'
|
||||
}
|
||||
if (!prop.value.fontFamily || prop.value.fontFamily == 'static/font/SourceHanSansCN-Regular.ttf') {
|
||||
style += `font-family: poster_default_font;`;
|
||||
if (!prop.value.fontFamily || prop.value.fontFamily == 'static/font/PingFang-Medium.ttf') {
|
||||
style += 'font-family: poster_default_font;'
|
||||
}
|
||||
let box: any = document.getElementById(prop.value.id)
|
||||
const box: any = document.getElementById(prop.value.id)
|
||||
if (box) {
|
||||
style += `width:${ box.offsetWidth }px;height:${ box.offsetHeight }px;`;
|
||||
style += `width:${box.offsetWidth}px;height:${box.offsetHeight}px;`
|
||||
} else {
|
||||
style += `width:${ prop.value.width }px;height:${ prop.value.height }px;`;
|
||||
style += `width:${prop.value.width}px;height:${prop.value.height}px;`
|
||||
}
|
||||
return style;
|
||||
return style
|
||||
})
|
||||
|
||||
defineExpose({})
|
||||
|
||||
@ -20,7 +20,7 @@ const data = computed(() => {
|
||||
})
|
||||
|
||||
const componentStyle = computed(() => {
|
||||
var style = '';
|
||||
let style = '';
|
||||
style += `width: ${ prop.value.width }px;`;
|
||||
return style;
|
||||
})
|
||||
|
||||
@ -20,7 +20,7 @@ const data = computed(() => {
|
||||
})
|
||||
|
||||
const componentStyle = computed(() => {
|
||||
var style = '';
|
||||
let style = '';
|
||||
style += `font-size: ${ prop.value.fontSize }px;color: ${ prop.value.fontColor };line-height: ${ prop.value.lineHeight + prop.value.fontSize }px;`;
|
||||
if (prop.value.x == 'left' || prop.value.x == 'center' || prop.value.x == 'right') {
|
||||
style += `text-align: ${ prop.value.x };`;
|
||||
@ -28,7 +28,7 @@ const componentStyle = computed(() => {
|
||||
if (prop.value.weight) {
|
||||
style += `font-weight: bold;`;
|
||||
}
|
||||
if (!prop.value.fontFamily || prop.value.fontFamily == 'static/font/SourceHanSansCN-Regular.ttf') {
|
||||
if (!prop.value.fontFamily || prop.value.fontFamily == 'static/font/PingFang-Medium.ttf') {
|
||||
style += `font-family: poster_default_font;`;
|
||||
}
|
||||
let box: any = document.getElementById(prop.value.id)
|
||||
|
||||
@ -6,7 +6,13 @@
|
||||
<span class="text-page-title">{{ pageName }}</span>
|
||||
<el-button type="primary" class="w-[100px]" @click="dialogVisible = true">{{ t('添加海报') }}</el-button>
|
||||
</div>
|
||||
|
||||
<div class="mt-[20px]" v-if="!isImagick">
|
||||
<el-alert type="warning" show-icon :closable="false">
|
||||
<template #title>
|
||||
<span class="!text-[14px]">检测到PHP未安装ImageMagick扩展,需安装后才能使用海报功能</span>
|
||||
</template>
|
||||
</el-alert>
|
||||
</div>
|
||||
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
|
||||
<el-form :inline="true" :model="posterTableData.searchParam" ref="searchFormDiyPosterRef">
|
||||
<el-form-item :label="t('posterName')" prop="name">
|
||||
@ -103,8 +109,8 @@ import { reactive, ref, computed } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { ElMessageBox, FormInstance } from 'element-plus'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { getPosterPageList,getPosterType,modifyPosterStatus,modifyPosterDefault,deletePoster,getPreviewPoster } from '@/app/api/poster'
|
||||
import { img,setTablePageStorage,getTablePageStorage } from '@/utils/common'
|
||||
import { getPosterPageList, getPosterType, modifyPosterStatus, modifyPosterDefault, deletePoster, getPreviewPoster ,checkImagick} from '@/app/api/poster'
|
||||
import { img, setTablePageStorage, getTablePageStorage } from '@/utils/common'
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
@ -151,10 +157,10 @@ const addEvent = async (formEl: FormInstance | undefined) => {
|
||||
}
|
||||
|
||||
// 获取自定义海报类型
|
||||
const loadPosterType = ()=> {
|
||||
getPosterType({}).then((res:any)=>{
|
||||
for (let key in posterType) {
|
||||
delete posterType[key];
|
||||
const loadPosterType = () => {
|
||||
getPosterType({}).then((res:any) => {
|
||||
for (const key in posterType) {
|
||||
delete posterType[key]
|
||||
}
|
||||
|
||||
for (const key in res.data) {
|
||||
@ -163,7 +169,7 @@ const loadPosterType = ()=> {
|
||||
})
|
||||
}
|
||||
|
||||
loadPosterType();
|
||||
loadPosterType()
|
||||
|
||||
const posterTableData: any = reactive({
|
||||
page: 1,
|
||||
@ -192,13 +198,13 @@ const loadPosterPageList = (page: number = 1) => {
|
||||
posterTableData.loading = false
|
||||
posterTableData.data = res.data.data
|
||||
posterTableData.total = res.data.total
|
||||
setTablePageStorage(posterTableData.page, posterTableData.limit, posterTableData.searchParam);
|
||||
setTablePageStorage(posterTableData.page, posterTableData.limit, posterTableData.searchParam)
|
||||
}).catch(() => {
|
||||
posterTableData.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
loadPosterPageList(getTablePageStorage(posterTableData.searchParam).page);
|
||||
loadPosterPageList(getTablePageStorage(posterTableData.searchParam).page)
|
||||
|
||||
// 编辑自定义海报
|
||||
const editEvent = (data: any) => {
|
||||
@ -212,7 +218,7 @@ const editEvent = (data: any) => {
|
||||
const isRepeat = ref(false)
|
||||
|
||||
// 修改海报启用状态
|
||||
const modifyPosterStatusFn = (id:any,status:any)=> {
|
||||
const modifyPosterStatusFn = (id:any, status:any) => {
|
||||
if (isRepeat.value) return
|
||||
isRepeat.value = true
|
||||
|
||||
@ -225,7 +231,7 @@ const modifyPosterStatusFn = (id:any,status:any)=> {
|
||||
}
|
||||
|
||||
// 将自定义海报修改为默认海报
|
||||
const modifyPosterDefaultFn = (id:any)=> {
|
||||
const modifyPosterDefaultFn = (id:any) => {
|
||||
if (isRepeat.value) return
|
||||
isRepeat.value = true
|
||||
modifyPosterDefault({
|
||||
@ -265,16 +271,15 @@ const previewPoster = (data: any) => {
|
||||
isRepeat.value = true
|
||||
|
||||
getPreviewPoster({
|
||||
id:data.id,
|
||||
type:data.type
|
||||
}).then(((res:any)=>{
|
||||
if(res.data) {
|
||||
previewPosterUrl.value = res.data;
|
||||
previewDialogVisible.value = true;
|
||||
id: data.id,
|
||||
type: data.type
|
||||
}).then((res:any) => {
|
||||
if (res.data) {
|
||||
previewPosterUrl.value = res.data
|
||||
previewDialogVisible.value = true
|
||||
}
|
||||
isRepeat.value = false
|
||||
}))
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
const resetForm = (formEl: FormInstance | undefined) => {
|
||||
@ -282,6 +287,16 @@ const resetForm = (formEl: FormInstance | undefined) => {
|
||||
formEl.resetFields()
|
||||
loadPosterPageList()
|
||||
}
|
||||
const isImagick = ref(false)
|
||||
// 判断是否安装imagemagick扩展
|
||||
const checkImagickFn = () => {
|
||||
checkImagick().then((res:any) => {
|
||||
console.log(res)
|
||||
isImagick.value = res.data
|
||||
|
||||
})
|
||||
}
|
||||
checkImagickFn()
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
@ -68,14 +68,14 @@
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getPrinterPageList, modifyPrinterStatus, deletePrinter,refreshPrinterToken,testPrint } from '@/app/api/printer'
|
||||
import { ElMessageBox,FormInstance } from 'element-plus'
|
||||
import { useRoute,useRouter } from 'vue-router'
|
||||
import { setTablePageStorage,getTablePageStorage } from "@/utils/common";
|
||||
import { getPrinterPageList, modifyPrinterStatus, deletePrinter, refreshPrinterToken, testPrint } from '@/app/api/printer'
|
||||
import { ElMessageBox, FormInstance } from 'element-plus'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { setTablePageStorage, getTablePageStorage } from '@/utils/common'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const pageName = route.meta.title;
|
||||
const pageName = route.meta.title
|
||||
const repeat = ref(false)
|
||||
|
||||
const handleClick = (path: string) => {
|
||||
@ -110,7 +110,7 @@ const loadPrinterList = (page: number = 1) => {
|
||||
printerTable.loading = false
|
||||
printerTable.data = res.data.data
|
||||
printerTable.total = res.data.total
|
||||
setTablePageStorage(printerTable.page, printerTable.limit, printerTable.searchParam);
|
||||
setTablePageStorage(printerTable.page, printerTable.limit, printerTable.searchParam)
|
||||
}).catch(() => {
|
||||
printerTable.loading = false
|
||||
})
|
||||
@ -154,11 +154,11 @@ const editEvent = (data: any) => {
|
||||
*/
|
||||
const deleteEvent = (id: number) => {
|
||||
ElMessageBox.confirm(t('printerDeleteTips'), t('warning'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning',
|
||||
}
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning'
|
||||
}
|
||||
).then(() => {
|
||||
if (repeat.value) return
|
||||
repeat.value = true
|
||||
@ -183,11 +183,11 @@ const resetForm = (formEl: FormInstance | undefined) => {
|
||||
*/
|
||||
const testPrintEvent = (printer_id: any) => {
|
||||
ElMessageBox.confirm(t('testPrintTips'), t('warning'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning',
|
||||
}
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning'
|
||||
}
|
||||
).then(() => {
|
||||
if (repeat.value) return
|
||||
repeat.value = true
|
||||
@ -205,11 +205,11 @@ const testPrintEvent = (printer_id: any) => {
|
||||
*/
|
||||
const refreshTokenEvent = (printer_id: any) => {
|
||||
ElMessageBox.confirm(t('refreshTokenTips'), t('warning'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning',
|
||||
}
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning'
|
||||
}
|
||||
).then(() => {
|
||||
if (repeat.value) return
|
||||
repeat.value = true
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
|
||||
<el-form class="page-form" :model="formData" label-width="150px" ref="ruleFormRef" v-loading="loading">
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
<h3 class="panel-title !text-sm">{{ t('admin') }}</h3>
|
||||
|
||||
<h3 class="text-[16px] text-[#1D1F3A] font-bold mb-4">{{ pageName }}</h3>
|
||||
<h3 class="panel-title !text-[14px] bg-[#F4F5F7] p-3 border-[#E6E6E6] border-solid border-b-[1px]">{{ t('admin') }}</h3>
|
||||
<el-form-item :label="t('isCaptcha')">
|
||||
<el-switch v-model="formData.is_captcha" :active-value="1" :inactive-value="0" />
|
||||
</el-form-item>
|
||||
@ -12,8 +12,8 @@
|
||||
<upload-image v-model="formData.bg" />
|
||||
<div class="form-tip">{{t('adminBgImgTip')}}</div>
|
||||
</el-form-item>
|
||||
</el-card>
|
||||
|
||||
</el-card>
|
||||
</el-form>
|
||||
|
||||
<div class="fixed-footer-wrap">
|
||||
@ -29,12 +29,11 @@ import { reactive, ref } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getConfigLogin, setConfigLogin } from '@/app/api/sys'
|
||||
import { FormInstance } from 'element-plus'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const route = useRoute()
|
||||
const pageName = route.meta.title
|
||||
|
||||
const loading = ref(true)
|
||||
const ruleFormRef = ref<FormInstance>()
|
||||
const formData = reactive<Record<string, number | string>>({
|
||||
|
||||
@ -25,7 +25,11 @@
|
||||
<el-form-item :label="t('createTime')">
|
||||
<div class="input-width"> {{ formData.create_time }} </div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('发送结果')">
|
||||
<div class="input-width" v-if="formData.status == 'sending'"> 发送失败 </div>
|
||||
<div class="input-width" v-if="formData.status == 'success'"> 发送成功 </div>
|
||||
<div class="input-width" v-if="formData.status == 'fail'"> {{ formData.result }} </div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
@ -55,7 +59,9 @@ const initialFormData = {
|
||||
name: '',
|
||||
nickname: '',
|
||||
mobile: '',
|
||||
sms_type_name: ''
|
||||
sms_type_name: '',
|
||||
status:'',
|
||||
result:''
|
||||
}
|
||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||
|
||||
|
||||
@ -53,8 +53,8 @@ const initialFormData = {
|
||||
access_key: '',
|
||||
secret_key: '',
|
||||
is_use: '',
|
||||
app_id:'',
|
||||
secret_id:'',
|
||||
app_id: '',
|
||||
secret_id: ''
|
||||
}
|
||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<el-card class="box-card !border-none" shadow="never" v-loading="loading">
|
||||
<div v-if="type=='login'" >
|
||||
<div class="bg-[var(--el-color-primary-light-9)] p-2 text-[14px] rounded-[6px]">
|
||||
<span class="">还未注册牛云短信?</span>
|
||||
<span>还未注册牛云短信?</span>
|
||||
<span @click="toRegister" class="cursor-pointer text-primary">去注册</span>
|
||||
</div>
|
||||
<el-form :model="formData" label-width="150px" ref="formRef" :rules="formRules" class="page-form mt-[20px]">
|
||||
@ -21,7 +21,7 @@
|
||||
</div>
|
||||
<div v-if="type=='register'" >
|
||||
<div class="bg-[var(--el-color-primary-light-9)] p-2 text-[14px] rounded-[6px]">
|
||||
<span class="">已有账号,</span>
|
||||
<span>已有账号,</span>
|
||||
<span @click="type='login'" class="cursor-pointer text-primary">去登录</span>
|
||||
</div>
|
||||
<el-form :model="registerFormData" label-width="150px" ref="registerFormRef" :rules="registerFormRules" class="page-form mt-[20px]">
|
||||
@ -111,6 +111,9 @@
|
||||
<span class="text-primary">忘记密码,快去修改</span>
|
||||
</div>
|
||||
<el-form :model="changeFormData" label-width="150px" ref="changeFormRef" :rules="changeFormRules" class="page-form mt-[20px]">
|
||||
<el-form-item label="用户名" prop="username">
|
||||
<el-input placeholder="请输入用户名" class="input-width" maxlength="50" show-word-limit v-model="changeFormData.username" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号" prop="mobile">
|
||||
<el-input placeholder="请输入手机号" class="input-width" maxlength="11" show-word-limit v-model="changeFormData.mobile" clearable />
|
||||
</el-form-item>
|
||||
@ -139,16 +142,16 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref ,computed,reactive} from 'vue'
|
||||
import { loginAccount,getSmsCaptcha,getSmsSend,resetPassword,registerAccount ,getSmsSignConfig} from '@/app/api/notice'
|
||||
import { t } from "@/lang";
|
||||
import { ref, computed, reactive } from 'vue'
|
||||
import { loginAccount, getSmsCaptcha, getSmsSend, resetPassword, registerAccount, getSmsSignConfig } from '@/app/api/notice'
|
||||
import { t } from '@/lang'
|
||||
|
||||
const props = defineProps({
|
||||
info:{
|
||||
info: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
isLogin:{
|
||||
isLogin: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
@ -164,7 +167,7 @@ const formData = ref({
|
||||
})
|
||||
|
||||
const isBack = computed(() => {
|
||||
return !!props.info && Object.keys(props.info).length > 0;
|
||||
return !!props.info && Object.keys(props.info).length > 0
|
||||
})
|
||||
|
||||
const formRules = computed(() => {
|
||||
@ -194,9 +197,9 @@ const back = () => {
|
||||
// 注册
|
||||
const signConfig = reactive({
|
||||
signTypeList: [],
|
||||
signSourceList:[]
|
||||
signSourceList: []
|
||||
})
|
||||
const getSmsSignConfigFn = ()=> {
|
||||
const getSmsSignConfigFn = () => {
|
||||
getSmsSignConfig().then(res => {
|
||||
signConfig.signTypeList = res.data.sign_type_list
|
||||
signConfig.signSourceList = res.data.sign_source_list
|
||||
@ -263,39 +266,39 @@ const registerFormRules = computed(() => {
|
||||
}
|
||||
],
|
||||
mobile: [
|
||||
{ required: true, message: '请输入手机号', trigger: 'blur' },
|
||||
{ required: true, message: '请输入手机号', trigger: 'blur' }
|
||||
],
|
||||
captcha_code: [
|
||||
{ required: true, message: '请输入验证码', trigger: 'blur' },
|
||||
{ required: true, message: '请输入验证码', trigger: 'blur' }
|
||||
],
|
||||
code: [
|
||||
{ required: true, message: '请输入动态码', trigger: 'blur' },
|
||||
{ required: true, message: '请输入动态码', trigger: 'blur' }
|
||||
],
|
||||
company: [
|
||||
{ required: true, message: '请输入公司名称', trigger: 'blur' },
|
||||
{ required: true, message: '请输入公司名称', trigger: 'blur' }
|
||||
],
|
||||
signature: [
|
||||
{ required: true, message: '请输入短信签名', trigger: 'blur' },
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
const singleBracketValid = /^【[^【】]*】$/.test(value);
|
||||
const singleBracketValid = /^【[^【】]*】$/.test(value)
|
||||
if (!singleBracketValid) {
|
||||
return callback(new Error('短信签名必须被【】包裹'));
|
||||
return callback(new Error('短信签名必须被【】包裹'))
|
||||
}
|
||||
|
||||
const content = value.slice(1, -1);
|
||||
const content = value.slice(1, -1)
|
||||
|
||||
const lengthValid = content.length >= 2 && content.length <= 20;
|
||||
const lengthValid = content.length >= 2 && content.length <= 20
|
||||
if (!lengthValid) {
|
||||
return callback(new Error('短信签名内容需在 2-20 个字符之间'));
|
||||
return callback(new Error('短信签名内容需在 2-20 个字符之间'))
|
||||
}
|
||||
|
||||
const invalidChars = /[\s\-+=*&%#@~;]/;
|
||||
const invalidChars = /[\s\-+=*&%#@~;]/
|
||||
if (invalidChars.test(content)) {
|
||||
return callback(new Error('短信签名不能包含空格或特殊字符 - + = * & % # @ ~ ;'));
|
||||
return callback(new Error('短信签名不能包含空格或特殊字符 - + = * & % # @ ~ ;'))
|
||||
}
|
||||
|
||||
callback();
|
||||
callback()
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
@ -305,19 +308,19 @@ const registerFormRules = computed(() => {
|
||||
{ validator: phoneVerify, trigger: 'blur' }
|
||||
],
|
||||
companyName: [
|
||||
{ required: true, message: '请输入企业名称', trigger: 'blur' },
|
||||
{ required: true, message: '请输入企业名称', trigger: 'blur' }
|
||||
],
|
||||
contentExample: [
|
||||
{ required: true, message: '请输入短信示例内容', trigger: 'blur' },
|
||||
{ required: true, message: '请输入短信示例内容', trigger: 'blur' }
|
||||
],
|
||||
creditCode: [
|
||||
{ required: true, message: '请输入社会统一信用代码', trigger: 'blur' },
|
||||
{ required: true, message: '请输入社会统一信用代码', trigger: 'blur' }
|
||||
],
|
||||
legalPerson: [
|
||||
{ required: true, message: '请输入法人姓名', trigger: 'blur' },
|
||||
{ required: true, message: '请输入法人姓名', trigger: 'blur' }
|
||||
],
|
||||
principalName: [
|
||||
{ required: true, message: '请输入经办人姓名', trigger: 'blur' },
|
||||
{ required: true, message: '请输入经办人姓名', trigger: 'blur' }
|
||||
],
|
||||
principalIdCard: [
|
||||
{ required: true, message: '请输入经办人身份证', trigger: 'blur' },
|
||||
@ -326,22 +329,22 @@ const registerFormRules = computed(() => {
|
||||
imgUrl: [
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
const needImage = [3, 4, 5].includes(registerFormData.value.signSource) || registerFormData.value.signType == 1;
|
||||
const needImage = [3, 4, 5].includes(registerFormData.value.signSource) || registerFormData.value.signType == 1
|
||||
if (needImage) {
|
||||
if (!value || value.length === 0) {
|
||||
callback(new Error('请上传图片'));
|
||||
callback(new Error('请上传图片'))
|
||||
} else {
|
||||
callback();
|
||||
callback()
|
||||
}
|
||||
} else {
|
||||
callback(); // 不需要校验
|
||||
callback() // 不需要校验
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
const idCardVerify = (rule: any, value: any, callback: any) => {
|
||||
if (value && !/^[1-9]\d{5}(19|20)\d{2}((0\d)|(1[0-2]))(([0-2]\d)|3[0-1])\d{3}([0-9Xx])$/.test(value)) {
|
||||
callback(new Error(t('请输入正确的身份证号码')))
|
||||
@ -360,25 +363,26 @@ const phoneVerify = (rule: any, value: any, callback: any) => {
|
||||
const register = async () => {
|
||||
await registerFormRef.value?.validate(async (valid) => {
|
||||
if (valid) {
|
||||
const { captcha_key, captcha_code, captcha_img, ...params } = registerFormData.value;
|
||||
const { captcha_key, captcha_code, captcha_img, ...params } = registerFormData.value
|
||||
registerAccount(params).then((res) => {
|
||||
type.value='login'
|
||||
type.value = 'login'
|
||||
}).catch((err) => {
|
||||
getSmsCaptchaFn()
|
||||
})
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// 重置密码
|
||||
const changeFormRef = ref()
|
||||
const changeFormData = ref({
|
||||
mobile: '',
|
||||
captcha_key : '',
|
||||
captcha_key: '',
|
||||
captcha_code: '',
|
||||
captcha_img: '',
|
||||
code: '',
|
||||
key: ''
|
||||
key: '',
|
||||
username: props.info.username || '',
|
||||
})
|
||||
|
||||
const getSmsCaptchaFn = async () => {
|
||||
@ -398,11 +402,11 @@ const getSmsCaptchaFn = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
const sending = ref(false); // 发送中状态
|
||||
const countdown = ref(0); // 倒计时秒数
|
||||
const sending = ref(false) // 发送中状态
|
||||
const countdown = ref(0) // 倒计时秒数
|
||||
|
||||
const getSmsSendFn = () => {
|
||||
if (countdown.value > 0 || sending.value) return; // 正在倒计时或发送中,直接返回
|
||||
if (countdown.value > 0 || sending.value) return // 正在倒计时或发送中,直接返回
|
||||
if (type.value === 'register') {
|
||||
registerFormRef.value.validateField(['mobile', 'captcha_code'], (valid) => {
|
||||
if (!valid) return
|
||||
@ -413,13 +417,13 @@ const getSmsSendFn = () => {
|
||||
captcha_code: registerFormData.value.captcha_code
|
||||
}
|
||||
getSmsSend(params).then((res) => {
|
||||
startCountdown(60); // 启动60秒倒计时
|
||||
registerFormData.value.key = res.data.key;
|
||||
startCountdown(60) // 启动60秒倒计时
|
||||
registerFormData.value.key = res.data.key
|
||||
}).catch((err) => {
|
||||
getSmsCaptchaFn()
|
||||
sending.value = false;
|
||||
sending.value = false
|
||||
}).finally(() => {
|
||||
sending.value = false; // 无论成功失败都重置发送状态
|
||||
sending.value = false // 无论成功失败都重置发送状态
|
||||
})
|
||||
})
|
||||
} else if (type.value === 'password') {
|
||||
@ -433,28 +437,28 @@ const getSmsSendFn = () => {
|
||||
captcha_code: changeFormData.value.captcha_code
|
||||
}
|
||||
getSmsSend(params).then((res) => {
|
||||
startCountdown(60); // 启动60秒倒计时
|
||||
changeFormData.value.key = res.data.key;
|
||||
startCountdown(60) // 启动60秒倒计时
|
||||
changeFormData.value.key = res.data.key
|
||||
}).catch((err) => {
|
||||
getSmsCaptchaFn()
|
||||
sending.value = false;
|
||||
sending.value = false
|
||||
}).finally(() => {
|
||||
sending.value = false; // 无论成功失败都重置发送状态
|
||||
});
|
||||
});
|
||||
sending.value = false // 无论成功失败都重置发送状态
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 启动倒计时
|
||||
const startCountdown = (seconds) => {
|
||||
countdown.value = seconds;
|
||||
countdown.value = seconds
|
||||
const timer = setInterval(() => {
|
||||
countdown.value--;
|
||||
countdown.value--
|
||||
if (countdown.value <= 0) {
|
||||
clearInterval(timer);
|
||||
sending.value = false; // 发送状态重置
|
||||
clearInterval(timer)
|
||||
sending.value = false // 发送状态重置
|
||||
}
|
||||
}, 1000);
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
const changeFormRules = computed(() => {
|
||||
@ -468,13 +472,16 @@ const changeFormRules = computed(() => {
|
||||
}
|
||||
],
|
||||
captcha_code: [
|
||||
{ required: true, message: '请输入验证码', trigger: 'blur' },
|
||||
{ required: true, message: '请输入验证码', trigger: 'blur' }
|
||||
],
|
||||
code: [
|
||||
{ required: true, message: '请输入动态码', trigger: 'blur' },
|
||||
{ required: true, message: '请输入动态码', trigger: 'blur' }
|
||||
],
|
||||
username: [
|
||||
{ required: true, message: '请输入用户名', trigger: 'blur' }
|
||||
]
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
const editPass = async () => {
|
||||
loading.value = true
|
||||
captchaType.value = 'password'
|
||||
@ -488,16 +495,16 @@ const editPass = async () => {
|
||||
const reset = async () => {
|
||||
await changeFormRef.value?.validate(async (valid) => {
|
||||
if (valid) {
|
||||
let params = {
|
||||
const params = {
|
||||
key: changeFormData.value.key,
|
||||
code: changeFormData.value.code,
|
||||
mobile: changeFormData.value.mobile
|
||||
}
|
||||
resetPassword(props.info.username, { ...params }).then((res) => {
|
||||
let newPassword = res.data.password
|
||||
ElMessageBox.confirm(`新密码为:${ newPassword }`, '请保存好新密码', {
|
||||
resetPassword(changeFormData.value.username, { ...params }).then((res) => {
|
||||
const newPassword = res.data.password
|
||||
ElMessageBox.confirm(`新密码为:${newPassword}`, '请保存好新密码', {
|
||||
confirmButtonText: '确定',
|
||||
showCancelButton: false,
|
||||
showCancelButton: false
|
||||
}).then(() => {
|
||||
type.value = 'login'
|
||||
emit('complete')
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref ,watch} from 'vue'
|
||||
import { ref, watch } from 'vue'
|
||||
import { getSmsPackagesList, smsOrderCreate, getOrderPayInfo, getOrderPayStatus, calculateOrderPay } from '@/app/api/notice'
|
||||
|
||||
const props = defineProps({
|
||||
@ -100,7 +100,7 @@ const submitPayment = async () => {
|
||||
await ElMessageBox.confirm('请确认支付是否完成', '支付提示', {
|
||||
confirmButtonText: '已完成支付',
|
||||
cancelButtonText: '返回',
|
||||
type: 'warning',
|
||||
type: 'warning'
|
||||
})
|
||||
emit('complete')
|
||||
}
|
||||
@ -115,13 +115,13 @@ const goBack = () => {
|
||||
emit('back')
|
||||
}
|
||||
|
||||
const showRecharge = ref(false);
|
||||
const showRecharge = ref(false)
|
||||
watch(() => props.isRecharge, (newVal) => {
|
||||
showRecharge.value = newVal;
|
||||
showRecharge.value = newVal
|
||||
if (newVal) {
|
||||
getSmsPackagesListFn();
|
||||
getSmsPackagesListFn()
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
@ -140,4 +140,4 @@ watch(() => props.isRecharge, (newVal) => {
|
||||
box-shadow: 0 0 6px rgba(64, 158, 255, 0.3);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@ -64,9 +64,9 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref , reactive,onMounted} from 'vue'
|
||||
import { getSmsOrdersList ,getOrderInfo} from '@/app/api/notice'
|
||||
import { t } from "@/lang";
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { getSmsOrdersList, getOrderInfo } from '@/app/api/notice'
|
||||
import { t } from '@/lang'
|
||||
|
||||
const props = defineProps({
|
||||
username: {
|
||||
@ -82,27 +82,27 @@ const tableData = reactive({
|
||||
loading: false,
|
||||
data: [],
|
||||
searchParam: {
|
||||
name: "",
|
||||
name: '',
|
||||
order: '',
|
||||
sort: ''
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
// 获取列表
|
||||
const loadRankList = () => {
|
||||
tableData.loading = true;
|
||||
let params = {
|
||||
tableData.loading = true
|
||||
const params = {
|
||||
page: tableData.page,
|
||||
limit: tableData.limit,
|
||||
...tableData.searchParam
|
||||
}
|
||||
getSmsOrdersList(props.username, params).then((res) => {
|
||||
tableData.loading = false;
|
||||
tableData.data = res.data.data;
|
||||
tableData.total = res.data.total;
|
||||
tableData.loading = false
|
||||
tableData.data = res.data.data
|
||||
tableData.total = res.data.total
|
||||
}).catch(() => {
|
||||
tableData.loading = false;
|
||||
});
|
||||
tableData.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
// 详情
|
||||
@ -112,7 +112,7 @@ const loading = ref(false)
|
||||
const detailEvent = (row:any) => {
|
||||
loading.value = true
|
||||
visibleDetail.value = true
|
||||
getOrderInfo(props.username,{out_trade_no:row.out_trade_no}).then(res=>{
|
||||
getOrderInfo(props.username, { out_trade_no: row.out_trade_no }).then(res => {
|
||||
detail.value = res.data
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
@ -47,10 +47,10 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref ,reactive,onMounted} from 'vue'
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { getSmsSendList } from '@/app/api/notice'
|
||||
import { timeStampTurnTime } from '@/utils/common'
|
||||
import { t } from "@/lang";
|
||||
import { t } from '@/lang'
|
||||
|
||||
const props = defineProps({
|
||||
username: {
|
||||
@ -75,26 +75,26 @@ const tableData = reactive({
|
||||
|
||||
// 获取列表
|
||||
const loadRankList = () => {
|
||||
tableData.loading = true;
|
||||
let params = {
|
||||
tableData.loading = true
|
||||
const params = {
|
||||
page: tableData.page,
|
||||
limit: tableData.limit,
|
||||
...tableData.searchParam
|
||||
}
|
||||
getSmsSendList(props.username, params).then((res) => {
|
||||
tableData.loading = false;
|
||||
tableData.data = res.data.data;
|
||||
tableData.total = res.data.total;
|
||||
tableData.loading = false
|
||||
tableData.data = res.data.data
|
||||
tableData.total = res.data.total
|
||||
}).catch(() => {
|
||||
tableData.loading = false;
|
||||
});
|
||||
tableData.loading = false
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
if (props.username) {
|
||||
loadRankList();
|
||||
loadRankList()
|
||||
}
|
||||
})
|
||||
const searchFormRef = ref<FormInstance>();
|
||||
const searchFormRef = ref<FormInstance>()
|
||||
const resetForm = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
formEl.resetFields()
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<el-dialog v-model="visible" :title="t('选择签名')" width="1200px" destroy-on-close :close-on-click-modal="false">
|
||||
<el-alert type="warning" :closable="false" class="!mb-[10px]">
|
||||
<template #default>
|
||||
<p class="">签名数据的变更(新增 / 删除)需经过五分钟的生效周期,在此期间系统将完成数据同步与更新</p>
|
||||
<p>签名数据的变更(新增 / 删除)需经过五分钟的生效周期,在此期间系统将完成数据同步与更新</p>
|
||||
</template>
|
||||
</el-alert>
|
||||
<div class="flex justify-between items-center mb-[16px]">
|
||||
@ -141,8 +141,8 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, reactive } from 'vue'
|
||||
import { getSignList,addSign,getSmsSignConfig,deleteSign } from '@/app/api/notice'
|
||||
import { t } from "@/lang";
|
||||
import { getSignList, addSign, getSmsSignConfig, deleteSign } from '@/app/api/notice'
|
||||
import { t } from '@/lang'
|
||||
|
||||
const visible = ref(false)
|
||||
const visibleAdd = ref(false)
|
||||
@ -171,9 +171,9 @@ const formData = reactive({ ...initialFormData })
|
||||
|
||||
const signConfig = reactive({
|
||||
signTypeList: [],
|
||||
signSourceList:[]
|
||||
signSourceList: []
|
||||
})
|
||||
const getSmsSignConfigFn = ()=> {
|
||||
const getSmsSignConfigFn = () => {
|
||||
getSmsSignConfig().then(res => {
|
||||
signConfig.signTypeList = res.data.sign_type_list
|
||||
signConfig.signSourceList = res.data.sign_source_list
|
||||
@ -191,24 +191,24 @@ const formRules = computed(() => {
|
||||
{ required: true, message: '请输入短信签名', trigger: 'blur' },
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
const singleBracketValid = /^【[^【】]*】$/.test(value);
|
||||
const singleBracketValid = /^【[^【】]*】$/.test(value)
|
||||
if (!singleBracketValid) {
|
||||
return callback(new Error('短信签名必须被【】包裹'));
|
||||
return callback(new Error('短信签名必须被【】包裹'))
|
||||
}
|
||||
|
||||
const content = value.slice(1, -1);
|
||||
const content = value.slice(1, -1)
|
||||
|
||||
const lengthValid = content.length >= 2 && content.length <= 20;
|
||||
const lengthValid = content.length >= 2 && content.length <= 20
|
||||
if (!lengthValid) {
|
||||
return callback(new Error('短信签名内容需在 2-20 个字符之间'));
|
||||
return callback(new Error('短信签名内容需在 2-20 个字符之间'))
|
||||
}
|
||||
|
||||
const invalidChars = /[\s\-+=*&%#@~;]/;
|
||||
const invalidChars = /[\s\-+=*&%#@~;]/
|
||||
if (invalidChars.test(content)) {
|
||||
return callback(new Error('短信签名不能包含空格或特殊字符 - + = * & % # @ ~ ;'));
|
||||
return callback(new Error('短信签名不能包含空格或特殊字符 - + = * & % # @ ~ ;'))
|
||||
}
|
||||
|
||||
callback();
|
||||
callback()
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
@ -218,19 +218,19 @@ const formRules = computed(() => {
|
||||
{ validator: phoneVerify, trigger: 'blur' }
|
||||
],
|
||||
companyName: [
|
||||
{ required: true, message: '请输入企业名称', trigger: 'blur' },
|
||||
{ required: true, message: '请输入企业名称', trigger: 'blur' }
|
||||
],
|
||||
contentExample: [
|
||||
{ required: true, message: '请输入短信示例内容', trigger: 'blur' },
|
||||
{ required: true, message: '请输入短信示例内容', trigger: 'blur' }
|
||||
],
|
||||
creditCode: [
|
||||
{ required: true, message: '请输入社会统一信用代码', trigger: 'blur' },
|
||||
{ required: true, message: '请输入社会统一信用代码', trigger: 'blur' }
|
||||
],
|
||||
legalPerson: [
|
||||
{ required: true, message: '请输入法人姓名', trigger: 'blur' },
|
||||
{ required: true, message: '请输入法人姓名', trigger: 'blur' }
|
||||
],
|
||||
principalName: [
|
||||
{ required: true, message: '请输入经办人姓名', trigger: 'blur' },
|
||||
{ required: true, message: '请输入经办人姓名', trigger: 'blur' }
|
||||
],
|
||||
principalIdCard: [
|
||||
{ required: true, message: '请输入经办人身份证', trigger: 'blur' },
|
||||
@ -239,22 +239,22 @@ const formRules = computed(() => {
|
||||
imgUrl: [
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
const needImage = [3, 4, 5].includes(formData.signSource) || formData.signType === 1;
|
||||
const needImage = [3, 4, 5].includes(formData.signSource) || formData.signType === 1
|
||||
if (needImage) {
|
||||
if (!value || value.length === 0) {
|
||||
callback(new Error('请上传图片'));
|
||||
callback(new Error('请上传图片'))
|
||||
} else {
|
||||
callback();
|
||||
callback()
|
||||
}
|
||||
} else {
|
||||
callback(); // 不需要校验
|
||||
callback() // 不需要校验
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
|
||||
};
|
||||
}
|
||||
})
|
||||
|
||||
const idCardVerify = (rule: any, value: any, callback: any) => {
|
||||
@ -276,14 +276,14 @@ const phoneVerify = (rule: any, value: any, callback: any) => {
|
||||
const onSave = async () => {
|
||||
await formRef.value?.validate(async (valid) => {
|
||||
if (valid) {
|
||||
addSign(props.username,formData).then((res) => {
|
||||
addSign(props.username, formData).then((res) => {
|
||||
setTimeout(() => {
|
||||
visibleAdd.value = false
|
||||
loadSignList()
|
||||
}, 500);
|
||||
}, 500)
|
||||
})
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// 表单内容
|
||||
@ -293,8 +293,8 @@ const tableData = reactive({
|
||||
total: 0,
|
||||
loading: false,
|
||||
data: [],
|
||||
searchParam: {},
|
||||
});
|
||||
searchParam: {}
|
||||
})
|
||||
|
||||
const open = () => {
|
||||
visible.value = true
|
||||
@ -302,19 +302,19 @@ const open = () => {
|
||||
}
|
||||
// 获取列表
|
||||
const loadSignList = () => {
|
||||
tableData.loading = true;
|
||||
let params = {
|
||||
tableData.loading = true
|
||||
const params = {
|
||||
page: tableData.page,
|
||||
limit: tableData.limit,
|
||||
...tableData.searchParam,
|
||||
...tableData.searchParam
|
||||
}
|
||||
getSignList(props.username, params).then((res) => {
|
||||
tableData.loading = false;
|
||||
tableData.data = res.data.data;
|
||||
tableData.loading = false
|
||||
tableData.data = res.data.data
|
||||
tableData.total = res.data.total
|
||||
}).catch(() => {
|
||||
tableData.loading = false;
|
||||
});
|
||||
tableData.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
const addEvent = () => {
|
||||
@ -328,14 +328,14 @@ const deleteTemplate = (row:any) => {
|
||||
ElMessageBox.confirm(t('确定删除该签名吗?'), t('提示'), {
|
||||
confirmButtonText: t('确定'),
|
||||
cancelButtonText: t('取消'),
|
||||
type: 'warning',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
deleteSign(props.username, { signatures: [row.sign] }).then((res) => {
|
||||
// loadSignList()
|
||||
tableData.loading = true;
|
||||
tableData.loading = true
|
||||
setTimeout(() => {
|
||||
loadSignList()
|
||||
},1000)
|
||||
}, 1000)
|
||||
})
|
||||
})
|
||||
}
|
||||
@ -373,23 +373,23 @@ const handleSelectionChange = (val: []) => {
|
||||
}
|
||||
}
|
||||
const checkSelectable = (row: any, index: number) => {
|
||||
return !row.is_default; // 只有不是“使用中”的行可选
|
||||
return !row.is_default // 只有不是“使用中”的行可选
|
||||
}
|
||||
|
||||
// 批量删除
|
||||
const batchDeleteEvent = () => {
|
||||
if (multipleSelection.value.length == 0) {
|
||||
ElMessage({
|
||||
type: "warning",
|
||||
message: `${ t("请选择要删除的签名") }`,
|
||||
type: 'warning',
|
||||
message: `${t('请选择要删除的签名')}`
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
ElMessageBox.confirm(t("确定删除选中的签名吗?"), t("warning"), {
|
||||
confirmButtonText: t("confirm"),
|
||||
cancelButtonText: t("cancel"),
|
||||
type: "warning"
|
||||
ElMessageBox.confirm(t('确定删除选中的签名吗?'), t('warning'), {
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
const signatures: any = []
|
||||
multipleSelection.value.forEach((item: any) => {
|
||||
@ -399,7 +399,7 @@ const batchDeleteEvent = () => {
|
||||
deleteSign(props.username, {
|
||||
signatures
|
||||
}).then(() => {
|
||||
tableData.loading = true;
|
||||
tableData.loading = true
|
||||
setTimeout(() => {
|
||||
loadSignList()
|
||||
}, 1000)
|
||||
@ -416,4 +416,4 @@ const selectTemplate = (row:any) => {
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@ -143,16 +143,16 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref ,computed,reactive,onMounted,watch} from 'vue'
|
||||
import { getTemplateList,getTemplateReportConfig,reportTemplate,templateSync ,getreportTemplateInfo,clearTemplate} from '@/app/api/notice'
|
||||
import { t } from "@/lang";
|
||||
import { ref, computed, reactive, onMounted, watch } from 'vue'
|
||||
import { getTemplateList, getTemplateReportConfig, reportTemplate, templateSync, getreportTemplateInfo, clearTemplate } from '@/app/api/notice'
|
||||
import { t } from '@/lang'
|
||||
|
||||
const props = defineProps({
|
||||
username: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
signature:{
|
||||
signature: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
@ -163,22 +163,22 @@ const tableData = reactive({
|
||||
limit: 10,
|
||||
total: 0,
|
||||
loading: false,
|
||||
data: [], // 当前页展示的数据(通过 computed 生成)
|
||||
allData: [], // 原始完整数据
|
||||
data: [], // 当前页展示的数据(通过 computed 生成)
|
||||
allData: [], // 原始完整数据
|
||||
searchParam: {
|
||||
template_id: "",
|
||||
template_id: '',
|
||||
name: '',
|
||||
status: ''
|
||||
}
|
||||
});
|
||||
})
|
||||
const filterData = () => {
|
||||
const { template_id, name, status } = tableData.searchParam;
|
||||
const { template_id, name, status } = tableData.searchParam
|
||||
return tableData.allData.filter(item => {
|
||||
const matchId = !template_id || String(item.template_id || '').includes(template_id);
|
||||
const matchName = !name || String(item.name || '').includes(name);
|
||||
const matchStatus = !status || item.audit_info.audit_status == status;
|
||||
return matchId && matchName && matchStatus;
|
||||
});
|
||||
const matchId = !template_id || String(item.template_id || '').includes(template_id)
|
||||
const matchName = !name || String(item.name || '').includes(name)
|
||||
const matchStatus = !status || item.audit_info.audit_status == status
|
||||
return matchId && matchName && matchStatus
|
||||
})
|
||||
}
|
||||
|
||||
watch(() => [tableData.limit, tableData.page], () => {
|
||||
@ -187,33 +187,33 @@ watch(() => [tableData.limit, tableData.page], () => {
|
||||
|
||||
// 获取列表
|
||||
const loadSmsTemplateList = () => {
|
||||
tableData.loading = true;
|
||||
tableData.loading = true
|
||||
getTemplateList({ sms_type: 'niuyun', username: props.username }).then((res) => {
|
||||
tableData.allData = res.data;
|
||||
tableData.page = 1; // 搜索后回到第一页
|
||||
tableData.allData = res.data
|
||||
tableData.page = 1 // 搜索后回到第一页
|
||||
pagedDataChange()
|
||||
}).catch(() => {
|
||||
tableData.loading = false;
|
||||
});
|
||||
tableData.loading = false
|
||||
})
|
||||
}
|
||||
const searchFormRef = ref(null)
|
||||
const resetForm = (formRef) => {
|
||||
if (!formRef) return;
|
||||
if (!formRef) return
|
||||
tableData.searchParam = {
|
||||
template_id: "",
|
||||
template_id: '',
|
||||
name: '',
|
||||
status: ''
|
||||
}
|
||||
loadSmsTemplateList()
|
||||
};
|
||||
}
|
||||
const pagedData = ref([])
|
||||
const pagedDataChange = () => {
|
||||
const filtered = filterData(); // 使用筛选后的数据
|
||||
tableData.total = filtered.length;
|
||||
const start = (tableData.page - 1) * tableData.limit;
|
||||
const end = start + tableData.limit;
|
||||
pagedData.value = filtered.slice(start, end);
|
||||
tableData.loading = false;
|
||||
const filtered = filterData() // 使用筛选后的数据
|
||||
tableData.total = filtered.length
|
||||
const start = (tableData.page - 1) * tableData.limit
|
||||
const end = start + tableData.limit
|
||||
pagedData.value = filtered.slice(start, end)
|
||||
tableData.loading = false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
@ -226,7 +226,7 @@ const visibleAsync = ref(false)
|
||||
const repeatList = ref({})
|
||||
const syncEvent = () => {
|
||||
templateSync('niuyun', props.username).then((res) => {
|
||||
repeatList.value = res.data.repeat_list;
|
||||
repeatList.value = res.data.repeat_list
|
||||
if (repeatList.value && Object.keys(repeatList.value).length > 0) {
|
||||
visibleAsync.value = true
|
||||
} else {
|
||||
@ -255,7 +255,7 @@ const clearEvent = (row:any) => {
|
||||
ElMessageBox.confirm(t('确定要清除报备信息吗'), t('提示'), {
|
||||
confirmButtonText: t('确定'),
|
||||
cancelButtonText: t('取消'),
|
||||
type: 'warning',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
clearTemplate(props.username, row.template_id).then(() => {
|
||||
loadSmsTemplateList()
|
||||
@ -271,7 +271,7 @@ const visibleReport = ref(false)
|
||||
const reportData = ref({
|
||||
template_type: 1,
|
||||
template_key: '',
|
||||
params_json:{}
|
||||
params_json: {}
|
||||
})
|
||||
const getTemplateReportConfigFn = () => {
|
||||
getTemplateReportConfig().then((res) => {
|
||||
@ -296,33 +296,32 @@ const isMarketingWithVariable = computed(() => {
|
||||
|
||||
watch(isMarketingWithVariable, (val) => {
|
||||
if (val) {
|
||||
ElMessage.error('营销推广类型不支持变量');
|
||||
ElMessage.error('营销推广类型不支持变量')
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
const reportLoading = ref(false)
|
||||
const reportEvent = (row:any) => {
|
||||
reportLoading.value = true
|
||||
let signature = props.signature
|
||||
const signature = props.signature
|
||||
if (!signature) {
|
||||
ElMessage.error('请先配置签名')
|
||||
return
|
||||
} else {
|
||||
if (row.template_id) {
|
||||
visibleReport.value = true;
|
||||
detail.value = row;
|
||||
visibleReport.value = true
|
||||
detail.value = row
|
||||
getreportTemplateInfo('niuyun', props.username, { template_key: row.key }).then((res) => {
|
||||
const paramJson = res.data?.param_json ?? {};
|
||||
reportData.value.template_key = res.data.template_key;
|
||||
reportData.value.template_type = Number(res.data.template_type);
|
||||
reportData.value.params_json = {};
|
||||
const paramJson = res.data?.param_json ?? {}
|
||||
reportData.value.template_key = res.data.template_key
|
||||
reportData.value.template_type = Number(res.data.template_type)
|
||||
reportData.value.params_json = {}
|
||||
if (detail.value.variable) {
|
||||
for (const key in detail.value.variable) {
|
||||
reportData.value.params_json[key] = paramJson[key] ?? '';
|
||||
reportData.value.params_json[key] = paramJson[key] ?? ''
|
||||
}
|
||||
}
|
||||
reportLoading.value = false;
|
||||
});
|
||||
reportLoading.value = false
|
||||
})
|
||||
} else {
|
||||
visibleReport.value = true
|
||||
reportLoading.value = false
|
||||
@ -331,7 +330,6 @@ const reportEvent = (row:any) => {
|
||||
reportData.value.template_key = detail.value.key
|
||||
reportData.value.params_json = {}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -343,10 +341,10 @@ const reportTemplateFn = () => {
|
||||
// 校验每个变量是否已选择类型
|
||||
const missingParams = Object.entries(detail.value.variable).some(
|
||||
([key]) => !reportData.value.params_json[key]
|
||||
);
|
||||
)
|
||||
if (missingParams) {
|
||||
ElMessage.error('请为每个变量选择类型');
|
||||
return;
|
||||
ElMessage.error('请为每个变量选择类型')
|
||||
return
|
||||
}
|
||||
if (detail.value.template_id) {
|
||||
reportData.value.template_id = Number(detail.value.template_id)
|
||||
|
||||
@ -3,7 +3,8 @@
|
||||
|
||||
<el-form class="page-form" :model="formData" label-width="150px" ref="formRef" :rules="formRules" v-loading="loading">
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
<h3 class="panel-title !text-sm">{{ t('copyrightEdit') }}</h3>
|
||||
<h3 class="text-[16px] text-[#1D1F3A] font-bold mb-4">{{ pageName }}</h3>
|
||||
<h3 class="panel-title !text-[14px] bg-[#F4F5F7] p-3 border-[#E6E6E6] border-solid border-b-[1px]">{{ t('copyrightEdit') }}</h3>
|
||||
|
||||
<el-form-item :label="t('logo')">
|
||||
<upload-image v-model="formData.logo" />
|
||||
@ -17,23 +18,25 @@
|
||||
<el-form-item :label="t('copyrightDesc')" >
|
||||
<el-input v-model.trim="formData.copyright_desc" type="textarea" rows="4" clearable :placeholder="t('copyrightDescPlaceholder')" class="input-width" maxlength="150" />
|
||||
</el-form-item>
|
||||
</el-card>
|
||||
|
||||
<el-card class="box-card mt-[15px] !border-none" shadow="never">
|
||||
<h3 class="panel-title !text-sm">{{ t('putOnRecordEdit') }}</h3>
|
||||
|
||||
<el-form-item :label="t('icp')" prop="icp">
|
||||
<el-input v-model.trim="formData.icp" :placeholder="t('icpPlaceholder')" class="input-width" clearable maxlength="20"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('govRecord')" >
|
||||
<el-input v-model.trim="formData.gov_record" :placeholder="t('govRecordPlaceholder')" class="input-width" clearable maxlength="50"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('govUrl')" >
|
||||
<el-input v-model.trim="formData.gov_url" :placeholder="t('govUrlPlaceholder')" class="input-width" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('marketSupervisionUrl')" >
|
||||
<el-input v-model.trim="formData.market_supervision_url" rows="4" clearable :placeholder="t('marketSupervisionUrlPlaceholder')" class="input-width" />
|
||||
</el-form-item>
|
||||
<div class="mt-[20px]">
|
||||
<h3 class="panel-title !text-[14px] bg-[#F4F5F7] p-3 border-[#E6E6E6] border-solid border-b-[1px]">{{ t('putOnRecordEdit') }}</h3>
|
||||
<el-form-item :label="t('icp')" prop="icp">
|
||||
<el-input v-model.trim="formData.icp" :placeholder="t('icpPlaceholder')" class="input-width" clearable maxlength="20"/>
|
||||
<div class="form-tip">{{ t('网站的ICP备案号,显示在H5和PC端底部') }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('govRecord')" >
|
||||
<el-input v-model.trim="formData.gov_record" :placeholder="t('govRecordPlaceholder')" class="input-width" clearable maxlength="50"/>
|
||||
<div class="form-tip">{{ t('公安部门登记的备案信息,显示在pc底部') }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('govUrl')" >
|
||||
<el-input v-model.trim="formData.gov_url" :placeholder="t('govUrlPlaceholder')" class="input-width" clearable />
|
||||
<div class="form-tip">{{ t('H5和PC底部显示的网站公安点击跳转的链接') }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('marketSupervisionUrl')" >
|
||||
<el-input v-model.trim="formData.market_supervision_url" rows="4" clearable :placeholder="t('marketSupervisionUrlPlaceholder')" class="input-width" />
|
||||
<div class="form-tip">{{ t('H5和PC底部显示的市场监督管理局点击跳转的链接') }}</div>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-form>
|
||||
|
||||
|
||||
@ -145,8 +145,8 @@ loadExportList()
|
||||
* 下载导出报表
|
||||
*/
|
||||
const downloadEvent = (data: any) => {
|
||||
var url = img(data.file_path);
|
||||
var suffix = url.substring(url.lastIndexOf("."), url.length);
|
||||
const url = img(data.file_path);
|
||||
const suffix = url.substring(url.lastIndexOf("."), url.length);
|
||||
const a = document.createElement('a')
|
||||
a.setAttribute('download', url)
|
||||
a.setAttribute('target', '_blank')
|
||||
|
||||
@ -107,7 +107,7 @@ const loadNoticeList = () => {
|
||||
noticeTableData.seller = []
|
||||
res.data.forEach(item => {
|
||||
if (item.notice.length) {
|
||||
const buyer = [], seller = []
|
||||
const buyer = []; const seller = []
|
||||
Object.keys(item.notice).forEach((key, index) => {
|
||||
const notice = item.notice[key]
|
||||
notice.addon_name = item.title
|
||||
|
||||
@ -113,7 +113,7 @@ const setTemplateList = async () => {
|
||||
templateList.seller.list = []
|
||||
res.data.forEach(item => {
|
||||
if (item.notice.length) {
|
||||
const buyer = [], seller = []
|
||||
const buyer = []; const seller = []
|
||||
Object.keys(item.notice).forEach((key, index) => {
|
||||
const notice = item.notice[key]
|
||||
notice.addon_name = item.title
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
<h3 class="panel-title !text-sm">{{ payItems.name }}</h3>
|
||||
|
||||
<div>
|
||||
<div class="flex items-center justify-between p-[10px] table-item-border bg">
|
||||
<div class="flex items-center justify-between px-[10px] table-item-border bg h-[50px]">
|
||||
<span class="text-base w-[230px]">{{ t('payType') }}</span>
|
||||
<span class="text-base w-[110px] text-center">{{ t('onState') }}</span>
|
||||
<span class="text-base w-[80px] text-center" v-if="isEdit">{{ t('templateName') }}</span>
|
||||
@ -52,7 +52,6 @@
|
||||
<el-button type="primary" :loading="loading" @click="saveFn(formRef)">{{ t('save') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template v-for="(item, index) in payTypeList">
|
||||
<component :is="item.setting_component" :ref="(el) => setPayTypeRefs(el, item.key)" v-if="item.setting_component" @complete="setConfigInfo"/>
|
||||
</template>
|
||||
@ -210,6 +209,6 @@ const cancelFn = () => {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.table-item-border {
|
||||
@apply border-b border-[var(--el-border-color)];
|
||||
@apply border-b border-[var(--el-border-color-lighter)];
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -39,7 +39,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { defineAsyncComponent, reactive, ref } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getSmsList ,getAccountIsLogin} from '@/app/api/notice'
|
||||
import { getSmsList, getAccountIsLogin } from '@/app/api/notice'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
@ -135,11 +135,11 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref ,computed, onMounted} from 'vue'
|
||||
import { reactive, ref, computed, onMounted } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { ArrowLeft } from "@element-plus/icons-vue"
|
||||
import { getAccountIsLogin,getAccountInfo,editAccount ,editSms,getSmsCaptcha,getSmsSend,enableNiusms} from '@/app/api/notice'
|
||||
import { useRoute, useRouter} from 'vue-router'
|
||||
import { ArrowLeft } from '@element-plus/icons-vue'
|
||||
import { getAccountIsLogin, getAccountInfo, editAccount, editSms, getSmsCaptcha, getSmsSend, enableNiusms } from '@/app/api/notice'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import smsNiuLogin from '@/app/views/setting/components/sms_niu_login.vue'
|
||||
import smsTemplate from '@/app/views/setting/components/sms_template.vue'
|
||||
import smsRechargeRecord from '@/app/views/setting/components/sms_recharge_record.vue'
|
||||
@ -173,7 +173,7 @@ const backRecharge = () => {
|
||||
isRecharge.value = false
|
||||
getAccountIsLoginFn()
|
||||
}
|
||||
const getAccountIsLoginFn =()=> {
|
||||
const getAccountIsLoginFn = () => {
|
||||
loading.value = true
|
||||
getAccountIsLogin().then(res => {
|
||||
isLoginStatus.value = res.data.is_login
|
||||
@ -190,7 +190,6 @@ const getAccountIsLoginFn =()=> {
|
||||
loading.value = false
|
||||
isInit.value = true
|
||||
}
|
||||
|
||||
}).catch(err => {
|
||||
loading.value = false
|
||||
isInit.value = true
|
||||
@ -206,7 +205,7 @@ const openDialog = () => {
|
||||
const beforeChangeIsEnable = (val) => {
|
||||
if (!isInit.value) return false
|
||||
|
||||
let enable = is_enable.value == 1 ? 0 : 1
|
||||
const enable = is_enable.value == 1 ? 0 : 1
|
||||
return new Promise((resolve, reject) => {
|
||||
enableNiusms({ is_enable: enable }).then(() => {
|
||||
resolve(true)
|
||||
@ -218,7 +217,7 @@ const beforeChangeIsEnable = (val) => {
|
||||
|
||||
const handleSelectTemplate = (val) => {
|
||||
loading.value = true
|
||||
editAccount(username.value,{signature: val.sign}).then(res=>{
|
||||
editAccount(username.value, { signature: val.sign }).then(res => {
|
||||
getAccountIsLoginFn()
|
||||
})
|
||||
}
|
||||
@ -269,48 +268,48 @@ const changeFormRules = computed(() => {
|
||||
}
|
||||
],
|
||||
captcha_code: [
|
||||
{ required: true, message: '请输入验证码', trigger: 'blur' },
|
||||
{ required: true, message: '请输入验证码', trigger: 'blur' }
|
||||
],
|
||||
code: [
|
||||
{ required: true, message: '请输入动态码', trigger: 'blur' },
|
||||
{ required: true, message: '请输入动态码', trigger: 'blur' }
|
||||
]
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
const sending = ref(false); // 发送中状态
|
||||
const countdown = ref(0); // 倒计时秒数
|
||||
const sending = ref(false) // 发送中状态
|
||||
const countdown = ref(0) // 倒计时秒数
|
||||
|
||||
const getSmsSendFn = () => {
|
||||
if (countdown.value > 0 || sending.value) return; // 正在倒计时或发送中,直接返回
|
||||
if (countdown.value > 0 || sending.value) return // 正在倒计时或发送中,直接返回
|
||||
changeFormRef.value.validateField(['captcha_code'], (valid) => {
|
||||
if (!valid) return;
|
||||
sending.value = true; // 标记为发送中
|
||||
if (!valid) return
|
||||
sending.value = true // 标记为发送中
|
||||
const params = {
|
||||
mobile: formData.mobiles,
|
||||
captcha_key: changeFormData.value.captcha_key,
|
||||
captcha_code: changeFormData.value.captcha_code
|
||||
};
|
||||
}
|
||||
getSmsSend(params).then((res) => {
|
||||
changeFormData.value.key = res.data.key;
|
||||
startCountdown(60); // 启动60秒倒计时
|
||||
changeFormData.value.key = res.data.key
|
||||
startCountdown(60) // 启动60秒倒计时
|
||||
}).catch((err) => {
|
||||
getSmsCaptchaFn()
|
||||
sending.value = false;
|
||||
sending.value = false
|
||||
}).finally(() => {
|
||||
sending.value = false; // 无论成功失败都重置发送状态
|
||||
});
|
||||
});
|
||||
};
|
||||
sending.value = false // 无论成功失败都重置发送状态
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 启动倒计时
|
||||
const startCountdown = (seconds) => {
|
||||
countdown.value = seconds;
|
||||
countdown.value = seconds
|
||||
const timer = setInterval(() => {
|
||||
countdown.value--;
|
||||
countdown.value--
|
||||
if (countdown.value <= 0) {
|
||||
clearInterval(timer);
|
||||
clearInterval(timer)
|
||||
}
|
||||
}, 1000);
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
const onSave = async () => {
|
||||
@ -326,7 +325,7 @@ const onSave = async () => {
|
||||
}
|
||||
} else {
|
||||
params = {
|
||||
new_mobile: changeFormData.value.new_mobile,
|
||||
new_mobile: changeFormData.value.new_mobile
|
||||
}
|
||||
}
|
||||
|
||||
@ -335,7 +334,7 @@ const onSave = async () => {
|
||||
getAccountIsLoginFn()
|
||||
})
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
const back = () => {
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
import { onMounted, onBeforeUnmount, ref } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { t } from '@/lang'
|
||||
import { ArrowLeft } from "@element-plus/icons-vue"
|
||||
import { ArrowLeft } from '@element-plus/icons-vue'
|
||||
import { getOrderPayStatus } from '@/app/api/notice'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user