update admin

This commit is contained in:
全栈小学生 2024-09-28 09:24:34 +08:00
parent 4aaf885ef0
commit f8371690c2
108 changed files with 1747 additions and 432 deletions

View File

@ -12,7 +12,7 @@ export function getAddonLocal(params: Record<string, any>) {
* *
* @returns * @returns
*/ */
export function getAddonDetial(id: number) { export function getAddonDetail(id: number) {
return request.get(`addon/${id}`) return request.get(`addon/${id}`)
} }

View File

@ -460,6 +460,26 @@ export function deleteCron(id: string) {
return request.delete(`sys/schedule/${ id }`, { showSuccessMessage: true }) return request.delete(`sys/schedule/${ id }`, { showSuccessMessage: true })
} }
/**
*
* @returns
*/
export function doCron(params: Record<string, any>) {
return request.put(`sys/schedule/do/${ params.id }`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
*
* @returns
*/
export function getCronLogList(params: any) {
return request.get(`sys/schedule/log/list`, { params })
}
/***************************************************** 协议管理 ****************************************************/ /***************************************************** 协议管理 ****************************************************/
/** /**

View File

@ -109,6 +109,7 @@ const getCloudBuildLogFn = () => {
if (showDialog.value && cloudBuildLog.length) { if (showDialog.value && cloudBuildLog.length) {
active.value = 'complete' active.value = 'complete'
terminalRef.value.execute('clear') terminalRef.value.execute('clear')
clearCloudBuildTask()
} }
notificationEl && notificationEl.close() notificationEl && notificationEl.close()
cloudBuildTask.value = null cloudBuildTask.value = null

View File

@ -18,11 +18,11 @@
<div class="mt-[20px]" v-for="(item, index) in upgradeContent.version_list" :key="index"> <div class="mt-[20px]" v-for="(item, index) in upgradeContent.version_list" :key="index">
<div class="font-bold text-lg">{{ item.version_no }}</div> <div class="font-bold text-lg">{{ item.version_no }}</div>
<div class="mt-[5px]" v-if="item.release_time">{{ item.release_time }}</div> <div class="mt-[5px]" v-if="item.release_time">{{ item.release_time }}</div>
<div class="mt-[10px] p-[10px] rounded bg-[#f4f4f5] whitespace-pre" v-if="item.upgrade_log" v-html="item.upgrade_log"></div> <div class="mt-[10px] p-[10px] rounded bg-[#f4f4f5] whitespace-pre-wrap !break-all" v-if="item.upgrade_log" v-html="item.upgrade_log"></div>
</div> </div>
</el-scrollbar> </el-scrollbar>
</div> </div>
<div class="flex justify-end"> <div class="flex justify-end" v-if="upgradeContent.version_list.length">
<el-button type="primary" @click="handleUpgrade" :loading="uploading">{{ t('upgrade.upgradeButton') }}</el-button> <el-button type="primary" @click="handleUpgrade" :loading="uploading">{{ t('upgrade.upgradeButton') }}</el-button>
</div> </div>
</div> </div>
@ -109,20 +109,17 @@
</div> </div>
</template> </template>
</el-dialog> </el-dialog>
<cloud-build ref="cloudBuildRef" />
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, h, watch } from 'vue' import { ref, h, watch } from 'vue'
import { t } from '@/lang' import { t } from '@/lang'
import { getVersions } from '@/app/api/auth' import { getVersions } from '@/app/api/auth'
import { getFrameworkVersionList } from '@/app/api/module' import { getFrameworkNewVersion } from '@/app/api/module'
import { getUpgradeContent, getUpgradeTask, upgradeAddon, executeUpgrade, preUpgradeCheck, clearUpgradeTask } from '@/app/api/upgrade' import { getUpgradeContent, getUpgradeTask, upgradeAddon, executeUpgrade, preUpgradeCheck, clearUpgradeTask } from '@/app/api/upgrade'
import { Terminal, TerminalFlash } from 'vue-web-terminal' import { Terminal, TerminalFlash } from 'vue-web-terminal'
import 'vue-web-terminal/lib/theme/dark.css' import 'vue-web-terminal/lib/theme/dark.css'
import { AnyObject } from '@/types/global' import { AnyObject } from '@/types/global'
import CloudBuild from '@/app/components/cloud-build/index.vue'
import { ElNotification, ElMessage, ElMessageBox } from 'element-plus' import { ElNotification, ElMessage, ElMessageBox } from 'element-plus'
import Storage from '@/utils/storage' import Storage from '@/utils/storage'
@ -132,12 +129,11 @@ const upgradeTask = ref<null | AnyObject>(null)
const active = ref('content') const active = ref('content')
const upgradeCheck = ref<null | AnyObject>(null) const upgradeCheck = ref<null | AnyObject>(null)
const uploading = ref(false) const uploading = ref(false)
const terminalRef = ref(null) const terminalRef: any = ref(null)
const emits = defineEmits(['complete']) const emits = defineEmits(['complete', 'cloudbuild'])
const cloudBuildRef = ref(null)
const upgradeTipsShowDialog = ref<boolean>(false) const upgradeTipsShowDialog = ref<boolean>(false)
let upgradeLog = [] let upgradeLog: any = []
/** /**
* 查询升级任务 * 查询升级任务
*/ */
@ -172,6 +168,7 @@ const getUpgradeTaskFn = () => {
active.value = 'complete' active.value = 'complete'
notificationEl && notificationEl.close() notificationEl && notificationEl.close()
emits('complete') emits('complete')
clearUpgradeTask()
return return
} }
upgradeTask.value = data upgradeTask.value = data
@ -210,13 +207,14 @@ const elNotificationClick = () => {
notificationEl && notificationEl.close() notificationEl && notificationEl.close()
} }
const versions = ref('') const frameworkVersion = ref('')
const getVersionsInfo = () => {
getVersions().then(res => { getVersions().then(res => {
versions.value = res.data.version.version frameworkVersion.value = res.data.version.version
})
const newFrameworkVersion = ref("")
getFrameworkNewVersion().then(({ data }) => {
newFrameworkVersion.value = data.last_version
}) })
}
getVersionsInfo()
/** /**
* 执行升级 * 执行升级
@ -247,18 +245,12 @@ const open = (addonKey: string = '') => {
ElMessage({ message: '已有正在执行中的升级任务', type: 'error' }) ElMessage({ message: '已有正在执行中的升级任务', type: 'error' })
showDialog.value = true showDialog.value = true
} else { } else {
getFrameworkVersionList().then(({ data }) => { if (addonKey && frameworkVersion.value != newFrameworkVersion.value) {
const newVersion = data.length ? data[0] : null
if (addonKey && newVersion && newVersion.version_no !== versions.value) {
ElMessage({ message: '存在新版本框架,请先升级框架', type: 'error' }) ElMessage({ message: '存在新版本框架,请先升级框架', type: 'error' })
return return
} else { }
getUpgradeContent(addonKey).then(({ data }) => { getUpgradeContent(addonKey).then(({ data }) => {
upgradeContent.value = data upgradeContent.value = data
if (!data.version_list.length) {
ElMessage({ message: '已经是最新版本了', type: 'error' })
return
}
if (Storage.get('upgradeTipsLock')) { if (Storage.get('upgradeTipsLock')) {
showDialog.value = true showDialog.value = true
} else { } else {
@ -266,14 +258,12 @@ const open = (addonKey: string = '') => {
} }
}).catch() }).catch()
} }
})
}
} }
/** /**
* 升级进度动画 * 升级进度动画
*/ */
let flashInterval = null let flashInterval: any = null
const terminalFlash = new TerminalFlash() const terminalFlash = new TerminalFlash()
const onExecCmd = (key, command, success, failed, name) => { const onExecCmd = (key, command, success, failed, name) => {
if (command == '开始升级') { if (command == '开始升级') {
@ -335,7 +325,7 @@ const clearUpgradeTaskFn = () => {
*/ */
const handleCloudBuild = () => { const handleCloudBuild = () => {
showDialog.value = false showDialog.value = false
cloudBuildRef.value?.open() emits('cloudbuild')
} }
const upgradeTipsConfirm = (isLock: boolean = false) => { const upgradeTipsConfirm = (isLock: boolean = false) => {

View File

@ -8,7 +8,7 @@
<span>{{saveInfo.username}}</span> <span>{{saveInfo.username}}</span>
</el-form-item> </el-form-item>
<el-form-item :label="t('realName')"> <el-form-item :label="t('realName')">
<el-input v-model="saveInfo.real_name" :placeholder="t('realNamePlaceholder')" clearable class="input-width" /> <el-input v-model.trim="saveInfo.real_name" :placeholder="t('realNamePlaceholder')" clearable class="input-width" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
@ -31,8 +31,7 @@ import useUserStore from '@/stores/modules/user'
const userStore = useUserStore() const userStore = useUserStore()
const router = useRouter() const router = useRouter()
// //
const saveInfo = reactive({}) const saveInfo: any = reactive({})
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()
const loading = ref(true) const loading = ref(true)
const dialogVisible = ref(false) const dialogVisible = ref(false)
@ -61,7 +60,7 @@ const submitForm = (formEl: FormInstance | undefined) => {
setUserInfo(saveInfo).then((res: any) => { setUserInfo(saveInfo).then((res: any) => {
loading.value = false loading.value = false
dialogVisible.value = false dialogVisible.value = false
let data = deepClone(userStore.userInfo) let data: any = deepClone(userStore.userInfo)
data.head_img = saveInfo.head_img data.head_img = saveInfo.head_img
userStore.setUserInfo(data) userStore.setUserInfo(data)
}).catch(() => { }).catch(() => {

View File

@ -28,5 +28,6 @@
"manager": "用户", "manager": "用户",
"managerPlaceholder": "请选择用户", "managerPlaceholder": "请选择用户",
"managerTips": "选择或者新增用户作为管理员", "managerTips": "选择或者新增用户作为管理员",
"newAddManager": "新增用户" "newAddManager": "新增用户",
"userDeleteTips": "是否要删除该管理员?"
} }

View File

@ -3,7 +3,7 @@
"preview": "预览图", "preview": "预览图",
"copy": "复制", "copy": "复制",
"clickVisit": "点击访问", "clickVisit": "点击访问",
"PCDomainName": "pc域名", "pCDomainName": "pc域名",
"newInfo": "最新消息", "newInfo": "最新消息",
"isOpen": "是否开启" "isOpen": "是否开启"
} }

View File

@ -20,5 +20,6 @@
"customMenu": "自定义菜单", "customMenu": "自定义菜单",
"wechatTemplate": "模板消息", "wechatTemplate": "模板消息",
"menusEmptyTips": "空菜单,不能保存与发布。", "menusEmptyTips": "空菜单,不能保存与发布。",
"reply": "自动回复" "reply": "自动回复",
"menuUrlErrorTips": "请输入完整的网页链接如https://www.baidu.com"
} }

View File

@ -19,5 +19,6 @@
"dataValuePlaceholder":"请输入数据值", "dataValuePlaceholder":"请输入数据值",
"sortPlaceholder":"数值越大越排前", "sortPlaceholder":"数值越大越排前",
"momePlaceholder":"请输入备注", "momePlaceholder":"请输入备注",
"createTime":"创建时间" "createTime":"创建时间",
"keyFormatTips": "关键字只允许输入字母和下划线"
} }

View File

@ -86,6 +86,7 @@
"graphicNavShowStyle": "展示风格", "graphicNavShowStyle": "展示风格",
"graphicNavStyleFixed": "固定显示", "graphicNavStyleFixed": "固定显示",
"graphicNavStyleSingleSlide": "单行滑动", "graphicNavStyleSingleSlide": "单行滑动",
"graphicNavStyleMultiLine": "多行滑动",
"graphicNavStylePageSlide": "分页滑动", "graphicNavStylePageSlide": "分页滑动",
"graphicNavRowCount": "每行数量", "graphicNavRowCount": "每行数量",
"graphicNavPageCount": "显示方式", "graphicNavPageCount": "显示方式",

View File

@ -1,4 +1,7 @@
{ {
"title": "插件名称", "title": "插件名称",
"key": "插件标识" "key": "插件标识",
"type": "插件类型",
"app": "应用",
"addon": "插件"
} }

View File

@ -43,6 +43,8 @@
"transferTime": "转账时间", "transferTime": "转账时间",
"memberInfoPlaceholder": "请输入会员名称/会员昵称/手机号", "memberInfoPlaceholder": "请输入会员名称/会员昵称/手机号",
"cashOutNumber": "提现单号", "cashOutNumber": "提现单号",
"cashOutNumberPlaceholder": "请输入提现单号" "cashOutNumberPlaceholder": "请输入提现单号",
"alipayAccount": "支付宝账号",
"bankName": "银行名称",
"bankAccount": "银行卡号"
} }

View File

@ -6,5 +6,11 @@
"createTime": "申请时间", "createTime": "申请时间",
"refundNoPlaceholder": "请输入退款编号", "refundNoPlaceholder": "请输入退款编号",
"startDate": "开始时间", "startDate": "开始时间",
"endDate": "结束时间" "endDate": "结束时间",
"outTradeNo": "交易流水号",
"refundTypeName": "退款方式",
"statusName": "退款状态",
"transfer": "转账",
"transferType": "转账方式",
"voucher": "凭证"
} }

View File

@ -7,6 +7,7 @@
"calendarSign": "日历签到", "calendarSign": "日历签到",
"periodSign": "周期签到", "periodSign": "周期签到",
"daySignAward": "日签奖励", "daySignAward": "日签奖励",
"daySignAwardPlaceholder": "请选择日签奖励",
"continueSignAward": "连签奖励", "continueSignAward": "连签奖励",
"calendarSignTip": "用户根据日期进行打卡,连续签到一定天数可即可获得连签奖励。", "calendarSignTip": "用户根据日期进行打卡,连续签到一定天数可即可获得连签奖励。",
"periodSignTip": "用户在规定的周期内完成签到可以获得奖励;一个周期结束后将进入下一个循环周期。", "periodSignTip": "用户在规定的周期内完成签到可以获得奖励;一个周期结束后将进入下一个循环周期。",

View File

@ -6,13 +6,11 @@
"createTime":"注册时间", "createTime":"注册时间",
"lastVisitTime":"最后访问时间", "lastVisitTime":"最后访问时间",
"addMember":"添加会员", "addMember":"添加会员",
"updateMember":"编辑会员",
"nickNamePlaceholder":"请输入会员昵称", "nickNamePlaceholder":"请输入会员昵称",
"mobilePlaceholder":"请输入手机号", "mobilePlaceholder":"请输入手机号",
"channelPlaceholder":"请选择注册类型", "channelPlaceholder":"请选择注册类型",
"memberNoPlaceholder":"请选择会员编号", "memberNoPlaceholder":"请选择会员编号",
"memberDeleteTips" : "确定要删除该会员吗?", "memberDeleteTips" : "确定要删除该会员吗?",
"detail": "详情",
"edit": "编辑", "edit": "编辑",
"memberDelete":"删除", "memberDelete":"删除",
"adjust":"调整", "adjust":"调整",
@ -44,12 +42,41 @@
"mobileHint": "请输入正确的手机号!", "mobileHint": "请输入正确的手机号!",
"memberLabelTag": "标签", "memberLabelTag": "标签",
"setLabel": "标签", "setLabel": "标签",
"notAvailable": "暂无",
"memberLabelPlaceholder": "请选择会员标签", "memberLabelPlaceholder": "请选择会员标签",
"memberInfo":"会员信息", "memberInfo":"会员信息",
"memberInfoPlaceholder":"请输入会员编号/昵称/手机号", "memberInfoPlaceholder":"请输入会员编号/昵称/手机号",
"lock": "锁定", "lock": "锁定",
"normal": "正常", "normal": "正常",
"memberLevel": "会员等级", "memberLevel": "会员等级",
"memberLevelPlaceholder": "请选择会员等级" "memberLevelPlaceholder": "请选择会员等级",
"adjustType":"调整类型",
"adjustReduceBalance":"减少余额",
"adjustAddBalance":"增加余额",
"adjustReducePoint":"减少积分",
"adjustAddPoint":"增加积分",
"adjustBalance":"调整余额",
"currBalance":"当前余额",
"currPoint":"当前积分",
"adjustPlaceholder":"请输入调整数量",
"memoPlaceholder":"请输入备注",
"adjustBalancePlaceholder":"请输入调整余额",
"adjustPointPlaceholder":"请输入调整积分",
"adjustBalanceMaxAccountMessage":"调整后余额需大于0",
"adjustPointMaxAccountMessage":"调整后积分需大于0",
"birthday": "出生日期",
"birthdayTip": "请输入出生日期",
"headimg": "会员头像",
"updateMember": "编辑会员信息",
"notAvailable":"暂无",
"girlSex":"女",
"manSex":"男",
"secrecySex":"保密",
"detail":"详情",
"accumulative":"累计",
"money":"可提现余额",
"commission":"佣金",
"memberNull":"未读取到会员详情信息",
"memberLevelUpdate": "修改等级至",
"memberLevelUpdateTips": "该操作只会修改会员等级不会发放等级礼包"
} }

View File

@ -2,5 +2,6 @@
"isCaptcha": "是否启用验证码", "isCaptcha": "是否启用验证码",
"bgImg": "登录页广告图", "bgImg": "登录页广告图",
"admin": "平台端", "admin": "平台端",
"adminBgImgTip": "建议上传尺寸为450*400px" "adminBgImgTip": "建议上传尺寸为450*400px",
"siteBgImgTip": "建议上传尺寸为620*980px"
} }

View File

@ -2,5 +2,7 @@
"title": "协议标题", "title": "协议标题",
"type": "协议类型", "type": "协议类型",
"titlePlaceholder": "请输入协议标题", "titlePlaceholder": "请输入协议标题",
"contentPlaceholder": "请填写协议内容",
"contentMaxTips": "协议内容字符数应在550000之间",
"content": "内容" "content": "内容"
} }

View File

@ -1,16 +1,21 @@
{ {
"commonSetting": "通用设置",
"logonMode": "普通注册方式", "logonMode": "普通注册方式",
"isUsername": "账号密码登录", "isUsername": "账号密码登录",
"isMobile": "手机验证码登录",
"isAuthRegister": "第三方自动注册",
"isBindMobile": "强制绑定手机",
"isUsernameTip": "开启之后可以使用账号+密码进行注册和登录", "isUsernameTip": "开启之后可以使用账号+密码进行注册和登录",
"isMobileTip": "开启之后可以使用手机+验证码进行注册和登录", "isMobile": "手机验证码登录",
"isAuthRegisterTip": "开启之后,微信公众号、小程序等第三方平台可以自动注册会员。方便会员自动登录", "isMobileTip": "开启之后可以使用手机+验证码进行注册和登录或者快捷登录/注册",
"isBindMobileTip": "开启之后,会员通过普通注册方式会强制绑定手机号,同时在相关页面也会引导会员强制绑定手机账号,否则影响功能正常使用,也方便商家进行管理,同时方便会员在不同端口统一账号", "isBindMobile": "强制绑定手机",
"isBindMobileTip": "开启之后,会员注册时会强制绑定手机号,并且在相关页面也会引导会员强制绑定手机账号,否则将影响功能正常使用,方便会员在不同端口统一账号,也方便商家进行管理",
"agreement": "政策协议", "agreement": "政策协议",
"agreementTips": "注册时服务协议和隐私协议是否进行展示", "agreementTips": "注册时服务协议和隐私协议是否进行展示",
"tripartiteSetting": "第三方设置",
"isAuthRegister": "快捷登录/注册",
"isAuthRegisterTip": "开启之后,微信公众号、小程序等第三方平台可以自动注册会员或者快捷登录/注册会员,方便会员自动登录",
"mobileOrUsernameNoEmpty": "普通注册方式至少需启用一种", "mobileOrUsernameNoEmpty": "普通注册方式至少需启用一种",
"commonSetting": "通用设置", "loginPageSet": "界面设置",
"tripartiteSetting": "第三方设置" "bgUrl": "背景图",
"bgUrlPlaceholder": "建议图片尺寸750*669像素图片格式jpg、png、jpeg",
"desc": "描述",
"descPlaceholder": "请输入描述"
} }

View File

@ -28,5 +28,8 @@
"visitTimePlaceholder":"请输入访问时间", "visitTimePlaceholder":"请输入访问时间",
"createTimePlaceholder":"请输入消息时间", "createTimePlaceholder":"请输入消息时间",
"buyerNotice": "会员消息", "buyerNotice": "会员消息",
"messageKey":"消息模版",
"messageInfo":"发送记录详情",
"smsType":"短信类型",
"sellerNotice":"平台消息" "sellerNotice":"平台消息"
} }

View File

@ -57,5 +57,11 @@
"collectionNamePlaceholder": "请输入收款账户名称", "collectionNamePlaceholder": "请输入收款账户名称",
"collectionBankPlaceholder": "请输入收款银行", "collectionBankPlaceholder": "请输入收款银行",
"collectionAccountPlaceholder": "请输入收款账号", "collectionAccountPlaceholder": "请输入收款账号",
"collectionDescPlaceholder": "请输入转账说明" "collectionDescPlaceholder": "请输入转账说明",
"jsapiDir": "JSAPI支付授权目录",
"jsapiDirTips": "需在微信商户号>产品中心>开发配置>支付配置 支付授权目录中添加该链接",
"h5Domain": "H5支付域名",
"h5DomainTips": "需在微信商户号>产品中心>开发配置>支付配置 H5支付域名中添加该域名",
"nativeDomain": "Native支付回调链接",
"nativeDomainTips": "需在微信商户号>产品中心>开发配置>支付配置 Native支付回调链接中添加该链接"
} }

View File

@ -61,6 +61,8 @@
"formCheckbox":"复选框", "formCheckbox":"复选框",
"formDateTime":"日期", "formDateTime":"日期",
"formImageSelect":"图片上传", "formImageSelect":"图片上传",
"formFileSelect":"文件上传",
"formVideoSelect":"视频上传",
"formEditor":"富文本", "formEditor":"富文本",
"formNumber":"数字框", "formNumber":"数字框",
"pk":"主键", "pk":"主键",

View File

@ -29,5 +29,7 @@
"addCron": "添加任务", "addCron": "添加任务",
"cronTimeTips": "任务周期时间不能为空", "cronTimeTips": "任务周期时间不能为空",
"cronTipsOne": "启动计划任务方式:", "cronTipsOne": "启动计划任务方式:",
"cronTipsTwo": "1、使用命令启动php think cron:schedule 如果更改了任务周期、状态、删除任务等操作后,需要重新启动下 php think cron:schedule 确保生效" "cronTipsTwo": "1、使用命令启动php think workerman 如果更改了任务周期、状态、删除任务等操作后,需要重新启动下 php think workerman 确保生效",
"doOne": "执行一次",
"cronLog": "执行日志"
} }

View File

@ -0,0 +1,11 @@
{
"id": "日志编号",
"name": "任务名称",
"key": "key",
"class": "调用目标字符串",
"executeResult": "日志信息",
"status": "执行状态",
"executeTime": "执行时间",
"info": "详情",
"cronInfo": "日志详情"
}

View File

@ -32,15 +32,15 @@
</el-form-item> </el-form-item>
<el-form-item :label="t('routePath')" prop="router_path" v-show="formData.menu_type == 1"> <el-form-item :label="t('routePath')" prop="router_path" v-show="formData.menu_type == 1">
<el-input v-model="formData.router_path" :placeholder="t('routePathPlaceholder')" class="input-width" /> <el-input v-model.trim="formData.router_path" :placeholder="t('routePathPlaceholder')" class="input-width" />
</el-form-item> </el-form-item>
<el-form-item :label="t('viewPath')" prop="view_path" v-show="formData.menu_type == 1"> <el-form-item :label="t('viewPath')" prop="view_path" v-show="formData.menu_type == 1">
<el-input v-model="formData.view_path" :placeholder="t('viewPathPlaceholder')" class="input-width" /> <el-input v-model.trim="formData.view_path" :placeholder="t('viewPathPlaceholder')" class="input-width" />
</el-form-item> </el-form-item>
<el-form-item :label="t('authId')" prop="api_url" v-show="formData.menu_type != 0"> <el-form-item :label="t('authId')" prop="api_url" v-show="formData.menu_type != 0">
<el-input v-model="formData.api_url" :placeholder="t('authIdPlaceholder')" class="input-width"> <el-input v-model.trim="formData.api_url" :placeholder="t('authIdPlaceholder')" class="input-width">
<template #append> <template #append>
<el-select class="w-[90px] border-none" v-model="formData.methods"> <el-select class="w-[90px] border-none" v-model="formData.methods">
<el-option label="POST" value="post" /> <el-option label="POST" value="post" />
@ -73,7 +73,7 @@
</el-form-item> </el-form-item>
<el-form-item :label="t('menuShortName')"> <el-form-item :label="t('menuShortName')">
<el-input v-model="formData.menu_short_name" :placeholder="t('menuShortNamePlaceholder')" class="input-width" /> <el-input v-model.trim="formData.menu_short_name" :placeholder="t('menuShortNamePlaceholder')" class="input-width" />
</el-form-item> </el-form-item>
<el-form-item :label="t('sort')"> <el-form-item :label="t('sort')">

View File

@ -10,14 +10,14 @@
<div class="flex justify-between items-center mt-[20px]"> <div class="flex justify-between items-center mt-[20px]">
<el-form :inline="true" :model="sysUserLogTableData.searchParam" ref="searchFormRef"> <el-form :inline="true" :model="sysUserLogTableData.searchParam" ref="searchFormRef">
<el-form-item :label="t('ip')" prop="ip"> <el-form-item :label="t('ip')" prop="ip">
<el-input v-model="sysUserLogTableData.searchParam.ip" :placeholder="t('ipPlaceholder')" /> <el-input v-model.trim="sysUserLogTableData.searchParam.ip" :placeholder="t('ipPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('username')" prop="username"> <el-form-item :label="t('username')" prop="username">
<el-input v-model="sysUserLogTableData.searchParam.username" :placeholder="t('usernamePlaceholder')" /> <el-input v-model.trim="sysUserLogTableData.searchParam.username" :placeholder="t('usernamePlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('url')" prop="url"> <el-form-item :label="t('url')" prop="url">
<el-input v-model="sysUserLogTableData.searchParam.url" :placeholder="t('urlPlaceholder')" /> <el-input v-model.trim="sysUserLogTableData.searchParam.url" :placeholder="t('urlPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>

View File

@ -10,7 +10,7 @@
<div class="flex justify-between items-center mt-[20px]"> <div class="flex justify-between items-center mt-[20px]">
<el-form :inline="true" :model="roleTableData.searchParam" ref="searchFormRef"> <el-form :inline="true" :model="roleTableData.searchParam" ref="searchFormRef">
<el-form-item :label="t('roleName')" prop="search"> <el-form-item :label="t('roleName')" prop="search">
<el-input v-model="roleTableData.searchParam.search" class="w-[240px]" :placeholder="t('roleNamePlaceholder')" /> <el-input v-model.trim="roleTableData.searchParam.search" class="w-[240px]" :placeholder="t('roleNamePlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="loadRoleList()">{{ t('search') }}</el-button> <el-button type="primary" @click="loadRoleList()">{{ t('search') }}</el-button>

View File

@ -11,7 +11,7 @@
<h3 class="panel-title !text-sm">{{ t('aliappSet') }}</h3> <h3 class="panel-title !text-sm">{{ t('aliappSet') }}</h3>
<el-form-item :label="t('aliappName')"> <el-form-item :label="t('aliappName')">
<el-input v-model="formData.name" :placeholder="t('aliappNamePlaceholder')" class="input-width" clearable /> <el-input v-model.trim="formData.name" :placeholder="t('aliappNamePlaceholder')" class="input-width" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="t('aliappQrcode')"> <el-form-item :label="t('aliappQrcode')">
@ -24,11 +24,11 @@
<h3 class="panel-title !text-sm">{{ t('aliappDevelopInfo') }}</h3> <h3 class="panel-title !text-sm">{{ t('aliappDevelopInfo') }}</h3>
<el-form-item :label="t('aliappOriginal')"> <el-form-item :label="t('aliappOriginal')">
<el-input v-model="formData.private_key" :placeholder="t('aliappOriginalPlaceholder')" class="input-width" clearable /> <el-input v-model.trim="formData.private_key" :placeholder="t('aliappOriginalPlaceholder')" class="input-width" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="t('aliappAppid')"> <el-form-item :label="t('aliappAppid')">
<el-input v-model="formData.app_id" :placeholder="t('appidPlaceholder')" class="input-width" clearable /> <el-input v-model.trim="formData.app_id" :placeholder="t('appidPlaceholder')" class="input-width" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="t('countersignType')"> <el-form-item :label="t('countersignType')">
@ -61,7 +61,7 @@
<h3 class="panel-title !text-sm">{{ t('theServerSetting') }}</h3> <h3 class="panel-title !text-sm">{{ t('theServerSetting') }}</h3>
<el-form-item label="AESKey"> <el-form-item label="AESKey">
<el-input v-model="formData.aes_key" :placeholder="t('AESKeyPlaceholder')" class="input-width" show-word-limit clearable /> <el-input v-model.trim="formData.aes_key" :placeholder="t('AESKeyPlaceholder')" class="input-width" show-word-limit clearable />
</el-form-item> </el-form-item>
</el-card> </el-card>

View File

@ -16,7 +16,7 @@
<el-switch v-model="formData.is_open"/> <el-switch v-model="formData.is_open"/>
</el-form-item> </el-form-item>
<el-form-item :label="t('PCDomainName')"> <el-form-item :label="t('pCDomainName')">
<el-input :model-value="formData.request_url" class="input-width" :readonly="true"> <el-input :model-value="formData.request_url" class="input-width" :readonly="true">
<template #append> <template #append>
<div class="cursor-pointer" @click="copyEvent(formData.request_url)">{{ t('copy') }}</div> <div class="cursor-pointer" @click="copyEvent(formData.request_url)">{{ t('copy') }}</div>

View File

@ -35,8 +35,7 @@
<el-table-column :label="t('response')" min-width="180"> <el-table-column :label="t('response')" min-width="180">
<template #default="{ row }"> <template #default="{ row }">
<div v-for="(item, index) in row.weapp.content" :key="'a' + index" class="text-left"> <div v-for="(item, index) in row.weapp.content" :key="'a' + index" class="text-left">{{ item.join(":") }}</div>
{{ item.join(":") }}</div>
</template> </template>
</el-table-column> </el-table-column>

View File

@ -4,7 +4,7 @@
<el-form :model="buttonData" label-width="140px" ref="formRef" :rules="formRules" class="page-form mt-[30px]"> <el-form :model="buttonData" label-width="140px" ref="formRef" :rules="formRules" class="page-form mt-[30px]">
<el-form-item :label="t('menuName')" prop="name"> <el-form-item :label="t('menuName')" prop="name">
<el-input v-model="buttonData.name" :placeholder="t('menuNamePlaceholder')" class="input-width" clearable /> <el-input v-model.trim="buttonData.name" :placeholder="t('menuNamePlaceholder')" class="input-width" clearable />
<div class="form-tip">{{ buttonData.sub_button ? t('menuNameTips') : t('subMenuNameTips') }}</div> <div class="form-tip">{{ buttonData.sub_button ? t('menuNameTips') : t('subMenuNameTips') }}</div>
</el-form-item> </el-form-item>
@ -17,15 +17,15 @@
</el-form-item> </el-form-item>
<el-form-item :label="t('webpageUrl')" prop="url"> <el-form-item :label="t('webpageUrl')" prop="url">
<el-input v-model="buttonData.url" :placeholder="t('webpageUrlPlaceholder')" class="input-width" clearable /> <el-input v-model.trim="buttonData.url" :placeholder="t('webpageUrlPlaceholder')" class="input-width" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="t('weappAppid')" prop="appid" v-show="buttonData.type == 'miniprogram'"> <el-form-item :label="t('weappAppid')" prop="appid" v-show="buttonData.type == 'miniprogram'">
<el-input v-model="buttonData.appid" :placeholder="t('weappAppidPlaceholder')" class="input-width" clearable /> <el-input v-model.trim="buttonData.appid" :placeholder="t('weappAppidPlaceholder')" class="input-width" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="t('weappPage')" prop="pagepath" v-show="buttonData.type == 'miniprogram'"> <el-form-item :label="t('weappPage')" prop="pagepath" v-show="buttonData.type == 'miniprogram'">
<el-input v-model="buttonData.pagepath" :placeholder="t('weappPagePlaceholder')" class="input-width" clearable /> <el-input v-model.trim="buttonData.pagepath" :placeholder="t('weappPagePlaceholder')" class="input-width" clearable />
</el-form-item> </el-form-item>
</template> </template>
@ -39,7 +39,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
import { t } from '@/lang' import { t } from '@/lang'
import { strByteLength } from '@/utils/common' import { strByteLength, isUrl } from '@/utils/common'
const prop = defineProps({ const prop = defineProps({
data: { data: {
@ -84,7 +84,20 @@ const formRules = computed(() => {
} }
], ],
url: [ url: [
{ required: !buttonData.value.sub_button || !buttonData.value.sub_button.length, message: t('webpageUrlPlaceholder'), trigger: 'blur' } { required: !buttonData.value.sub_button || !buttonData.value.sub_button.length, message: t('webpageUrlPlaceholder'), trigger: 'blur' },
{
validator: (rule: any, value: string, callback: any) => {
if (!buttonData.value.sub_button || !buttonData.value.sub_button.length) {
if (!isUrl(value)) {
callback(new Error(t('menuUrlErrorTips')))
} else {
callback()
}
} else {
callback()
}
}
}
], ],
appid: [ appid: [
{ required: ((!buttonData.value.sub_button || !buttonData.value.sub_button.length) && buttonData.value.type == 'miniprogram'), message: t('weappAppidPlaceholder'), trigger: 'blur' } { required: ((!buttonData.value.sub_button || !buttonData.value.sub_button.length) && buttonData.value.type == 'miniprogram'), message: t('weappAppidPlaceholder'), trigger: 'blur' }

View File

@ -25,7 +25,7 @@
<div class="py-[20px] px-[30px] h-[350px]"> <div class="py-[20px] px-[30px] h-[350px]">
<div v-if="formData.msgtype == 'text'"> <div v-if="formData.msgtype == 'text'">
<el-input <el-input
v-model="formData.text.content" :rows="5" type="textarea" placeholder="" maxlength="600" :show-word-limit="true" v-model.trim="formData.text.content" :rows="5" type="textarea" placeholder="" maxlength="600" :show-word-limit="true"
resize="none" resize="none"
input-style="box-shadow: none;height:300px" input-style="box-shadow: none;height:300px"
/> />
@ -94,14 +94,14 @@
<div v-if="formData.msgtype == 'miniprogrampage'"> <div v-if="formData.msgtype == 'miniprogrampage'">
<el-form :model="formData.miniprogrampage" label-width="140px" class="page-form" ref="formRef" :rules="formRules"> <el-form :model="formData.miniprogrampage" label-width="140px" class="page-form" ref="formRef" :rules="formRules">
<el-form-item label="小程序APPID" prop="appid"> <el-form-item label="小程序APPID" prop="appid">
<el-input v-model="formData.miniprogrampage.appid" class="input-width"/> <el-input v-model.trim="formData.miniprogrampage.appid" class="input-width"/>
<div class="form-tip">小程序需已经与公众号关联</div> <div class="form-tip">小程序需已经与公众号关联</div>
</el-form-item> </el-form-item>
<el-form-item label="小程序卡片标题" prop="title"> <el-form-item label="小程序卡片标题" prop="title">
<el-input v-model="formData.miniprogrampage.title" class="input-width"/> <el-input v-model.trim="formData.miniprogrampage.title" class="input-width"/>
</el-form-item> </el-form-item>
<el-form-item label="小程序的页面路径" prop="pagepath"> <el-form-item label="小程序的页面路径" prop="pagepath">
<el-input v-model="formData.miniprogrampage.pagepath" class="input-width"/> <el-input v-model.trim="formData.miniprogrampage.pagepath" class="input-width"/>
</el-form-item> </el-form-item>
<el-form-item label="小程序卡片图片" prop="thumb_media_url"> <el-form-item label="小程序卡片图片" prop="thumb_media_url">
<upload-image :limit="1" width="100px" height="100px" v-model="formData.miniprogrampage.thumb_media_url" v-if="formData.miniprogrampage.thumb_media_url"/> <upload-image :limit="1" width="100px" height="100px" v-model="formData.miniprogrampage.thumb_media_url" v-if="formData.miniprogrampage.thumb_media_url"/>

View File

@ -94,7 +94,7 @@ const router = useRouter()
const pageName = route.meta.title const pageName = route.meta.title
const showDialog = ref(false) const showDialog = ref(false)
const formData = reactive<Record<string, string>>({ const formData: any = reactive({
id: 0, id: 0,
name: '', name: '',
keyword: '', keyword: '',

View File

@ -27,13 +27,13 @@
<el-dialog v-model="dialogVisible" :title="type != 'edit' ? t('addDictData') : t('editDictData')" width="480" class="diy-dialog-wrap" :destroy-on-close="true"> <el-dialog v-model="dialogVisible" :title="type != 'edit' ? t('addDictData') : t('editDictData')" width="480" class="diy-dialog-wrap" :destroy-on-close="true">
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form"> <el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form">
<el-form-item :label="t('name')"> <el-form-item :label="t('name')">
<el-input v-model="name" disabled class="input-width" /> <el-input v-model.trim="name" disabled class="input-width" />
</el-form-item> </el-form-item>
<el-form-item :label="t('dataName')" prop="name"> <el-form-item :label="t('dataName')" prop="name">
<el-input v-model="formData.name" clearable :placeholder="t('dataNamePlaceholder')" class="input-width" /> <el-input v-model.trim="formData.name" clearable :placeholder="t('dataNamePlaceholder')" class="input-width" />
</el-form-item> </el-form-item>
<el-form-item :label="t('dataValue')" prop="value"> <el-form-item :label="t('dataValue')" prop="value">
<el-input v-model="formData.value" clearable :placeholder="t('dataValuePlaceholder')" class="input-width" /> <el-input v-model.trim="formData.value" clearable :placeholder="t('dataValuePlaceholder')" class="input-width" />
</el-form-item> </el-form-item>
<el-form-item :label="t('sort')" prop="sort"> <el-form-item :label="t('sort')" prop="sort">
<div> <div>
@ -42,7 +42,7 @@
</div> </div>
</el-form-item> </el-form-item>
<el-form-item :label="t('memo')"> <el-form-item :label="t('memo')">
<el-input v-model="formData.memo" type="textarea" clearable :placeholder="t('momePlaceholder')" class="input-width" /> <el-input v-model.trim="formData.memo" type="textarea" clearable :placeholder="t('momePlaceholder')" class="input-width" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>

View File

@ -6,9 +6,10 @@
</el-form-item> </el-form-item>
<el-form-item :label="t('key')" prop="key"> <el-form-item :label="t('key')" prop="key">
<el-input v-model.trim="formData.key" clearable maxlength="40" show-word-limit :placeholder="t('keyPlaceholder')" class="input-width" /> <el-input v-model.trim="formData.key" clearable maxlength="40" show-word-limit :placeholder="t('keyPlaceholder')" class="input-width" />
<p class="form-tip">{{ t('keyFormatTips') }}</p>
</el-form-item> </el-form-item>
<el-form-item :label="t('memo')"> <el-form-item :label="t('memo')">
<el-input v-model="formData.memo" type="textarea" clearable :placeholder="t('memoPlaceholder')" class="input-width" /> <el-input v-model.trim="formData.memo" type="textarea" clearable :placeholder="t('memoPlaceholder')" class="input-width" />
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -50,7 +51,17 @@ const formRules = computed(() => {
{ required: true, message: t('namePlaceholder'), trigger: 'blur' } { required: true, message: t('namePlaceholder'), trigger: 'blur' }
], ],
key: [ key: [
{ required: true, message: t('keyPlaceholder'), trigger: 'blur' } { required: true, message: t('keyPlaceholder'), trigger: 'blur' },
{
validator: (rule: any, value: any, callback: any) => {
if (/^[a-zA-Z_]+$/.test(value)) {
callback()
} else {
callback(new Error(t('keyFormatTips')))
}
},
trigger: 'blur'
}
], ],
data: [ data: [
{ required: true, message: t('dataPlaceholder'), trigger: 'blur' } { required: true, message: t('dataPlaceholder'), trigger: 'blur' }

View File

@ -13,10 +13,10 @@
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> <el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="dictTable.searchParam" ref="searchFormRef"> <el-form :inline="true" :model="dictTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('name')" prop="name"> <el-form-item :label="t('name')" prop="name">
<el-input v-model="dictTable.searchParam.name" :placeholder="t('namePlaceholder')" /> <el-input v-model.trim="dictTable.searchParam.name" :placeholder="t('namePlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('key')" prop="key"> <el-form-item :label="t('key')" prop="key">
<el-input v-model="dictTable.searchParam.key" :placeholder="t('keyPlaceholder')" /> <el-input v-model.trim="dictTable.searchParam.key" :placeholder="t('keyPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>

View File

@ -87,15 +87,15 @@
<el-input v-model.trim="item.title.text" :placeholder="t('activeCubeTitlePlaceholder')" clearable maxlength="4" show-word-limit/> <el-input v-model.trim="item.title.text" :placeholder="t('activeCubeTitlePlaceholder')" clearable maxlength="4" show-word-limit/>
</el-form-item> </el-form-item>
<el-form-item :label="t('activeCubeSubTitleTextColor')" v-show="selectBlockStyle.value == 'style-3'"> <el-form-item :label="t('activeCubeSubTitleTextColor')" v-show="diyStore.editComponent.blockStyle.value == 'style-3'">
<el-color-picker v-model="item.title.textColor" show-alpha :predefine="diyStore.predefineColors" /> <el-color-picker v-model="item.title.textColor" show-alpha :predefine="diyStore.predefineColors" />
</el-form-item> </el-form-item>
<el-form-item :label="t('activeCubeSubTitle')" v-if="selectBlockStyle.value != 'style-3'"> <el-form-item :label="t('activeCubeSubTitle')" v-if="diyStore.editComponent.blockStyle.value != 'style-3'">
<el-input v-model.trim="item.subTitle.text" :placeholder="t('activeCubeSubTitlePlaceholder')" clearable :maxlength="(selectBlockStyle.value != 'style-4' ? '6' : '4')" show-word-limit/> <el-input v-model.trim="item.subTitle.text" :placeholder="t('activeCubeSubTitlePlaceholder')" clearable :maxlength="(diyStore.editComponent.blockStyle.value != 'style-4' ? '6' : '4')" show-word-limit/>
</el-form-item> </el-form-item>
<div v-show="selectBlockStyle.value == 'style-4'"> <div v-show="diyStore.editComponent.blockStyle.value == 'style-4'">
<el-form-item :label="t('activeCubeSubTitleTextColor')"> <el-form-item :label="t('activeCubeSubTitleTextColor')">
<el-color-picker v-model="item.subTitle.textColor" show-alpha :predefine="diyStore.predefineColors" /> <el-color-picker v-model="item.subTitle.textColor" show-alpha :predefine="diyStore.predefineColors" />
</el-form-item> </el-form-item>
@ -111,7 +111,7 @@
</el-form-item> </el-form-item>
</div> </div>
<div v-show="selectBlockStyle.value != 'style-4' && selectBlockStyle.value != 'style-3'"> <div v-show="diyStore.editComponent.blockStyle.value != 'style-4' && diyStore.editComponent.blockStyle.value != 'style-3'">
<el-form-item :label="t('activeCubeButton')"> <el-form-item :label="t('activeCubeButton')">
<el-input v-model.trim="item.moreTitle.text" :placeholder="t('activeCubeButtonPlaceholder')" clearable maxlength="3" show-word-limit/> <el-input v-model.trim="item.moreTitle.text" :placeholder="t('activeCubeButtonPlaceholder')" clearable maxlength="3" show-word-limit/>
</el-form-item> </el-form-item>

View File

@ -89,7 +89,7 @@
</el-form-item> </el-form-item>
<el-form-item :label="t('dataSources')"> <el-form-item :label="t('dataSources')">
<el-input v-model="item.diy_title" :placeholder="t('selectDiyPagePlaceholder')" readonly class="select-diy-page-input" @click="diyPageShowDialogOpen(index)"> <el-input v-model.trim="item.diy_title" :placeholder="t('selectDiyPagePlaceholder')" readonly class="select-diy-page-input" @click="diyPageShowDialogOpen(index)">
<template #suffix> <template #suffix>
<div @click.stop="tabClear(index)"> <div @click.stop="tabClear(index)">
<el-icon v-if="item.diy_title"> <el-icon v-if="item.diy_title">
@ -248,7 +248,7 @@ import useDiyStore from '@/stores/modules/diy'
import { ref, reactive, watch, onMounted, nextTick } from 'vue' import { ref, reactive, watch, onMounted, nextTick } from 'vue'
import { ElTable } from 'element-plus' import { ElTable } from 'element-plus'
import Sortable from 'sortablejs' import Sortable from 'sortablejs'
import { range } from 'lodash-es' import { range,cloneDeep } from 'lodash-es'
import { getDiyPageListByCarouselSearch } from '@/app/api/diy' import { getDiyPageListByCarouselSearch } from '@/app/api/diy'
@ -427,6 +427,8 @@ const loadDiyPageList = (page: number = 1) => {
newData.push(data[i]); newData.push(data[i]);
} }
} }
} else {
newData = cloneDeep(data); //
} }
if (isExistCount) { if (isExistCount) {
res.data.total = res.data.total - isExistCount; res.data.total = res.data.total - isExistCount;

View File

@ -32,7 +32,7 @@
<el-form-item :label="t('graphicNavShowStyle')"> <el-form-item :label="t('graphicNavShowStyle')">
<el-radio-group v-model="diyStore.editComponent.showStyle" @change="changeShowStyle"> <el-radio-group v-model="diyStore.editComponent.showStyle" @change="changeShowStyle">
<el-radio :label="'fixed'">{{t('graphicNavStyleFixed')}}</el-radio> <el-radio :label="'fixed'">{{t('graphicNavStyleFixed')}}</el-radio>
<el-radio :label="'singleSlide'">{{t('graphicNavStyleSingleSlide')}}</el-radio> <el-radio :label="'singleSlide'">{{diyStore.editComponent.pageCount == 2 ? t('graphicNavStyleMultiLine') : t('graphicNavStyleSingleSlide')}}</el-radio>
<el-radio :label="'pageSlide'">{{t('graphicNavStylePageSlide')}}</el-radio> <el-radio :label="'pageSlide'">{{t('graphicNavStylePageSlide')}}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>

View File

@ -54,12 +54,12 @@
<el-button class="page-btn absolute right-[20px]" @click="diyStore.changeCurrentIndex(-99)">{{ t('pageSet') }}</el-button> <el-button class="page-btn absolute right-[20px]" @click="diyStore.changeCurrentIndex(-99)">{{ t('pageSet') }}</el-button>
<div class="diy-view-wrap w-[375px] shadow-lg mx-auto"> <div class="diy-view-wrap w-[375px] shadow-lg mx-auto">
<div class="preview-head bg-no-repeat bg-center bg-cover cursor-pointer h-[64px]" :class="[diyStore.global.topStatusBar.style]" :style="{backgroundColor :diyStore.global.topStatusBar.bgColor}" @click="diyStore.changeCurrentIndex(-99)"> <div class="preview-head bg-no-repeat bg-center bg-cover cursor-pointer h-[64px]" :class="[diyStore.global.topStatusBar.style]" :style="{backgroundColor :diyStore.global.topStatusBar.bgColor}" @click="diyStore.changeCurrentIndex(-99)">
<div v-if="diyStore.global.topStatusBar.style == 'style-1'" class="content-wrap"> <div v-if="diyStore.global.topStatusBar.style == 'style-1' && diyStore.global.topStatusBar.isShow" class="content-wrap">
<div class="title-wrap" :style="{ fontSize: '14px', color: diyStore.global.topStatusBar.textColor, textAlign: diyStore.global.topStatusBar.textAlign }"> <div class="title-wrap" :style="{ fontSize: '14px', color: diyStore.global.topStatusBar.textColor, textAlign: diyStore.global.topStatusBar.textAlign }">
{{ diyStore.global.title }} {{ diyStore.global.title }}
</div> </div>
</div> </div>
<div v-if="diyStore.global.topStatusBar.style == 'style-2'" class="content-wrap"> <div v-if="diyStore.global.topStatusBar.style == 'style-2' && diyStore.global.topStatusBar.isShow" class="content-wrap">
<div class="title-wrap" :style="{ color: diyStore.global.topStatusBar.textColor }"> <div class="title-wrap" :style="{ color: diyStore.global.topStatusBar.textColor }">
<div class="h-[28px] max-w-[150px] mr-[8px]" v-if="diyStore.global.topStatusBar.imgUrl"> <div class="h-[28px] max-w-[150px] mr-[8px]" v-if="diyStore.global.topStatusBar.imgUrl">
<img class="max-w-[100%] max-h-[100%]" :src="img(diyStore.global.topStatusBar.imgUrl)" mode="heightFix" /> <img class="max-w-[100%] max-h-[100%]" :src="img(diyStore.global.topStatusBar.imgUrl)" mode="heightFix" />
@ -67,16 +67,16 @@
<div :style="{ color: diyStore.global.topStatusBar.textColor }">{{ diyStore.global.title }}</div> <div :style="{ color: diyStore.global.topStatusBar.textColor }">{{ diyStore.global.title }}</div>
</div> </div>
</div> </div>
<div v-if="diyStore.global.topStatusBar.style == 'style-3'" class="content-wrap"> <div v-if="diyStore.global.topStatusBar.style == 'style-3' && diyStore.global.topStatusBar.isShow" class="content-wrap">
<div class="title-wrap" v-if="diyStore.global.topStatusBar.imgUrl"> <div class="title-wrap" v-if="diyStore.global.topStatusBar.imgUrl">
<img class="max-w-[100%] max-h-[100%]" :src="img(diyStore.global.topStatusBar.imgUrl)" /> <img class="max-w-[100%] max-h-[100%]" :src="img(diyStore.global.topStatusBar.imgUrl)" />
</div> </div>
<div class="search"> <div class="search">
<span class="iconfont iconsousuo absolute left-[10px]"></span> <span class="nc-iconfont nc-icon-sousuo-duanV6xx1 !text-[12px] absolute left-[10px]"></span>
<span class="text-[14px]">{{diyStore.global.topStatusBar.inputPlaceholder}}</span> <span class="text-[12px]">{{diyStore.global.topStatusBar.inputPlaceholder}}</span>
</div> </div>
</div> </div>
<div v-if="diyStore.global.topStatusBar.style == 'style-4'" class="content-wrap"> <div v-if="diyStore.global.topStatusBar.style == 'style-4' && diyStore.global.topStatusBar.isShow" class="content-wrap">
<span class="iconfont iconxiazai19 !text-[14px]" :style="{ color: diyStore.global.topStatusBar.textColor }"></span> <span class="iconfont iconxiazai19 !text-[14px]" :style="{ color: diyStore.global.topStatusBar.textColor }"></span>
<div class="title-wrap" :style="{ color: diyStore.global.topStatusBar.textColor }">我的位置</div> <div class="title-wrap" :style="{ color: diyStore.global.topStatusBar.textColor }">我的位置</div>
<span class="iconfont iconxiangyoujiantou !text-[12px]" :style="{ color: diyStore.global.topStatusBar.textColor }"></span> <span class="iconfont iconxiangyoujiantou !text-[12px]" :style="{ color: diyStore.global.topStatusBar.textColor }"></span>
@ -109,7 +109,7 @@
<div class="font-bold text-xl mb-[40px]">{{ t('developTitle') }}</div> <div class="font-bold text-xl mb-[40px]">{{ t('developTitle') }}</div>
<div class="mb-[20px] flex flex-col"> <div class="mb-[20px] flex flex-col">
<text class="mb-[10px]">{{ t('wapDomain') }}</text> <text class="mb-[10px]">{{ t('wapDomain') }}</text>
<el-input v-model="wapDomain" :placeholder="t('wapDomainPlaceholder')" clearable /> <el-input v-model.trim="wapDomain" :placeholder="t('wapDomainPlaceholder')" clearable />
</div> </div>
<el-button type="primary" @click="saveWapDomain">{{ t('confirm') }}</el-button> <el-button type="primary" @click="saveWapDomain">{{ t('confirm') }}</el-button>
<el-button type="primary" @click="settingTips()" plain>{{ t('settingTips') }}</el-button> <el-button type="primary" @click="settingTips()" plain>{{ t('settingTips') }}</el-button>
@ -337,15 +337,14 @@ const changeTemplatePage = (value:any)=> {
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
diyStore.changeCurrentIndex(-99) diyStore.changeCurrentIndex(-99)
diyStore.init(); //
if (value) { if (value) {
let data = templatePages[value].data; let data = cloneDeep(templatePages[value].data);
diyStore.global = data.global; diyStore.global = data.global;
if (data.value.length) { if (data.value.length) {
diyStore.value = data.value diyStore.value = data.value
} }
} else { } else {
//
diyStore.init();
if (route.query.title) diyStore.global.title = diyStore.typeName if (route.query.title) diyStore.global.title = diyStore.typeName
} }
}).catch(() => { }).catch(() => {
@ -353,15 +352,14 @@ const changeTemplatePage = (value:any)=> {
template.value = oldTemplate.value; template.value = oldTemplate.value;
}); });
} else { } else {
diyStore.init(); //
if (value) { if (value) {
let data = templatePages[value].data; let data = cloneDeep(templatePages[value].data);
diyStore.global = data.global; diyStore.global = data.global;
if (data.value.length) { if (data.value.length) {
diyStore.value = data.value diyStore.value = data.value
} }
} else { } else {
//
diyStore.init();
if (route.query.title) diyStore.global.title = diyStore.typeName if (route.query.title) diyStore.global.title = diyStore.typeName
} }
} }
@ -793,6 +791,7 @@ const settingTips = () => {
align-items: center; align-items: center;
margin-right: 105px; margin-right: 105px;
overflow: hidden; overflow: hidden;
box-sizing: border-box;
span { span {
overflow: hidden; // overflow: hidden; //

View File

@ -12,7 +12,7 @@
<div class="font-bold text-xl mb-[40px]">{{ t('developTitle') }}</div> <div class="font-bold text-xl mb-[40px]">{{ t('developTitle') }}</div>
<div class="mb-[20px] flex flex-col"> <div class="mb-[20px] flex flex-col">
<text class="mb-[10px]">{{ t('wapDomain') }}</text> <text class="mb-[10px]">{{ t('wapDomain') }}</text>
<el-input v-model="wapDomain" :placeholder="t('wapDomainPlaceholder')" clearable /> <el-input v-model.trim="wapDomain" :placeholder="t('wapDomainPlaceholder')" clearable />
</div> </div>
<div class="flex"> <div class="flex">
<el-button type="primary" @click="saveDomain()">{{ t('confirm') }}</el-button> <el-button type="primary" @click="saveDomain()">{{ t('confirm') }}</el-button>
@ -80,7 +80,7 @@ const page: any = reactive({})
const router = useRouter() const router = useRouter()
const wapDomain = ref('') const wapDomain = ref('')
const wapImage = ref('') const wapImage = ref('')
const link = ref({ const link: any = ref({
name: '' name: ''
}) })

View File

@ -10,7 +10,7 @@
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> <el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="diyPageTableData.searchParam" ref="searchFormDiyPageRef"> <el-form :inline="true" :model="diyPageTableData.searchParam" ref="searchFormDiyPageRef">
<el-form-item :label="t('title')" prop="title"> <el-form-item :label="t('title')" prop="title">
<el-input v-model="diyPageTableData.searchParam.title" :placeholder="t('titlePlaceholder')" /> <el-input v-model.trim="diyPageTableData.searchParam.title" :placeholder="t('titlePlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('forAddon')" prop="addon_name"> <el-form-item :label="t('forAddon')" prop="addon_name">
<el-select v-model="diyPageTableData.searchParam.addon_name" :placeholder="t('forAddonPlaceholder')" @change="handleSelectAddonChange"> <el-select v-model="diyPageTableData.searchParam.addon_name" :placeholder="t('forAddonPlaceholder')" @change="handleSelectAddonChange">
@ -70,14 +70,14 @@
</el-card> </el-card>
<!--添加页面--> <!--添加页面-->
<el-dialog v-model="dialogVisible" :title="t('addPageTips')" width="25%"> <el-dialog v-model="dialogVisible" :title="t('addPageTips')" width="350px">
<el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules"> <el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules">
<el-form-item :label="t('title')" prop="title"> <el-form-item :label="t('title')" prop="title">
<el-input v-model="formData.title" :placeholder="t('titlePlaceholder')" clearable maxlength="12" show-word-limit class="w-full" /> <el-input v-model.trim="formData.title" :placeholder="t('titlePlaceholder')" clearable maxlength="12" show-word-limit class="w-full" />
</el-form-item> </el-form-item>
<el-form-item :label="t('typeName')" prop="type"> <el-form-item :label="t('typeName')" prop="type">
<el-select v-model="formData.type" :placeholder="t('pageTypePlaceholder')" class="w-full"> <el-select v-model="formData.type" :placeholder="t('pageTypePlaceholder')" class="!w-full">
<el-option v-for="(item, key) in pageType" :label="item.title" :value="key" :key="key"/> <el-option v-for="(item, key) in pageType" :label="item.title" :value="key" :key="key"/>
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -102,10 +102,10 @@
<span>{{ sharePage }}</span> <span>{{ sharePage }}</span>
</el-form-item> </el-form-item>
<el-form-item :label="t('shareTitle')" prop="title"> <el-form-item :label="t('shareTitle')" prop="title">
<el-input v-model="shareFormData[tabShareType].title" :placeholder="t('shareTitlePlaceholder')" clearable maxlength="30" show-word-limit /> <el-input v-model.trim="shareFormData[tabShareType].title" :placeholder="t('shareTitlePlaceholder')" clearable maxlength="30" show-word-limit />
</el-form-item> </el-form-item>
<el-form-item :label="t('shareDesc')" prop="desc" v-if="tabShareType == 'wechat'"> <el-form-item :label="t('shareDesc')" prop="desc" v-if="tabShareType == 'wechat'">
<el-input v-model="shareFormData[tabShareType].desc" :placeholder="t('shareDescPlaceholder')" type="textarea" rows="4" clearable maxlength="100" show-word-limit /> <el-input v-model.trim="shareFormData[tabShareType].desc" :placeholder="t('shareDescPlaceholder')" type="textarea" rows="4" clearable maxlength="100" show-word-limit />
</el-form-item> </el-form-item>
<el-form-item :label="t('shareImageUrl')" prop="url"> <el-form-item :label="t('shareImageUrl')" prop="url">
<upload-image v-model="shareFormData[tabShareType].url" :limit="1" /> <upload-image v-model="shareFormData[tabShareType].url" :limit="1" />

View File

@ -11,7 +11,7 @@
<div class="font-bold text-xl mb-[40px]">{{ t('developTitle') }}</div> <div class="font-bold text-xl mb-[40px]">{{ t('developTitle') }}</div>
<div class="mb-[20px] flex flex-col"> <div class="mb-[20px] flex flex-col">
<text class="mb-[10px]">{{ t('wapDomain') }}</text> <text class="mb-[10px]">{{ t('wapDomain') }}</text>
<el-input v-model="wapDomain" :placeholder="t('wapDomainPlaceholder')" clearable /> <el-input v-model.trim="wapDomain" :placeholder="t('wapDomainPlaceholder')" clearable />
</div> </div>
<div class="flex"> <div class="flex">
<el-button type="primary" @click="saveDomain()">{{ t('confirm') }}</el-button> <el-button type="primary" @click="saveDomain()">{{ t('confirm') }}</el-button>
@ -105,7 +105,7 @@ const page: any = reactive({})
const router = useRouter() const router = useRouter()
const wapDomain = ref('') const wapDomain = ref('')
const wapImage = ref('') const wapImage = ref('')
const link = ref({ const link: any = ref({
name: '' name: ''
}) })

View File

@ -9,7 +9,7 @@
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> <el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="diyRouteTableData.searchParam" ref="searchFormDiyRouteRef"> <el-form :inline="true" :model="diyRouteTableData.searchParam" ref="searchFormDiyRouteRef">
<el-form-item :label="t('title')" prop="title"> <el-form-item :label="t('title')" prop="title">
<el-input v-model="diyRouteTableData.searchParam.title" :placeholder="t('titlePlaceholder')" /> <el-input v-model.trim="diyRouteTableData.searchParam.title" :placeholder="t('titlePlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('forAddon')" prop="addon_name"> <el-form-item :label="t('forAddon')" prop="addon_name">
<el-select v-model="diyRouteTableData.searchParam.addon_name" :placeholder="t('forAddonPlaceholder')"> <el-select v-model="diyRouteTableData.searchParam.addon_name" :placeholder="t('forAddonPlaceholder')">
@ -70,10 +70,10 @@
<span>{{ sharePage }}</span> <span>{{ sharePage }}</span>
</el-form-item> </el-form-item>
<el-form-item :label="t('shareTitle')" prop="title"> <el-form-item :label="t('shareTitle')" prop="title">
<el-input v-model="shareFormData[tabShareType].title" :placeholder="t('shareTitlePlaceholder')" clearable maxlength="30" show-word-limit /> <el-input v-model.trim="shareFormData[tabShareType].title" :placeholder="t('shareTitlePlaceholder')" clearable maxlength="30" show-word-limit />
</el-form-item> </el-form-item>
<el-form-item :label="t('shareDesc')" prop="desc" v-if="tabShareType == 'wechat'"> <el-form-item :label="t('shareDesc')" prop="desc" v-if="tabShareType == 'wechat'">
<el-input v-model="shareFormData[tabShareType].desc" :placeholder="t('shareDescPlaceholder')" type="textarea" rows="4" clearable maxlength="100" show-word-limit /> <el-input v-model.trim="shareFormData[tabShareType].desc" :placeholder="t('shareDescPlaceholder')" type="textarea" rows="4" clearable maxlength="100" show-word-limit />
</el-form-item> </el-form-item>
<el-form-item :label="t('shareImageUrl')" prop="url"> <el-form-item :label="t('shareImageUrl')" prop="url">
<upload-image v-model="shareFormData[tabShareType].url" :limit="1" /> <upload-image v-model="shareFormData[tabShareType].url" :limit="1" />

View File

@ -17,7 +17,13 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="key" :label="t('key')" min-width="80"/> <el-table-column prop="key" :label="t('key')" min-width="120"/>
<el-table-column :label="t('type')" min-width="120">
<template #default="{ row }">
<span>{{ row.info.type === 'app' ? t('app') : t('addon') }}</span>
</template>
</el-table-column>
<el-table-column :label="t('operation')" fixed="right" align="right" min-width="160"> <el-table-column :label="t('operation')" fixed="right" align="right" min-width="160">
<template #default="{ row }"> <template #default="{ row }">

View File

@ -45,7 +45,7 @@
</div> </div>
</el-form-item> </el-form-item>
<el-form-item :label="t('navTitleOne')"> <el-form-item :label="t('navTitleOne')">
<el-input class="!w-[215px]" v-model="item.text" :placeholder="t('titleContent')" maxlength="5" show-word-limit /> <el-input class="!w-[215px]" v-model.trim="item.text" :placeholder="t('titleContent')" maxlength="5" show-word-limit />
</el-form-item> </el-form-item>
<el-form-item :label="t('navLinkOne')"> <el-form-item :label="t('navLinkOne')">
<diy-link v-model="item.link" @confirm="diyLinkFn" /> <diy-link v-model="item.link" @confirm="diyLinkFn" />
@ -69,21 +69,21 @@
<el-form-item :label="t('textColor')"> <el-form-item :label="t('textColor')">
<div class="flex align-center"> <div class="flex align-center">
<el-color-picker v-model="diyBottomData.value.textColor" /> <el-color-picker v-model="diyBottomData.value.textColor" />
<el-input class="ml-[10px]" v-model="diyBottomData.value.textColor" disabled /> <el-input class="ml-[10px]" v-model.trim="diyBottomData.value.textColor" disabled />
<el-button class="ml-[10px]" type="primary" @click="diyBottomData.value.textColor = '#333333'">{{ t('reset') }}</el-button> <el-button class="ml-[10px]" type="primary" @click="diyBottomData.value.textColor = '#333333'">{{ t('reset') }}</el-button>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item :label="t('textSelectColor')"> <el-form-item :label="t('textSelectColor')">
<div class="flex align-center"> <div class="flex align-center">
<el-color-picker v-model="diyBottomData.value.textHoverColor" /> <el-color-picker v-model="diyBottomData.value.textHoverColor" />
<el-input class="ml-[10px]" v-model="diyBottomData.value.textHoverColor" disabled /> <el-input class="ml-[10px]" v-model.trim="diyBottomData.value.textHoverColor" disabled />
<el-button class="ml-[10px]" type="primary" @click="diyBottomData.value.textHoverColor = '#333333'">{{ t('reset') }}</el-button> <el-button class="ml-[10px]" type="primary" @click="diyBottomData.value.textHoverColor = '#333333'">{{ t('reset') }}</el-button>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item :label="t('backgroundColor')"> <el-form-item :label="t('backgroundColor')">
<div class="flex align-center"> <div class="flex align-center">
<el-color-picker v-model="diyBottomData.value.backgroundColor" /> <el-color-picker v-model="diyBottomData.value.backgroundColor" />
<el-input class="ml-[10px]" v-model="diyBottomData.value.backgroundColor" disabled /> <el-input class="ml-[10px]" v-model.trim="diyBottomData.value.backgroundColor" disabled />
<el-button class="ml-[10px]" type="primary" @click="diyBottomData.value.backgroundColor = '#FFFFFF'">{{ t('reset') }}</el-button> <el-button class="ml-[10px]" type="primary" @click="diyBottomData.value.backgroundColor = '#FFFFFF'">{{ t('reset') }}</el-button>
</div> </div>
</el-form-item> </el-form-item>

View File

@ -51,7 +51,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item :label="t('tradeNo')" prop="trade_no"> <el-form-item :label="t('tradeNo')" prop="trade_no">
<el-input v-model="siteAccountLogTable.searchParam.trade_no" :placeholder="t('tradeNoPlaceholder')" /> <el-input v-model.trim="siteAccountLogTable.searchParam.trade_no" :placeholder="t('tradeNoPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('createTime')" prop="create_time"> <el-form-item :label="t('createTime')" prop="create_time">
<el-date-picker v-model="siteAccountLogTable.searchParam.create_time" type="datetimerange" <el-date-picker v-model="siteAccountLogTable.searchParam.create_time" type="datetimerange"

View File

@ -40,12 +40,12 @@
:end-placeholder="t('endDate')" /> :end-placeholder="t('endDate')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('cashOutNumber')" prop="cash_out_no"> <el-form-item :label="t('cashOutNumber')" prop="cash_out_no">
<el-input v-model="orderTableData.searchParam.cash_out_no" class="w-[240px]" <el-input v-model.trim="orderTableData.searchParam.cash_out_no" class="w-[240px]"
:placeholder="t('cashOutNumberPlaceholder')" /> :placeholder="t('cashOutNumberPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('memberInfo')" prop="keyword"> <el-form-item :label="t('memberInfo')" prop="keyword">
<el-input v-model="orderTableData.searchParam.keyword" class="w-[240px]" <el-input v-model.trim="orderTableData.searchParam.keyword" class="w-[240px]"
:placeholder="t('memberInfoPlaceholder')" /> :placeholder="t('memberInfoPlaceholder')" />
</el-form-item> </el-form-item>
@ -129,7 +129,7 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column :label="t('operation')" align="right" fixed="right" width="230"> <el-table-column :label="t('operation')" align="right" fixed="right" width="120">
<template #default="{ row }"> <template #default="{ row }">
<el-button v-for="(item, index) in operationBtn[row.status.toString()].value" :key="index + 'a'" <el-button v-for="(item, index) in operationBtn[row.status.toString()].value" :key="index + 'a'"
@click="fnProcessing(operationBtn[row.status.toString()].clickArr[index], row)" @click="fnProcessing(operationBtn[row.status.toString()].clickArr[index], row)"
@ -158,6 +158,19 @@
<el-form-item :label="t('cashOutMethod')"> <el-form-item :label="t('cashOutMethod')">
<div class="input-width"> {{ Transfertype[cashOutInfo.transfer_type].name }} </div> <div class="input-width"> {{ Transfertype[cashOutInfo.transfer_type].name }} </div>
</el-form-item> </el-form-item>
<template v-if="cashOutInfo.transfer_type == 'alipay'">
<el-form-item :label="t('alipayAccount')">
<div class="input-width"> {{ cashOutInfo.transfer_account }} </div>
</el-form-item>
</template>
<template v-if="cashOutInfo.transfer_type == 'bank'">
<el-form-item :label="t('bankName')">
<div class="input-width"> {{ cashOutInfo.transfer_bank }} </div>
</el-form-item>
<el-form-item :label="t('bankAccount')">
<div class="input-width"> {{ cashOutInfo.transfer_account }} </div>
</el-form-item>
</template>
<el-form-item :label="t('applicationForWithdrawalAmount')"> <el-form-item :label="t('applicationForWithdrawalAmount')">
<div class="input-width"> {{ cashOutInfo.apply_money }} </div> <div class="input-width"> {{ cashOutInfo.apply_money }} </div>
</el-form-item> </el-form-item>
@ -183,7 +196,7 @@
<el-dialog v-model="auditShowDialog" :title="t('rejectionAudit')" width="500px" :destroy-on-close="true"> <el-dialog v-model="auditShowDialog" :title="t('rejectionAudit')" width="500px" :destroy-on-close="true">
<el-form :model="auditFailure" label-width="90px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading"> <el-form :model="auditFailure" label-width="90px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
<el-form-item :label="t('reasonsRefusal')" prop="label_name"> <el-form-item :label="t('reasonsRefusal')" prop="label_name">
<el-input v-model="auditFailure.refuse_reason" clearable maxlength="200" :show-word-limit="true" :placeholder="t('reasonsRefusalPlaceholder')" :rows="4" class="input-width" type="textarea" /> <el-input v-model.trim="auditFailure.refuse_reason" clearable maxlength="200" :show-word-limit="true" :placeholder="t('reasonsRefusalPlaceholder')" :rows="4" class="input-width" type="textarea" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>

View File

@ -0,0 +1,158 @@
<template>
<el-drawer v-model="showDialog" title="退款详情" direction="rtl" :before-close="handleClose" class="member-detail-drawer">
<div class="main-container" v-loading="loading">
<div class="relative" v-if="formData">
<div class="flex mb-[20px] justify-between text-[15px]">
<span>{{ t('refundMoney') }}<span>{{ formData.money }}</span></span>
<span>{{ t('refundNo') }}<span>{{ formData.refund_no }}</span></span>
</div>
<el-table :data="refundList" size="large">
<el-table-column prop="out_trade_no" :label="t('outTradeNo')" min-width="200" />
<el-table-column prop="create_time" :label="t('createTime')" min-width="160" />
<el-table-column prop="refund_type_name" :label="t('refundTypeName')" min-width="120" />
<el-table-column :label="t('refundMoney')" min-width="120">
<template #default="{ row }">
<span>{{ row.money }}</span>
</template>
</el-table-column>
<el-table-column prop="status_name" :label="t('statusName')" min-width="120" />
<el-table-column :label="t('operation')" fixed="right" align="right" min-width="120">
<template #default="{ row }">
<el-button type="primary" v-if="row.status == 'wait'" link @click="transferEvent(row)">{{ t('transfer') }}</el-button>
</template>
</el-table-column>
</el-table>
</div>
<el-dialog v-model="transferDialog" :title="title" width="500px" class="diy-dialog-wrap" :destroy-on-close="true">
<el-form :model="transferFormData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
<el-form-item :label="t('transferType')">
<el-radio-group v-model="transferFormData.refund_type">
<el-radio :label="item.value" v-for="(item, index) in refundTypeData" :key="index">{{ item.name }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="t('refundMoney')">
<span>{{ transferFormData.refund_money }}</span>
</el-form-item>
<el-form-item :label="t('voucher')" v-if="transferFormData.refund_type == 'offline'">
<upload-image v-model="transferFormData.voucher" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="transferDialog = false">{{ t('cancel') }}</el-button>
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ t('confirm') }}</el-button>
</span>
</template>
</el-dialog>
</div>
</el-drawer>
</template>
<script lang="ts" setup>
import { reactive, ref, computed } from 'vue'
import { t } from '@/lang'
import { getPayRefundInfo, getRefundType, getRefundTransfer } from '@/app/api/pay'
import { FormInstance, ElMessage } from 'element-plus'
import { useRouter, useRoute } from 'vue-router'
import { img, filterNumber } from '@/utils/common'
import useAppStore from '@/stores/modules/app'
const route = useRoute()
const router = useRouter()
let popTitle: string = '退款详情';
const showDialog = ref(false)
const loading = ref(false)
let refundNo = '';
const refundList = ref([])
const formData: Record<string, any> = ref(null)
const handleClose = (done: () => void) => {
showDialog.value = false;
}
/**
* 表单数据
*/
const formRef = ref<FormInstance>()
const setFormData = async (row: any = null) => {
refundNo = row.no;
getRefundListInfo(refundNo)
}
const getRefundListInfo = async (no) => {
loading.value = true
formData.value = null
await getPayRefundInfo(no).then(({ data }) => {
formData.value = data
refundList.value.push(data)
})
loading.value = false
}
const refundTypeData = ref([])
getRefundType().then((data) => {
Object.keys(data.data).forEach((key: string) => {
refundTypeData.value.push({ value: key, name: data.data[key] })
})
})
const transferDialog = ref(false)
const transferEvent = (data:any) => {
transferDialog.value = true
transferFormData.refund_no = data.refund_no
transferFormData.refund_money = data.money
}
const initialFormData = {
refund_no: '',
refund_type: 'back',
voucher: '',
refund_money: 0.00
}
const transferFormData: Record<string, any> = reactive({ ...initialFormData })
//
const formRules = computed(() => {
return {
label_name: [
{ required: true, message: t('labelNamePlaceholder'), trigger: 'blur' }
]
}
})
const confirm = async (formEl: FormInstance | undefined) => {
if (loading.value || !formEl) return
await formEl.validate(async (valid) => {
if (valid) {
loading.value = true
const data = transferFormData
getRefundTransfer(data).then(res => {
loading.value = false
transferDialog.value = false
refundList.value = []
getRefundListInfo(refundNo)
}).catch(() => {
transferDialog.value = false
loading.value = false
})
}
})
}
defineExpose({
showDialog,
setFormData
})
</script>
<style lang="scss">
.member-detail-drawer{
width: 1000px !important;
}
</style>

View File

@ -9,7 +9,7 @@
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> <el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="payListTable.searchParam" ref="searchFormRef"> <el-form :inline="true" :model="payListTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('outTradeNo')" prop="trade_no"> <el-form-item :label="t('outTradeNo')" prop="trade_no">
<el-input v-model="payListTable.searchParam.out_trade_no" :placeholder="t('outTradeNoPlaceholder')" /> <el-input v-model.trim="payListTable.searchParam.out_trade_no" :placeholder="t('outTradeNoPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('createTime')" prop="create_time"> <el-form-item :label="t('createTime')" prop="create_time">
<el-date-picker v-model="payListTable.searchParam.create_time" type="datetimerange" <el-date-picker v-model="payListTable.searchParam.create_time" type="datetimerange"

View File

@ -10,7 +10,7 @@
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> <el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="payRefundTable.searchParam" ref="searchFormRef"> <el-form :inline="true" :model="payRefundTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('refundNo')" prop="refund_no"> <el-form-item :label="t('refundNo')" prop="refund_no">
<el-input v-model="payRefundTable.searchParam.refund_no" :placeholder="t('refundNoPlaceholder')" /> <el-input v-model.trim="payRefundTable.searchParam.refund_no" :placeholder="t('refundNoPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('createTime')" prop="create_time"> <el-form-item :label="t('createTime')" prop="create_time">
<el-date-picker v-model="payRefundTable.searchParam.create_time" type="datetimerange" <el-date-picker v-model="payRefundTable.searchParam.create_time" type="datetimerange"
@ -49,6 +49,7 @@
</div> </div>
</div> </div>
</el-card> </el-card>
<refund-detail ref="refundDetailDialog"></refund-detail>
</div> </div>
</template> </template>
@ -58,6 +59,7 @@ import { t } from '@/lang'
import { getPayRefundPages } from '@/app/api/pay' import { getPayRefundPages } from '@/app/api/pay'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
import type { FormInstance } from 'element-plus' import type { FormInstance } from 'element-plus'
import refundDetail from '@/app/views/finance/components/refund-detail.vue'
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
@ -97,9 +99,11 @@ const loadPayRefundList = (page: number = 1) => {
}) })
} }
loadPayRefundList() loadPayRefundList()
const refundDetailDialog: Record<string, any> | null = ref(null)
const infoEvent = (data:any) => { const infoEvent = (res:any) => {
router.push('/finance/refund/detail?refund_no=' + data.refund_no) let data = {no: res.refund_no};
refundDetailDialog.value.setFormData(data);
refundDetailDialog.value.showDialog = true;
} }
const resetForm = (formEl: FormInstance | undefined) => { const resetForm = (formEl: FormInstance | undefined) => {

View File

@ -114,7 +114,6 @@ const formRules = computed(() => {
return { return {
label_name: [ label_name: [
{ required: true, message: t('labelNamePlaceholder'), trigger: 'blur' } { required: true, message: t('labelNamePlaceholder'), trigger: 'blur' }
] ]
} }
}) })

View File

@ -7,7 +7,7 @@
<div class="font-bold text-xl mb-[40px]">{{ t('developTitle') }}</div> <div class="font-bold text-xl mb-[40px]">{{ t('developTitle') }}</div>
<div class="mb-[20px] flex flex-col"> <div class="mb-[20px] flex flex-col">
<text class="mb-[10px]">{{ t('wapDomain') }}</text> <text class="mb-[10px]">{{ t('wapDomain') }}</text>
<el-input v-model="wapDomain" :placeholder="t('wapDomainPlaceholder')" clearable /> <el-input v-model.trim="wapDomain" :placeholder="t('wapDomainPlaceholder')" clearable />
</div> </div>
<el-button type="primary" @click="save">{{ t('confirm') }}</el-button> <el-button type="primary" @click="save">{{ t('confirm') }}</el-button>
</div> </div>

View File

@ -1,10 +1,11 @@
<template> <template>
<el-form :model="formData" :rules="formRules" class="page-form" ref="formRef"> <el-form :model="formData" :rules="formRules" class="page-form" ref="formRef">
<el-form-item :label="t('continueSign')" prop="continue_sign"> <el-form-item :label="t('continueSign')" prop="continue_sign">
<el-input class="input-width" v-model.trim="formData.continue_sign" clearable /><span class="ml-[10px]">{{ t('day') }}</span> <el-input class="input-width" v-model.trim="formData.continue_sign" :maxlength="5" clearable />
<span class="ml-[10px]">{{ t('day') }}</span>
</el-form-item> </el-form-item>
<el-form-item :label="t('continueSign')" > <el-form-item :label="t('continueSign')" >
<div> <div class="flex-1">
<div v-for="(item,index) in gifts" :key="index" class="mb-[15px]"> <div v-for="(item,index) in gifts" :key="index" class="mb-[15px]">
<component :is="item.component" v-model="formData[item.key]" ref="giftRefs" v-if="item.component" /> <component :is="item.component" v-model="formData[item.key]" ref="giftRefs" v-if="item.component" />
</div> </div>
@ -15,7 +16,7 @@
<el-radio class="mb-[15px]" v-model="formData.receive_limit" :label="1" @change="radioChange($event, 1)">{{ t('noLimit') }}</el-radio> <el-radio class="mb-[15px]" v-model="formData.receive_limit" :label="1" @change="radioChange($event, 1)">{{ t('noLimit') }}</el-radio>
<div class="flex"> <div class="flex">
<el-radio class="!mr-[15px]" v-model="formData.receive_limit" :label="2" @change="radioChange($event, 2)">{{ t('everyOneLimit') }}</el-radio> <el-radio class="!mr-[15px]" v-model="formData.receive_limit" :label="2" @change="radioChange($event, 2)">{{ t('everyOneLimit') }}</el-radio>
<el-input class="input-width" v-model="formData.receive_num" clearable /><span class="ml-[10px]">{{ t('time') }}</span> <el-input class="input-width" v-model.trim="formData.receive_num" :maxlength="5" clearable /><span class="ml-[10px]">{{ t('time') }}</span>
</div> </div>
</div> </div>
</el-form-item> </el-form-item>
@ -76,18 +77,26 @@ getGiftDict().then(({ data }) => {
}) })
const formRef = ref(null) const formRef = ref(null)
//
const regExp = {
required: /[\S]+/,
number: /^\d{0,10}$/,
digit: /^\d{0,10}(.?\d{0,2})$/,
special: /^\d{0,10}(.?\d{0,3})$/
}
// //
const formRules = reactive<FormRules>({ const formRules = reactive<FormRules>({
continue_sign: [ continue_sign: [
{ required: true, message: t('continueSignPlaceholder'), trigger: 'blur' }, { required: true, message: t('continueSignPlaceholder'), trigger: 'blur' },
{ {
validator: (rule: any, value: any, callback: Function) => {
if (!Test.digits(formData.value.continue_sign)) { validator: (rule: any, value: any, callback: any) => {
callback('连续签到格式错误') if (isNaN(value) || !regExp.number.test(value)) {
} else if (formData.value.continue_sign <= 0) { callback('连续签到天数格式错误')
callback('连续签到不能小于等于0') } else if (value <=0) {
callback('连续签到天数不能小于等于0')
} else{ } else{
callback() callback();
} }
}, },
trigger: 'blur' trigger: 'blur'
@ -101,7 +110,7 @@ const formRules = reactive<FormRules>({
if (Test.empty(formData.value.receive_num)) { if (Test.empty(formData.value.receive_num)) {
callback('请输入限领次数') callback('请输入限领次数')
} }
if (!Test.digits(formData.value.receive_num)) { if (isNaN(formData.value.receive_num) || !regExp.number.test(formData.value.receive_num)) {
callback('限领次数格式错误') callback('限领次数格式错误')
} }
if (formData.value.receive_num <= 0) { if (formData.value.receive_num <= 0) {

View File

@ -0,0 +1,168 @@
<template>
<el-drawer v-model="showDialog" title="核销记录详情" direction="rtl" :before-close="handleClose" class="member-detail-drawer">
<div class="main-container" v-loading="loading">
<el-tabs v-model="activeName" class="pb-[10px]" @tab-change="handleClick">
<el-tab-pane label="核销信息" name="verifyInfo" />
<el-tab-pane label="商品信息" name="goodsInfo" />
</el-tabs>
<div v-if="activeName == 'verifyInfo'">
<div class="text-[14px] min-w-[110px] border-solid border-l-[3px] border-[var(--el-color-primary)] pl-[5px]">核销信息</div>
<el-row>
<el-col :span="8">
<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.type_name }}
</span>
</div>
</el-col>
<el-col :span="8">
<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]">
已核销
</span>
</div>
</el-col>
<el-col :span="8">
<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 : '--' }}
</span>
</div>
</el-col>
<el-col :span="8">
<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.create_time}}
</span>
</div>
</el-col>
<template v-for="(item,index) in verifyContentData.fixed">
<el-col :span="8">
<div class="flex items-center mt-[15px]" v-if="item.title">
<span class="text-[14px] w-[130px] text-right mr-[20px]">{{ item.title }}</span>
<span class="text-[14px] text-[#666666]">
{{ item.value }}
</span>
</div>
</el-col>
</template>
<template v-for="(item,index) in verifyData.verify_info">
<el-col :span="8" v-for="(val,key) in item">
<div class="flex items-center mt-[15px]" v-if="val.name">
<span class="text-[14px] w-[130px] text-right mr-[20px]">{{ val.name }}</span>
<span class="text-[14px] text-[#666666]">
{{ val.value }}
</span>
</div>
</el-col>
</template>
</el-row>
<template v-for="(item,index) in verifyContentData.diy">
<div class="text-[14px] min-w-[110px] border-solid border-l-[3px] border-[var(--el-color-primary)] pl-[5px] mt-[20px]">{{item.title}}</div>
<el-row>
<el-col :span="8" v-for="(subItem,subIndex) in item.list" :key="subIndex">
<div class="flex items-center mt-[15px]">
<span class="text-[14px] w-[130px] text-right mr-[20px]">{{ subItem.title }}</span>
<span class="text-[14px] text-[#666666]">
{{ subItem.value }}
</span>
</div>
</el-col>
</el-row>
</template>
</div>
<div v-if="activeName == 'goodsInfo'">
<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">
<img class="w-[50px] h-[50px] mr-[10px]" :src="img(row.cover)" />
</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>
</el-drawer>
</template>
<script lang="ts" setup>
import { reactive, ref, computed } from 'vue'
import { t } from '@/lang'
import { getVerifyDetail } from '@/app/api/verify'
import { FormInstance, ElMessage } from 'element-plus'
import { ArrowLeft } from '@element-plus/icons-vue'
import { useRouter, useRoute } from 'vue-router'
import { img, filterNumber } from '@/utils/common'
import useAppStore from '@/stores/modules/app'
const showDialog = ref(false)
const loading = ref(true)
const router = useRouter()
const appStore = useAppStore()
const activeName = ref('verifyInfo')
const formData:Record<string, any> = ref({})
const handleClick = (data:string) => {
activeName.value = data
}
const handleClose = (done: () => void) => {
showDialog.value = false;
}
//
let code: any = ''
const verifyData: any = ref({})
const verifyContentData: any = ref({})
const verifyGoodsList: any = ref([])
const getVerifyDetailFn = async () => {
loading.value = true
if (code) {
const data = await (await getVerifyDetail(code)).data
if (!data || Object.keys(data).length == 0) {
ElMessage.error(t('memberNull'))
setTimeout(() => {
router.go(-1)
}, 2000)
return false
}
verifyData.value = data
verifyContentData.value = data.value.content || {}
verifyGoodsList.value = data.value.list || []
loading.value = false
} else {
loading.value = false
}
}
const setFormData = async (row: any = null) => {
console.log("setFormData",row);
code = row.code;
getVerifyDetailFn();
}
defineExpose({
showDialog,
setFormData
})
</script>
<style lang="scss">
.member-detail-drawer{
width: 1000px !important;
}
</style>

View File

@ -11,10 +11,10 @@
</el-form-item> </el-form-item>
<el-form-item :label="t('signPeriod')" v-if="formData.is_use"> <el-form-item :label="t('signPeriod')" v-if="formData.is_use">
<el-input-number v-model="formData.sign_period" clearable class="input-width" controls-position="right" /><span class="ml-[10px]"></span> <el-input-number v-model="formData.sign_period" :min="0" :precision="0" clearable class="input-width" controls-position="right" /><span class="ml-[10px]"></span>
</el-form-item> </el-form-item>
<el-form-item :label="t('daySignAward')" prop="formData.day_award" v-if="formData.is_use"> <el-form-item :label="t('daySignAward')" prop="day_award" v-if="formData.is_use">
<div v-for="(item, index) in daySignAwardText" :key="index"> <div v-for="(item, index) in daySignAwardText" :key="index">
<span v-if="item.is_use == '1'">{{ item.content }}&nbsp;&nbsp;</span> <span v-if="item.is_use == '1'">{{ item.content }}&nbsp;&nbsp;</span>
</div> </div>
@ -27,7 +27,7 @@
<div class="form-tip">{{ t('daySignAwardTip') }}</div> <div class="form-tip">{{ t('daySignAwardTip') }}</div>
</el-form-item> </el-form-item>
<el-form-item :label="t('continueSignAward')" prop="formData.continue_award" v-if="formData.is_use"> <el-form-item :label="t('continueSignAward')" prop="continue_award" v-if="formData.is_use">
<div> <div>
<div class="form-tip">{{ t('continueSignAwardTipTop') }}</div> <div class="form-tip">{{ t('continueSignAwardTipTop') }}</div>
<div class="mt-[10px]"> <div class="mt-[10px]">
@ -68,9 +68,9 @@
</div> </div>
</el-form-item> </el-form-item>
<el-form-item :label="t('ruleExplain')" prop="formData.rule_explain" v-if="formData.is_use"> <el-form-item :label="t('ruleExplain')" prop="rule_explain" v-if="formData.is_use">
<div class="flex"> <div class="flex">
<el-input v-model="formData.rule_explain" :placeholder="t('ruleExplainTip')" type="textarea" rows="5" class="textarea-width" clearable /> <el-input v-model.trim="formData.rule_explain" :placeholder="t('ruleExplainTip')" type="textarea" maxlength="500" show-word-limit rows="5" class="textarea-width" clearable />
<el-button class="ml-[20px]" type="primary" @click="defaultExplainEvent()" plain>{{ t('useDefaultExplain') }}</el-button> <el-button class="ml-[20px]" type="primary" @click="defaultExplainEvent()" plain>{{ t('useDefaultExplain') }}</el-button>
</div> </div>
</el-form-item> </el-form-item>
@ -78,7 +78,7 @@
</el-form> </el-form>
<!-- 日签奖励 --> <!-- 日签奖励 -->
<el-dialog v-model="daySignDialog" :title="t('daySignTitle')" width="1200px" :destroy-on-close="true" v-if="formData.is_use"> <el-dialog v-model="daySignDialog" :title="t('daySignTitle')" width="1000px" :destroy-on-close="true" v-if="formData.is_use">
<sign-day ref="benefitsRef" v-model="formData.day_award" /> <sign-day ref="benefitsRef" v-model="formData.day_award" />
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
@ -89,7 +89,7 @@
</el-dialog> </el-dialog>
<!-- 连签奖励 --> <!-- 连签奖励 -->
<el-dialog v-model="continueSignDialog" :title="t('continueSignTitle')" width="1200px" :destroy-on-close="true" v-if="formData.is_use"> <el-dialog v-model="continueSignDialog" :title="t('continueSignTitle')" width="1000px" :destroy-on-close="true" v-if="formData.is_use">
<sign-continue ref="continueRef" v-model="continue_award" /> <sign-continue ref="continueRef" v-model="continue_award" />
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
@ -134,7 +134,10 @@ let editIndex = 0 // 连签奖励修改下标
const formRules = reactive<FormRules>({ const formRules = reactive<FormRules>({
sign_period: [ sign_period: [
{ required: true, message: t('signPeriodTip'), trigger: 'blur' } { required: true, message: t('signPeriodTip'), trigger: 'blur' }
] ],
day_award: [
{ required: true, message: t('daySignAwardPlaceholder'), trigger: 'change' }
],
}) })
/** /**

View File

@ -10,7 +10,7 @@
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> <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 :inline="true" :model="memberSignListTableData.searchParam" ref="searchFormRef">
<el-form-item :label="t('memberInfo')" prop="keywords"> <el-form-item :label="t('memberInfo')" prop="keywords">
<el-input v-model="memberSignListTableData.searchParam.keywords" class="w-[240px]" :placeholder="t('memberInfoPlaceholder')" /> <el-input v-model.trim="memberSignListTableData.searchParam.keywords" class="w-[240px]" :placeholder="t('memberInfoPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('createTime')" prop="create_time"> <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')" /> <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')" />

View File

@ -57,11 +57,8 @@
<el-dialog v-model="showDialog" :title="t('addVerifier')" width="500px" :destroy-on-close="true"> <el-dialog v-model="showDialog" :title="t('addVerifier')" width="500px" :destroy-on-close="true">
<el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules" class="page-form" v-loading="addLoading"> <el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules" class="page-form" v-loading="addLoading">
<el-form-item :label="t('member')" prop="member_id"> <el-form-item :label="t('member')" prop="member_id">
<el-select v-model="formData.member_id" filterable remote reserve-keyword clearable <el-select v-model="formData.member_id" filterable remote reserve-keyword clearable :placeholder="t('searchPlaceholder')" :remote-method="searchMember" :loading="searchLoading" class="input-width">
:placeholder="t('searchPlaceholder')" :remote-method="searchMember" :loading="searchLoading" <el-option v-for="item in memberList" :key="item.member_id" :label="item.nickname" :value="item.member_id" />
class="input-width">
<el-option v-for="item in memberList" :key="item.member_id" :label="item.nickname"
:value="item.member_id" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item :label="t('verifyType')" prop="verify_type"> <el-form-item :label="t('verifyType')" prop="verify_type">

View File

@ -10,7 +10,7 @@
<el-card class="box-card mt-[10px] !border-none table-search-wrap" shadow="never"> <el-card class="box-card mt-[10px] !border-none table-search-wrap" shadow="never">
<el-form :inline="true" :model="recordTable.searchParam" ref="searchFormRef"> <el-form :inline="true" :model="recordTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('verifyCode')" prop="code"> <el-form-item :label="t('verifyCode')" prop="code">
<el-input v-model="recordTable.searchParam.code" :placeholder="t('verifyCodePlaceholder')" /> <el-input v-model.trim="recordTable.searchParam.code" :placeholder="t('verifyCodePlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('verifyType')" prop="type"> <el-form-item :label="t('verifyType')" prop="type">
<el-select v-model="recordTable.searchParam.type" clearable :placeholder="t('verifyTypePlaceholder')" class="input-width"> <el-select v-model="recordTable.searchParam.type" clearable :placeholder="t('verifyTypePlaceholder')" class="input-width">
@ -64,6 +64,8 @@
@size-change="loadRecordList()" @current-change="loadRecordList" /> @size-change="loadRecordList()" @current-change="loadRecordList" />
</div> </div>
</div> </div>
<verify-detail ref="verifyDetailDialog" />
</el-card> </el-card>
</div> </div>
</template> </template>
@ -74,6 +76,7 @@ import { t } from '@/lang'
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
import { FormInstance } from 'element-plus' import { FormInstance } from 'element-plus'
import { getVerifyRecord, getVerifyTypeList, getVerifierSelect } from '@/app/api/verify' import { getVerifyRecord, getVerifyTypeList, getVerifierSelect } from '@/app/api/verify'
import verifyDetail from '@/app/views/marketing/components/verify-detail.vue'
import { img } from '@/utils/common' import { img } from '@/utils/common'
const route = useRoute() const route = useRoute()
@ -147,8 +150,10 @@ const resetForm = (formEl: FormInstance | undefined) => {
} }
// //
let verifyDetailDialog: Record<string, any> | null = ref(null)
const detailEvent = (data: any) => { const detailEvent = (data: any) => {
router.push(`/marketing/verify/detail?code=${data.code}`) verifyDetailDialog.value.setFormData({code: data.code})
verifyDetailDialog.value.showDialog = true
} }
</script> </script>

View File

@ -46,7 +46,7 @@
<el-form :inline="true" :model="memberAccountLogTableData.searchParam" ref="searchFormRef"> <el-form :inline="true" :model="memberAccountLogTableData.searchParam" ref="searchFormRef">
<el-form-item :label="t('memberInfo')" prop="keywords"> <el-form-item :label="t('memberInfo')" prop="keywords">
<el-input v-model="memberAccountLogTableData.searchParam.keywords" class="w-[240px]" :placeholder="t('memberInfoPlaceholder')" /> <el-input v-model.trim="memberAccountLogTableData.searchParam.keywords" class="w-[240px]" :placeholder="t('memberInfoPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('balanceType')" prop="balance_type"> <el-form-item :label="t('balanceType')" prop="balance_type">

View File

@ -55,7 +55,7 @@
<el-card class="box-card !border-none mb-[10px] table-search-wrap" shadow="never"> <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 :inline="true" :model="memberAccountLogTableData.searchParam" ref="searchFormRef">
<el-form-item :label="t('memberInfo')" prop="keywords"> <el-form-item :label="t('memberInfo')" prop="keywords">
<el-input v-model="memberAccountLogTableData.searchParam.keywords" class="w-[240px]" :placeholder="t('memberInfoPlaceholder')" /> <el-input v-model.trim="memberAccountLogTableData.searchParam.keywords" class="w-[240px]" :placeholder="t('memberInfoPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('fromType')" prop="from_type"> <el-form-item :label="t('fromType')" prop="from_type">
<el-select v-model="memberAccountLogTableData.searchParam.from_type" clearable :placeholder="t('fromTypePlaceholder')" class="input-width"> <el-select v-model="memberAccountLogTableData.searchParam.from_type" clearable :placeholder="t('fromTypePlaceholder')" class="input-width">
@ -162,7 +162,7 @@ const memberAccountLogTableData = reactive({
from_type: '', from_type: '',
create_time: '', create_time: '',
mobile: '', mobile: '',
member_id: member_id member_id
} }
}) })

View File

@ -3,22 +3,22 @@
<el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading"> <el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
<el-form-item :label="t('memberNo')" prop="member_no"> <el-form-item :label="t('memberNo')" prop="member_no">
<el-input v-model="formData.member_no" clearable maxlength="20" :placeholder="t('memberNoPlaceholder')" class="input-width" /> <el-input v-model.trim="formData.member_no" clearable maxlength="20" :placeholder="t('memberNoPlaceholder')" class="input-width" />
</el-form-item> </el-form-item>
<el-form-item :label="t('mobile')" prop="mobile"> <el-form-item :label="t('mobile')" prop="mobile">
<el-input v-model="formData.mobile" clearable :placeholder="t('mobilePlaceholder')" @keyup="filterNumber($event)" class="input-width" /> <el-input v-model.trim="formData.mobile" clearable :placeholder="t('mobilePlaceholder')" @keyup="filterNumber($event)" class="input-width" />
</el-form-item> </el-form-item>
<el-form-item :label="t('nickname')"> <el-form-item :label="t('nickname')">
<el-input v-model="formData.nickname" clearable :placeholder="t('nickNamePlaceholder')" class="input-width" maxlength="10" show-word-limit :readonly="nickname_name_input" @click="nickname_name_input = false" @blur="nickname_name_input = true" /> <el-input v-model.trim="formData.nickname" clearable :placeholder="t('nickNamePlaceholder')" class="input-width" maxlength="10" show-word-limit :readonly="nickname_name_input" @click="nickname_name_input = false" @blur="nickname_name_input = true" />
</el-form-item> </el-form-item>
<el-form-item :label="t('password')" prop="password"> <el-form-item :label="t('password')" prop="password">
<el-input v-model="formData.password" type="password" :placeholder="t('passwordPlaceholder')" clearable class="input-width" :show-password="true" :readonly="password_input" @click="password_input = false" @blur="password_input = true" /> <el-input v-model.trim="formData.password" type="password" :placeholder="t('passwordPlaceholder')" clearable class="input-width" :show-password="true" :readonly="password_input" @click="password_input = false" @blur="password_input = true" />
</el-form-item> </el-form-item>
<el-form-item :label="t('passwordCopy')" prop="password_copy"> <el-form-item :label="t('passwordCopy')" prop="password_copy">
<el-input v-model="formData.password_copy" type="password" :placeholder="t('passwordPlaceholder')" clearable class="input-width" :show-password="true" :readonly="password_copy_input" @click="password_copy_input = false" @blur="password_copy_input = true" /> <el-input v-model.trim="formData.password_copy" type="password" :placeholder="t('passwordPlaceholder')" clearable class="input-width" :show-password="true" :readonly="password_copy_input" @click="password_copy_input = false" @blur="password_copy_input = true" />
</el-form-item> </el-form-item>
</el-form> </el-form>

View File

@ -0,0 +1,406 @@
<template>
<el-drawer v-model="showDialog" :title="popTitle" direction="rtl" :before-close="handleClose" class="member-detail-drawer">
<div class="main-container" v-loading="loading">
<div class="bg-page py-[20px] pr-[30px] relative flex">
<div class="member-info w-[250px]">
<div class="flex items-center">
<div class="text-[14px] min-w-[110px] text-right mr-[20px]">{{ t('headimg') }}</div>
<div class="flex items-end text-[14px]">
<div class="w-[50px] h-[50px] flex items-center justify-center">
<img class="max-w-[50px] max-h-[50px] inline-block" v-if="formData.headimg" :src="img(formData.headimg)" alt="">
<img class="max-w-[50px] max-h-[50px] inline-block rounded-full" v-else src="@/app/assets/images/member_head.png" alt="">
</div>
<el-icon @click="editMemberInfo('headimg')" class="-bottom-[2px] -right-[4px] cursor-pointer">
<EditPen color="#273CE2" />
</el-icon>
</div>
</div>
<div class="flex items-center mt-[20px]">
<span class="text-[14px] min-w-[110px] text-right mr-[20px]">UID</span>
<span class="member-info-item text-[14px] text-[#666666] font-bold w-[150px]">
{{ formData.member_no || t('notAvailable') }}
</span>
</div>
</div>
<div class="flex flex-1 justify-between">
<div class="statistic-card">
<el-statistic :value="formData.point">
<template #title>
<div style="display: inline-flex; align-items: center">
<span class="text-[14px]">
{{ t('point') }}
</span>
<el-tooltip effect="dark" :content="t('adjust')" placement="top">
<el-icon @click="adjustPoint(formData)" class="ml-2 cursor-pointer" :size="12">
<EditPen color="#273CE2" />
</el-icon>
</el-tooltip>
<el-tooltip effect="dark" :content="t('detail')" placement="top">
<el-icon @click="infoPoint(formData)" class="ml-2 cursor-pointer" :size="12">
<View />
</el-icon>
</el-tooltip>
</div>
</template>
</el-statistic>
<div class="statistic-footer">
<div class="footer-item text-[14px] text-secondary">
<span>{{ t('accumulative') }}</span>
<span class="green ml-1">
{{ formData.point_get }}
</span>
</div>
</div>
</div>
<div class="statistic-card">
<el-statistic :value="formData.balance">
<template #title>
<div style="display: inline-flex; align-items: center">
<span class="text-[14px]">
{{ t('balance') }}
</span>
<el-tooltip effect="dark" :content="t('adjust')" placement="top">
<el-icon @click="adjustBalance(formData)" class="ml-2 cursor-pointer" :size="12">
<EditPen color="#273CE2" />
</el-icon>
</el-tooltip>
<el-tooltip effect="dark" :content="t('detail')" placement="top">
<el-icon @click="infoBalance(formData)" class="ml-2 cursor-pointer" :size="12">
<View />
</el-icon>
</el-tooltip>
</div>
</template>
</el-statistic>
<div class="statistic-footer">
<div class="footer-item text-[14px] text-secondary">
<span>{{ t('accumulative') }}</span>
<span class="red ml-1">
{{ formData.balance_get }}
</span>
</div>
</div>
</div>
<div class="statistic-card">
<el-statistic :value="formData.growth">
<template #title>
<div style="display: inline-flex; align-items: center">
<span class="text-[14px]">
{{ t('growth') }}
</span>
<el-tooltip effect="dark" :content="t('detail')" placement="top">
<el-icon @click="infoGrowth(formData)" class="ml-2 cursor-pointer" :size="12">
<View />
</el-icon>
</el-tooltip>
</div>
</template>
</el-statistic>
</div>
<div class="statistic-card">
<el-statistic :value="formData.money" title="New transactions today">
<template #title>
<div style="display: inline-flex; align-items: center">
<span class="text-[14px]">
{{ t("money") }}
</span>
<el-tooltip effect="dark" :content="t('detail')" placement="top">
<el-icon @click="infoBalance(formData)" class="ml-2 cursor-pointer" :size="12">
<View />
</el-icon>
</el-tooltip>
</div>
</template>
</el-statistic>
<div class="statistic-footer">
<div class="footer-item text-[14px] text-secondary">
<span>{{ t('accumulative') }}</span>
<span class="green ml-1">
{{ formData.money_get }}
</span>
</div>
</div>
</div>
<div class="statistic-card">
<el-statistic :value="formData.commission" title="New transactions today">
<template #title>
<div style="display: inline-flex; align-items: center ">
<span class="text-[14px]">
{{ t("commission") }}
</span>
<el-tooltip effect="dark" :content="t('detail')" placement="top">
<el-icon @click="infoCommission(formData)" class="ml-2 cursor-pointer" :size="12">
<View />
</el-icon>
</el-tooltip>
</div>
</template>
</el-statistic>
<div class="statistic-footer">
<div class="footer-item text-[14px] text-secondary">
<span>{{ t('accumulative') }}</span>
<span class="green ml-1">
{{ formData.commission_get }}
</span>
</div>
</div>
</div>
</div>
</div>
<div class="flex flex-wrap mt-[20px]">
<div class="flex items-center w-[33.3%] mt-[15px]">
<span class="text-[14px] w-[130px] text-right flex-shrink-0 mr-[20px]">{{ t('urserName') }}</span>
<span class="text-[14px] text-[#666666]">
{{ formData.username || t('notAvailable') }}
</span>
</div>
<div class="flex mt-[15px] w-[33.3%] break-all leading-[21px]">
<span class="text-[14px] w-[130px] text-right flex-shrink-0 mr-[20px]">{{ t('nickname') }}</span>
<span class="text-[14px] text-[#666666]">
{{ formData.nickname || t('notAvailable') }}
</span>
</div>
<div class="flex mt-[15px] w-[33.3%] break-all leading-[21px]">
<span class="text-[14px] w-[130px] text-right flex-shrink-0 mr-[20px]">{{ t('mobile') }}</span>
<span class="text-[14px] text-[#666666]">
{{ formData.mobile || t('notAvailable') }}
</span>
</div>
<div class="flex mt-[15px] w-[33.3%] break-all leading-[21px]">
<span class="text-[14px] w-[130px] text-right flex-shrink-0 mr-[20px]">{{ t('memberLevel') }}</span>
<span class="text-[14px] text-[#666666]">
{{ formData.member_level_name || t('notAvailable') }}<el-icon @click="editMemberInfo('member_level')" class="-bottom-[2px] -right-[4px] cursor-pointer">
<EditPen color="#273CE2" />
</el-icon>
</span>
</div>
<div class="flex mt-[15px] w-[33.3%] break-all leading-[21px]">
<span class="text-[14px] w-[130px] text-right flex-shrink-0 mr-[20px]">{{ t('memberLabel') }}</span>
<span class="text-[14px] text-[#666666]">
{{ formData.member_label_name&&formData.member_label_name.toString() || t('notAvailable') }}<el-icon @click="editMemberInfo('member_label')" class="-bottom-[2px] -right-[4px] cursor-pointer">
<EditPen color="#273CE2" />
</el-icon>
</span>
</div>
<div class="flex mt-[15px] w-[33.3%] break-all leading-[21px]">
<span class="text-[14px] w-[130px] text-right flex-shrink-0 mr-[20px]">{{ t('birthday') }}</span>
<span class="text-[14px] text-[#666666]">
{{ formData.birthday || t('notAvailable') }}<el-icon @click="editMemberInfo('birthday')" class="-bottom-[2px] -right-[4px] cursor-pointer">
<EditPen color="#273CE2" />
</el-icon>
</span>
</div>
<div class="flex mt-[15px] w-[33.3%] break-all leading-[21px]">
<span class="text-[14px] w-[130px] text-right flex-shrink-0 mr-[20px]">{{ t('sex') }}</span>
<span class="text-[14px] text-[#666666]">
{{ formData.sex == 1 && t('manSex') || formData.sex == 2 && t('girlSex') || t('secrecySex') }}<el-icon @click="editMemberInfo('sex')" class="-bottom-[2px] -right-[4px] cursor-pointer">
<EditPen color="#273CE2" />
</el-icon>
</span>
</div>
<div class="flex mt-[15px] w-[33.3%] break-all leading-[21px]">
<span class="text-[14px] w-[130px] text-right flex-shrink-0 mr-[20px]">{{ t('wxUnionid') }}</span>
<span class="text-[14px] text-[#666666]">
{{ formData.wx_unionid || t('notAvailable') }}
</span>
</div>
<div class="flex mt-[15px] w-[33.3%] break-all leading-[21px]">
<span class="text-[14px] w-[130px] text-right flex-shrink-0 mr-[20px]">{{ t('weappOpenid') }}</span>
<span class="text-[14px] text-[#666666]">
{{ formData.weapp_openid || t('notAvailable') }}
</span>
</div>
<div class="flex mt-[15px] w-[33.3%] break-all leading-[21px]">
<span class="text-[14px] w-[130px] text-right flex-shrink-0 mr-[20px]">{{ t('wxOpenid') }}</span>
<span class="text-[14px] text-[#666666]">
{{ formData.wx_openid || t('notAvailable') }}
</span>
</div>
<div class="flex mt-[15px] w-[33.3%] break-all leading-[21px]">
<span class="text-[14px] w-[130px] text-right flex-shrink-0 mr-[20px]">{{ t('registeredSource') }}</span>
<span class="text-[14px] text-[#666666]">
{{ formData.register_channel_name || t('notAvailable') }}
</span>
</div>
<div class="flex mt-[15px] w-[33.3%] break-all leading-[21px]">
<span class="text-[14px] w-[130px] text-right flex-shrink-0 mr-[20px]">{{ t('createTime') }}</span>
<span class="text-[14px] text-[#666666]">
{{ formData.create_time || t('notAvailable') }}
</span>
</div>
<div class="flex mt-[15px] w-[33.3%] break-all leading-[21px]">
<span class="text-[14px] w-[130px] text-right flex-shrink-0 mr-[20px]">{{ t('lastVisitTime') }}</span>
<span class="text-[14px] text-[#666666]">
{{ formData.last_visit_time || t('notAvailable') }}
</span>
</div>
</div>
</div>
<point-edit ref="pointDialog" @complete="getMemberInfoFn" />
<balance-edit ref="balanceDialog" @complete="getMemberInfoFn" />
<edit-member ref="editMemberDialog" @complete="getMemberInfoFn()" />
</el-drawer>
</template>
<script lang="ts" setup>
import { reactive, ref, computed } from 'vue'
import { t } from '@/lang'
import { addMember, getMemberList, getMemberNo, getMemberInfo } from '@/app/api/member'
import { FormInstance, ElMessage } from 'element-plus'
import { ArrowLeft } from '@element-plus/icons-vue'
import { useRouter, useRoute } from 'vue-router'
import { img, filterNumber } from '@/utils/common'
import PointEdit from '@/app/views/member/components/member-point-edit.vue'
import BalanceEdit from '@/app/views/member/components/member-balance-edit.vue'
import EditMember from '@/app/views/member/components/edit-member.vue'
import useAppStore from '@/stores/modules/app'
const showDialog = ref(false)
const loading = ref(false)
const repeat = ref(false)
let popTitle: string = '会员详情'
let memberNo: string = ''
let id = '';
const route = useRoute()
const router = useRouter()
const emit = defineEmits(['load'])
const nickname_name_input = ref(true)
const password_input = ref(true)
const password_copy_input = ref(true)
const handleClose = (done: () => void) => {
showDialog.value = false;
}
/**
* 表单数据
*/
const initialFormData = {
member_id: '',
nickname: '',
member_no: '',
init_member_no: '',
mobile: '',
password: '',
password_copy: ''
}
const formData: Record<string, any> = reactive({ ...initialFormData })
const formRef = ref<FormInstance>()
const pointDialog: Record<string, any> | null = ref(null)
const balanceDialog: Record<string, any> | null = ref(null)
const editMemberDialog: Record<string, any> | null = ref(null)
/**
* 修改会员信息
*/
const editMemberInfo = (type: any) => {
const data = ref({
type,
id,
data: formData
})
editMemberDialog.value.setDialogType(data.value)
editMemberDialog.value.showDialog = true
}
/**
* 调整积分
*/
const adjustPoint = (data: any) => {
pointDialog.value.setFormData(data)
pointDialog.value.showDialog = true
}
/**
* 调整余额
*/
const adjustBalance = (data: any) => {
balanceDialog.value.setFormData(data)
balanceDialog.value.showDialog = true
}
/**
* 积分详情
*/
const infoPoint = () => {
router.push(`/member/point?id=${id}`)
}
/**
* 余额详情
*/
const infoBalance = () => {
router.push(`/member/balance?id=${id}`)
}
/**
* 成长值明细
*/
const infoGrowth = () => {
router.push(`/member/growth?id=${id}`)
}
/**
* 佣金详情
*/
const infoCommission = () => {
router.push(`/member/commission?id=${id}`)
}
const getMemberInfoFn = async (bool=false) => {
loading.value = true
if (id) {
const data = await (await getMemberInfo(id)).data
if (!data || Object.keys(data).length == 0) {
ElMessage.error(t('memberNull'))
setTimeout(() => {
router.go(-1)
}, 2000)
return false
}
Object.keys(data).forEach((item) => {
formData[item] = data[item]
})
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
} else {
loading.value = false
}
if(!bool){
emit('load');
}
}
const setFormData = async (row: any = null) => {
id = row.id;
Object.assign(formData, initialFormData)
getMemberInfoFn(true);
}
defineExpose({
showDialog,
setFormData
})
</script>
<style lang="scss">
.member-detail-drawer{
width: 1000px !important;
}
</style>

View File

@ -6,7 +6,7 @@
<upload-image v-model="saveData.headimg" /> <upload-image v-model="saveData.headimg" />
</el-form-item> </el-form-item>
<el-form-item :label="t('nickname')" v-if="type == 'nickname'"> <el-form-item :label="t('nickname')" v-if="type == 'nickname'">
<el-input v-model="saveData.nickname" clearable :placeholder="t('nickNamePlaceholder')" class="input-width" /> <el-input v-model.trim="saveData.nickname" clearable :placeholder="t('nickNamePlaceholder')" class="input-width" />
</el-form-item> </el-form-item>
<el-form-item :label="t('birthday')" v-if="type == 'birthday'"> <el-form-item :label="t('birthday')" v-if="type == 'birthday'">
<el-date-picker v-model="saveData.birthday" value-format="YYYY-MM-DD" type="date" :placeholder="t('birthdayTip')" /> <el-date-picker v-model="saveData.birthday" value-format="YYYY-MM-DD" type="date" :placeholder="t('birthdayTip')" />

View File

@ -5,7 +5,7 @@
<el-checkbox v-model="formData.is_use" :true-label="1" :false-label="0" label="" size="large" /> <el-checkbox v-model="formData.is_use" :true-label="1" :false-label="0" label="" size="large" />
<span class="ml-[10px] el-form-item__label"></span> <span class="ml-[10px] el-form-item__label"></span>
<div class="w-[70px]"> <div class="w-[70px]">
<el-input v-model.trim="formData.money" clearable /> <el-input v-model.trim="formData.money" :maxlength="5" clearable />
</div> </div>
<span class="ml-[15px] el-form-item__label">元红包</span> <span class="ml-[15px] el-form-item__label">元红包</span>
</div> </div>
@ -33,26 +33,31 @@ const formData = ref({
money: '' money: ''
}) })
const formRef = ref(null) const formRef = ref(null)
//
const regExp = {
required: /[\S]+/,
number: /^\d{0,10}$/,
digit: /^\d{0,10}(.?\d{0,2})$/,
special: /^\d{0,10}(.?\d{0,3})$/
}
const formRules = reactive<FormRules>({ const formRules = reactive<FormRules>({
money: [ money: [
{ {
validator: (rule: any, value: any, callback: any) => { validator: (rule: any, value: any, callback: any) => {
if (formData.value.is_use) { if (formData.value.is_use) {
if (Test.empty(formData.value.money)) { if (Test.empty(value)) {
callback('请输入红包金额') callback('请输入红包金额')
} }else if (isNaN(value) || !regExp.digit.test(value)) {
if (!Test.amount(formData.value.money)) {
callback('红包金额格式错误') callback('红包金额格式错误')
} }else if (value <= 0) {
if (formData.value.money <= 0) {
callback('红包金额不能小于等于0') callback('红包金额不能小于等于0')
} }
callback() callback()
} else { } else {
callback() callback()
} }
} },
trigger: 'blur'
} }
] ]
}) })

View File

@ -32,26 +32,32 @@ const formData = ref({
}) })
const formRef = ref(null) const formRef = ref(null)
//
const regExp = {
required: /[\S]+/,
number: /^\d{0,10}$/,
digit: /^\d{0,10}(.?\d{0,2})$/,
special: /^\d{0,10}(.?\d{0,3})$/
}
const formRules = reactive<FormRules>({ const formRules = reactive<FormRules>({
num: [ num: [
{ {
validator: (rule: any, value: any, callback: Function) => { validator: (rule: any, value: any, callback: any) => {
if (formData.value.is_use) { if (formData.value.is_use) {
if (Test.empty(formData.value.num)) { if (value.length == 0) {
callback('请输入发放积分数量') callback('请输入积分数量')
} } else if (isNaN(value) || !regExp.number.test(value)) {
if (!Test.digits(formData.value.num)) {
callback('积分数量格式错误') callback('积分数量格式错误')
} } else if (value <=0) {
if (formData.value.num <= 0) {
callback('积分数量不能小于等于0') callback('积分数量不能小于等于0')
} else{
callback();
} }
callback()
} else { } else {
callback() callback()
} }
} },
trigger: 'blur'
} }
] ]
}) })

View File

@ -18,7 +18,7 @@
</el-form-item> </el-form-item>
<el-form-item :label="t('memo')" prop="memo"> <el-form-item :label="t('memo')" prop="memo">
<el-input v-model="formData.memo" type="textarea" rows="4" clearable :placeholder="t('memoPlaceholder')" class="input-width"/> <el-input v-model.trim="formData.memo" type="textarea" rows="4" clearable :placeholder="t('memoPlaceholder')" class="input-width"/>
</el-form-item> </el-form-item>
</el-form> </el-form>

View File

@ -18,7 +18,7 @@
</el-form-item> </el-form-item>
<el-form-item :label="t('memo')" prop="memo"> <el-form-item :label="t('memo')" prop="memo">
<el-input v-model="formData.memo" type="textarea" rows="4" clearable :placeholder="t('memoPlaceholder')" class="input-width"/> <el-input v-model.trim="formData.memo" type="textarea" rows="4" clearable :placeholder="t('memoPlaceholder')" class="input-width"/>
</el-form-item> </el-form-item>
</el-form> </el-form>

View File

@ -93,7 +93,7 @@ import { useRouter, useRoute } from 'vue-router'
const route = useRoute() const route = useRoute()
const pageName = route.meta.title const pageName = route.meta.title
const memberId: number = parseInt(route.query.id || 0) const member_id: number = parseInt(route.query.id || 0)
const memberAccountLogTableData = reactive({ const memberAccountLogTableData = reactive({
page: 1, page: 1,
@ -106,7 +106,7 @@ const memberAccountLogTableData = reactive({
from_type: '', from_type: '',
create_time: '', create_time: '',
mobile: '', mobile: '',
member_id: memberId member_id
} }
}) })

View File

@ -11,7 +11,7 @@
<el-card class="box-card !border-none my-[20px] table-search-wrap" shadow="never"> <el-card class="box-card !border-none my-[20px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="memberTableData.searchParam" ref="searchFormRef"> <el-form :inline="true" :model="memberTableData.searchParam" ref="searchFormRef">
<el-form-item :label="t('memberInfo')" prop="keyword"> <el-form-item :label="t('memberInfo')" prop="keyword">
<el-input v-model="memberTableData.searchParam.keyword" class="w-[240px]" :placeholder="t('memberInfoPlaceholder')" /> <el-input v-model.trim="memberTableData.searchParam.keyword" class="w-[240px]" :placeholder="t('memberInfoPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('registerChannel')" prop="register_channel"> <el-form-item :label="t('registerChannel')" prop="register_channel">
@ -56,8 +56,10 @@
<el-table-column prop="nickname" :show-overflow-tooltip="true" :label="t('memberInfo')" min-width="170"> <el-table-column prop="nickname" :show-overflow-tooltip="true" :label="t('memberInfo')" min-width="170">
<template #default="{ row }"> <template #default="{ row }">
<div class="flex items-center"> <div class="flex items-center">
<img class="w-[50px] h-[50px] mr-[10px]" v-if="row.headimg" :src="img(row.headimg)" alt=""> <div class="mr-[10px] rounded-full w-[50px] h-[50px] flex items-center justify-center">
<img class="w-[50px] h-[50px] mr-[10px] rounded-full" v-else src="@/app/assets/images/member_head.png" alt=""> <img class="max-w-[50px] max-h-[50px]" v-if="row.headimg" :src="img(row.headimg)" alt="">
<img class="max-w-[50px] max-h-[50px]" v-else src="@/app/assets/images/member_head.png" alt="">
</div>
<div class="flex flex flex-col"> <div class="flex flex flex-col">
<span>{{ row.nickname || '' }}</span> <span>{{ row.nickname || '' }}</span>
</div> </div>
@ -122,6 +124,7 @@
<add-member ref="addMemberDialog" @complete="loadMemberList()" /> <add-member ref="addMemberDialog" @complete="loadMemberList()" />
<edit-member ref="editMemberDialog" @complete="loadMemberList()" /> <edit-member ref="editMemberDialog" @complete="loadMemberList()" />
<export-sure ref="exportSureDialog" :show="flag" type="member" :searchParam="memberTableData.searchParam" @close="handleClose" /> <export-sure ref="exportSureDialog" :show="flag" type="member" :searchParam="memberTableData.searchParam" @close="handleClose" />
<detail-member ref="detailMemberDialog" @load="loadMemberList()"></detail-member>
</el-card> </el-card>
</div> </div>
</template> </template>
@ -130,10 +133,11 @@
import { reactive, ref } from 'vue' import { reactive, ref } from 'vue'
import { t } from '@/lang' import { t } from '@/lang'
import { img } from '@/utils/common' import { img } from '@/utils/common'
import { addMember, getRegisterChannelType, getMemberList, getMemberLabelAll, editMemberStatus, deleteMember, getMemberLevelAll } from '@/app/api/member' import { getRegisterChannelType, getMemberList, getMemberLabelAll, editMemberStatus, deleteMember, getMemberLevelAll } from '@/app/api/member'
import { ElMessageBox, FormInstance } from 'element-plus' import { ElMessageBox, FormInstance } from 'element-plus'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
import AddMember from '@/app/views/member/components/add-member.vue' import AddMember from '@/app/views/member/components/add-member.vue'
import detailMember from '@/app/views/member/components/detail-member.vue'
import EditMember from '@/app/views/member/components/edit-member.vue' import EditMember from '@/app/views/member/components/edit-member.vue'
const route = useRoute() const route = useRoute()
@ -204,6 +208,7 @@ loadMemberList()
const router = useRouter() const router = useRouter()
const addMemberDialog: Record<string, any> | null = ref(null) const addMemberDialog: Record<string, any> | null = ref(null)
const editMemberDialog: Record<string, any> | null = ref(null) const editMemberDialog: Record<string, any> | null = ref(null)
const detailMemberDialog: Record<string, any> | null = ref(null)
/** /**
* 设置标签 * 设置标签
@ -254,8 +259,10 @@ const editEvent = (data: any) => { }
/** /**
* 会员详情 * 会员详情
*/ */
const detailEvent = (data: any) => { const detailEvent = (res: any) => {
router.push(`/member/detail?id=${data.member_id}`) let data = {id: res.member_id};
detailMemberDialog.value.setFormData(data);
detailMemberDialog.value.showDialog = true;
} }
/** /**

View File

@ -35,7 +35,7 @@
<el-card class="box-card !border-none mb-[10px] table-search-wrap" shadow="never"> <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 :inline="true" :model="memberAccountLogTableData.searchParam" ref="searchFormRef">
<el-form-item :label="t('memberInfo')" prop="keywords"> <el-form-item :label="t('memberInfo')" prop="keywords">
<el-input v-model="memberAccountLogTableData.searchParam.keywords" class="w-[240px]" :placeholder="t('memberInfoPlaceholder')" /> <el-input v-model.trim="memberAccountLogTableData.searchParam.keywords" class="w-[240px]" :placeholder="t('memberInfoPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('fromType')" prop="from_type"> <el-form-item :label="t('fromType')" prop="from_type">
<el-select v-model="memberAccountLogTableData.searchParam.from_type" clearable :placeholder="t('fromTypePlaceholder')" class="input-width"> <el-select v-model="memberAccountLogTableData.searchParam.from_type" clearable :placeholder="t('fromTypePlaceholder')" class="input-width">

View File

@ -194,7 +194,6 @@
</el-form-item> </el-form-item>
</template> </template>
<!-- <el-form-item :label="t('旋转角度')">--> <!-- <el-form-item :label="t('旋转角度')">-->
<!-- <el-slider v-model="posterStore.editComponent.angle" show-input size="small" class="ml-[10px]" :min="0" :max="360" />--> <!-- <el-slider v-model="posterStore.editComponent.angle" show-input size="small" class="ml-[10px]" :min="0" :max="360" />-->
<!-- </el-form-item>--> <!-- </el-form-item>-->
@ -249,7 +248,6 @@ if(route && route.query){
route.query.back = route.query.back || '/admin/poster/list' route.query.back = route.query.back || '/admin/poster/list'
} }
const backPath:any = route.query.back const backPath:any = route.query.back
const template = ref(''); const template = ref('');
const oldTemplate = ref(''); const oldTemplate = ref('');
@ -262,8 +260,8 @@ const activeNames = ref(componentType)
const handleChange = (val: string[]) => { const handleChange = (val: string[]) => {
} }
const previewIframeStyle = (data)=>{ const previewIframeStyle = (data: any)=>{
let style = { let style: any = {
transform: '', transform: '',
zIndex: '', zIndex: '',
top: '', top: '',
@ -323,6 +321,7 @@ const xAlignList = ref([
className: 'right' className: 'right'
} }
]) ])
// //
const yAlignList = ref([ const yAlignList = ref([
{ {
@ -341,9 +340,8 @@ const yAlignList = ref([
className: 'bottom' className: 'bottom'
}, },
]) ])
const alignChangeFn = (type,data)=>{ const alignChangeFn = (type: any,data: any)=>{
posterStore.editComponent[type] = data.className; posterStore.editComponent[type] = data.className;
} }
// //

View File

@ -10,7 +10,7 @@
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> <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 :inline="true" :model="posterTableData.searchParam" ref="searchFormDiyPosterRef">
<el-form-item :label="t('posterName')" prop="name"> <el-form-item :label="t('posterName')" prop="name">
<el-input v-model="posterTableData.searchParam.name" :placeholder="t('posterNamePlaceholder')" /> <el-input v-model.trim="posterTableData.searchParam.name" :placeholder="t('posterNamePlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('posterType')" prop="type"> <el-form-item :label="t('posterType')" prop="type">
<el-select v-model="posterTableData.searchParam.type" :placeholder="t('posterTypePlaceholder')"> <el-select v-model="posterTableData.searchParam.type" :placeholder="t('posterTypePlaceholder')">
@ -66,14 +66,14 @@
</el-card> </el-card>
<!--添加海报--> <!--添加海报-->
<el-dialog v-model="dialogVisible" :title="t('addPosterTitle')" width="25%"> <el-dialog v-model="dialogVisible" :title="t('addPosterTitle')" width="350px">
<el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules"> <el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules">
<el-form-item :label="t('posterName')" prop="name"> <el-form-item :label="t('posterName')" prop="name">
<el-input v-model="formData.name" :placeholder="t('posterNamePlaceholder')" clearable maxlength="12" show-word-limit class="w-full" /> <el-input v-model.trim="formData.name" :placeholder="t('posterNamePlaceholder')" clearable maxlength="12" show-word-limit class="w-full" />
</el-form-item> </el-form-item>
<el-form-item :label="t('posterType')" prop="type"> <el-form-item :label="t('posterType')" prop="type">
<el-select v-model="formData.type" :placeholder="t('posterTypePlaceholder')" class="w-full"> <el-select v-model="formData.type" :placeholder="t('posterTypePlaceholder')" class="!w-full">
<el-option v-for="item in posterType" :label="item.name" :value="item.type" :key="item.type"/> <el-option v-for="item in posterType" :label="item.name" :value="item.type" :key="item.type"/>
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -151,7 +151,7 @@ const addEvent = async (formEl: FormInstance | undefined) => {
} }
// //
const loadPosterType = (addon = '')=> { const loadPosterType = ()=> {
getPosterType({}).then((res:any)=>{ getPosterType({}).then((res:any)=>{
for (let key in posterType) { for (let key in posterType) {
delete posterType[key]; delete posterType[key];

View File

@ -17,7 +17,7 @@
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never"> <el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="printerTemplateTable.searchParam" ref="searchFormRef"> <el-form :inline="true" :model="printerTemplateTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('templateName')" prop="template_name"> <el-form-item :label="t('templateName')" prop="template_name">
<el-input v-model="printerTemplateTable.searchParam.template_name" :placeholder="t('templateNamePlaceholder')" /> <el-input v-model.trim="printerTemplateTable.searchParam.template_name" :placeholder="t('templateNamePlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('templateType')" prop="template_type"> <el-form-item :label="t('templateType')" prop="template_type">
<el-select v-model="printerTemplateTable.searchParam.template_type" :placeholder="t('templateTypePlaceholder')" clearable> <el-select v-model="printerTemplateTable.searchParam.template_type" :placeholder="t('templateTypePlaceholder')" clearable>

View File

@ -13,7 +13,7 @@
<el-form-item :label="t('title')" prop="title"> <el-form-item :label="t('title')" prop="title">
<el-input v-model.trim="formData.title" clearable :placeholder="t('titlePlaceholder')" class="input-width" maxlength="20" /> <el-input v-model.trim="formData.title" clearable :placeholder="t('titlePlaceholder')" class="input-width" maxlength="20" />
</el-form-item> </el-form-item>
<el-form-item :label="t('content')"> <el-form-item :label="t('content')" prop="content">
<editor v-model="formData.content" /> <editor v-model="formData.content" />
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -73,6 +73,22 @@ const formRules = computed(() => {
return { return {
title: [ title: [
{ required: true, message: t('titlePlaceholder'), trigger: 'blur' } { required: true, message: t('titlePlaceholder'), trigger: 'blur' }
],
content: [
{
required: true,
trigger: ['blur', 'change'],
validator: (rule: any, value: any, callback: any) => {
if (value === '') {
callback(new Error(t('contentPlaceholder')))
} else if (value.length < 5 || value.length > 50000) {
callback(new Error(t('contentMaxTips')))
return false
} else {
callback()
}
}
}
] ]
} }
}) })
@ -100,4 +116,8 @@ const back = () => {
} }
</script> </script>
<style lang="scss" scoped></style> <style lang="scss">
.edui-default .edui-editor{
z-index: 1 !important;
}
</style>

View File

@ -15,11 +15,11 @@
</el-form-item> </el-form-item>
<el-form-item :label="t('cashWithdrawalAmount')" v-if="formData.is_open" prop="min"> <el-form-item :label="t('cashWithdrawalAmount')" v-if="formData.is_open" prop="min">
<el-input v-model="formData.min" @keyup="filterDigit($event)" class="input-width" :placeholder="t('cashWithdrawalAmountPlaceholder')" /> <el-input v-model.trim="formData.min" @keyup="filterDigit($event)" class="input-width" :placeholder="t('cashWithdrawalAmountPlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item :label="t('commissionRatio')" v-if="formData.is_open" prop="rate"> <el-form-item :label="t('commissionRatio')" v-if="formData.is_open" prop="rate">
<el-input v-model="formData.rate" @keyup="filterDigit($event)" class="input-width" :placeholder="t('commissionRatioPlaceholder')" /> <el-input v-model.trim="formData.rate" @keyup="filterDigit($event)" class="input-width" :placeholder="t('commissionRatioPlaceholder')" />
<span class="ml-2">%</span> <span class="ml-2">%</span>
</el-form-item> </el-form-item>

View File

@ -17,7 +17,7 @@
</el-form-item> </el-form-item>
<el-form-item :label="t('smsId')" prop="sms_id"> <el-form-item :label="t('smsId')" prop="sms_id">
<el-input v-model="formData.sms_id" :placeholder="t('smsIdPlaceholder')" class="input-width" show-word-limit clearable /> <el-input v-model.trim="formData.sms_id" :placeholder="t('smsIdPlaceholder')" class="input-width" show-word-limit clearable />
</el-form-item> </el-form-item>
<el-form-item :label="t('smsContent')"> <el-form-item :label="t('smsContent')">

View File

@ -21,7 +21,7 @@
</el-form-item> </el-form-item>
<!-- <el-form-item :label="t('first')" prop="first">--> <!-- <el-form-item :label="t('first')" prop="first">-->
<!-- <el-input v-model="formData.wechat_first" :placeholder="t('firstPlaceholder')" class="input-width" show-word-limit clearable />--> <!-- <el-input v-model.trim="formData.wechat_first" :placeholder="t('firstPlaceholder')" class="input-width" show-word-limit clearable />-->
<!-- </el-form-item>--> <!-- </el-form-item>-->
<el-form-item :label="t('content')"> <el-form-item :label="t('content')">
@ -31,7 +31,7 @@
</el-form-item> </el-form-item>
<!-- <el-form-item :label="t('remark')" prop="remark">--> <!-- <el-form-item :label="t('remark')" prop="remark">-->
<!-- <el-input v-model="formData.wechat_remark" :placeholder="t('remarkPlaceholder')" class="input-width" show-word-limit clearable />--> <!-- <el-input v-model.trim="formData.wechat_remark" :placeholder="t('remarkPlaceholder')" class="input-width" show-word-limit clearable />-->
<!-- </el-form-item>--> <!-- </el-form-item>-->
</el-form> </el-form>

View File

@ -7,7 +7,7 @@
<div class="form-tip">{{ t('appIdTips') }}</div> <div class="form-tip">{{ t('appIdTips') }}</div>
</el-form-item> </el-form-item>
<el-form-item :label="t('appSecretCert')" prop="config.app_secret_cert"> <el-form-item :label="t('appSecretCert')" prop="config.app_secret_cert">
<el-input v-model="formData.config.app_secret_cert" :placeholder="t('appSecretCertPlaceholder')" class="input-width" type="textarea" rows="4" clearable /> <el-input v-model.trim="formData.config.app_secret_cert" :placeholder="t('appSecretCertPlaceholder')" class="input-width" type="textarea" rows="4" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="t('appPublicCertPath')" prop="config.app_public_cert_path"> <el-form-item :label="t('appPublicCertPath')" prop="config.app_public_cert_path">

View File

@ -3,19 +3,19 @@
<el-form :model="formData" label-width="110px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading"> <el-form :model="formData" label-width="110px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
<el-form-item :label="t('collectionName')" prop="config.collection_name"> <el-form-item :label="t('collectionName')" prop="config.collection_name">
<el-input v-model="formData.config.collection_name" :placeholder="t('collectionNamePlaceholder')" class="input-width" show-word-limit clearable /> <el-input v-model.trim="formData.config.collection_name" :placeholder="t('collectionNamePlaceholder')" class="input-width" show-word-limit clearable />
</el-form-item> </el-form-item>
<el-form-item :label="t('collectionBank')" prop="config.collection_bank"> <el-form-item :label="t('collectionBank')" prop="config.collection_bank">
<el-input v-model="formData.config.collection_bank" :placeholder="t('collectionBankPlaceholder')" class="input-width" clearable /> <el-input v-model.trim="formData.config.collection_bank" :placeholder="t('collectionBankPlaceholder')" class="input-width" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="t('collectionAccount')" prop="config.collection_account"> <el-form-item :label="t('collectionAccount')" prop="config.collection_account">
<el-input v-model="formData.config.collection_account" :placeholder="t('collectionAccountPlaceholder')" class="input-width" clearable /> <el-input v-model.trim="formData.config.collection_account" :placeholder="t('collectionAccountPlaceholder')" class="input-width" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="t('collectionDesc')" prop="config.collection_desc"> <el-form-item :label="t('collectionDesc')" prop="config.collection_desc">
<el-input v-model="formData.config.collection_desc" :placeholder="t('collectionDescPlaceholder')" class="input-width" type="textarea" rows="4" clearable /> <el-input v-model.trim="formData.config.collection_desc" :placeholder="t('collectionDescPlaceholder')" class="input-width" type="textarea" rows="4" clearable />
</el-form-item> </el-form-item>
</el-form> </el-form>

View File

@ -1,6 +1,6 @@
<template> <template>
<el-dialog v-model="showDialog" :title="t('updateWechat')" width="500px" :destroy-on-close="true"> <el-dialog v-model="showDialog" :title="t('updateWechat')" 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 :model="formData" label-width="140px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
<el-form-item :label="t('mchId')" prop="config.mch_id"> <el-form-item :label="t('mchId')" prop="config.mch_id">
<el-input v-model.trim="formData.config.mch_id" :placeholder="t('mchIdPlaceholder')" class="input-width" maxlength="32" show-word-limit clearable /> <el-input v-model.trim="formData.config.mch_id" :placeholder="t('mchIdPlaceholder')" class="input-width" maxlength="32" show-word-limit clearable />
@ -26,6 +26,35 @@
<div class="form-tip">{{ t('mchPublicCertPathTips') }}</div> <div class="form-tip">{{ t('mchPublicCertPathTips') }}</div>
</el-form-item> </el-form-item>
<el-form-item :label="t('jsapiDir')" v-show="formData.channel == 'wechat' || formData.channel == 'weapp'">
<el-input :model-value="wapDomain + '/'" placeholder="Please input" class="input-width" :readonly="true" :disabled="true">
<template #append>
<div class="cursor-pointer" @click="copyEvent(wapDomain + '/')">{{ t('copy') }}
</div>
</template>
</el-input>
<div class="form-tip !leading-normal">{{ t('jsapiDirTips') }}</div>
</el-form-item>
<el-form-item :label="t('h5Domain')" v-show="formData.channel == 'h5'">
<el-input :model-value="wapDomain.replace('http://', '').replace('https://', '')" placeholder="Please input" class="input-width" :readonly="true" :disabled="true">
<template #append>
<div class="cursor-pointer" @click="copyEvent(wapDomain.replace('http://', '').replace('https://', ''))">{{ t('copy') }}
</div>
</template>
</el-input>
<div class="form-tip !leading-normal">{{ t('h5DomainTips') }}</div>
</el-form-item>
<el-form-item :label="t('nativeDomain')" v-show="formData.channel == 'pc'">
<el-input :model-value="serviceDomain" placeholder="Please input" class="input-width" :readonly="true" :disabled="true">
<template #append>
<div class="cursor-pointer" @click="copyEvent(serviceDomain)">{{ t('copy') }}
</div>
</template>
</el-input>
<div class="form-tip !leading-normal">{{ t('nativeDomainTips') }}</div>
</el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
@ -38,13 +67,22 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, reactive, computed } from 'vue' import { ref, reactive, computed, watch } from 'vue'
import { t } from '@/lang' import { t } from '@/lang'
import type { FormInstance } from 'element-plus' import { FormInstance, ElMessage } from 'element-plus'
import Test from '@/utils/test' import Test from '@/utils/test'
import { getUrl } from '@/app/api/sys'
import { useClipboard } from '@vueuse/core'
const showDialog = ref(false) const showDialog = ref(false)
const loading = ref(true) const loading = ref(true)
const wapDomain = ref('')
const serviceDomain = ref('')
getUrl().then((res: any) => {
wapDomain.value = res.data.wap_domain
serviceDomain.value = res.data.service_domain
})
/** /**
* 表单数据 * 表单数据
@ -118,6 +156,30 @@ const enableVerify = () => {
return verify return verify
} }
/**
* 复制
*/
const { copy, isSupported, copied } = useClipboard()
const copyEvent = (text: string) => {
if (!isSupported.value) {
ElMessage({
message: t('notSupportCopy'),
type: 'warning'
})
return
}
copy(text)
}
watch(copied, () => {
if (copied.value) {
ElMessage({
message: t('copySuccess'),
type: 'success'
})
}
})
defineExpose({ defineExpose({
showDialog, showDialog,
setFormData, setFormData,

View File

@ -9,25 +9,25 @@
</el-form-item> </el-form-item>
<el-form-item :label="t('aliBucket')" prop="bucket"> <el-form-item :label="t('aliBucket')" prop="bucket">
<el-input v-model="formData.bucket" :placeholder="t('aliBucketPlaceholder')" class="input-width" show-word-limit clearable /> <el-input v-model.trim="formData.bucket" :placeholder="t('aliBucketPlaceholder')" class="input-width" show-word-limit clearable />
<div class="form-tip">{{ t('aliBucketTips') }}</div> <div class="form-tip">{{ t('aliBucketTips') }}</div>
</el-form-item> </el-form-item>
<el-form-item :label="t('aliAccessKey')" prop="access_key"> <el-form-item :label="t('aliAccessKey')" prop="access_key">
<el-input v-model="formData.access_key" :placeholder="t('aliAccessKeyPlaceholder')" class="input-width" clearable /> <el-input v-model.trim="formData.access_key" :placeholder="t('aliAccessKeyPlaceholder')" class="input-width" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="t('aliSecretKey')" prop="secret_key"> <el-form-item :label="t('aliSecretKey')" prop="secret_key">
<el-input v-model="formData.secret_key" :placeholder="t('aliSecretKeyPlaceholder')" class="input-width" clearable /> <el-input v-model.trim="formData.secret_key" :placeholder="t('aliSecretKeyPlaceholder')" class="input-width" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="t('aliEndpoint')" prop="endpoint"> <el-form-item :label="t('aliEndpoint')" prop="endpoint">
<el-input v-model="formData.endpoint" :placeholder="t('aliEndpointPlaceholder')" class="input-width" clearable /> <el-input v-model.trim="formData.endpoint" :placeholder="t('aliEndpointPlaceholder')" class="input-width" clearable />
<div class="form-tip">{{ t('aliEndpointTips') }}</div> <div class="form-tip">{{ t('aliEndpointTips') }}</div>
</el-form-item> </el-form-item>
<el-form-item :label="t('domain')" prop="domain"> <el-form-item :label="t('domain')" prop="domain">
<el-input v-model="formData.domain" :placeholder="t('domainPlaceholder')" class="input-width" clearable /> <el-input v-model.trim="formData.domain" :placeholder="t('domainPlaceholder')" class="input-width" clearable />
</el-form-item> </el-form-item>
</el-form> </el-form>

View File

@ -9,20 +9,20 @@
</el-form-item> </el-form-item>
<el-form-item :label="t('qiniuBucket')" prop="bucket"> <el-form-item :label="t('qiniuBucket')" prop="bucket">
<el-input v-model="formData.bucket" :placeholder="t('qiniuBucketPlaceholder')" class="input-width" show-word-limit clearable /> <el-input v-model.trim="formData.bucket" :placeholder="t('qiniuBucketPlaceholder')" class="input-width" show-word-limit clearable />
<div class="form-tip">{{ t('qiniuBucketTips') }}</div> <div class="form-tip">{{ t('qiniuBucketTips') }}</div>
</el-form-item> </el-form-item>
<el-form-item :label="t('qiniuAccessKey')" prop="access_key"> <el-form-item :label="t('qiniuAccessKey')" prop="access_key">
<el-input v-model="formData.access_key" :placeholder="t('qiniuAccessKeyPlaceholder')" class="input-width" clearable /> <el-input v-model.trim="formData.access_key" :placeholder="t('qiniuAccessKeyPlaceholder')" class="input-width" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="t('qiniuSecretKey')" prop="secret_key"> <el-form-item :label="t('qiniuSecretKey')" prop="secret_key">
<el-input v-model="formData.secret_key" :placeholder="t('qiniuSecretKeyPlaceholder')" class="input-width" clearable /> <el-input v-model.trim="formData.secret_key" :placeholder="t('qiniuSecretKeyPlaceholder')" class="input-width" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="t('domain')" prop="domain"> <el-form-item :label="t('domain')" prop="domain">
<el-input v-model="formData.domain" :placeholder="t('domainPlaceholder')" class="input-width" clearable /> <el-input v-model.trim="formData.domain" :placeholder="t('domainPlaceholder')" class="input-width" clearable />
</el-form-item> </el-form-item>
</el-form> </el-form>

View File

@ -9,24 +9,24 @@
</el-form-item> </el-form-item>
<el-form-item :label="t('tencentBucket')" prop="bucket"> <el-form-item :label="t('tencentBucket')" prop="bucket">
<el-input v-model="formData.bucket" :placeholder="t('tencentBucketPlaceholder')" class="input-width" show-word-limit clearable /> <el-input v-model.trim="formData.bucket" :placeholder="t('tencentBucketPlaceholder')" class="input-width" show-word-limit clearable />
<div class="form-tip">{{ t('tencentBucketTips') }}</div> <div class="form-tip">{{ t('tencentBucketTips') }}</div>
</el-form-item> </el-form-item>
<el-form-item :label="t('tencentAccessKey')" prop="access_key"> <el-form-item :label="t('tencentAccessKey')" prop="access_key">
<el-input v-model="formData.access_key" :placeholder="t('tencentAccessKeyPlaceholder')" class="input-width" clearable /> <el-input v-model.trim="formData.access_key" :placeholder="t('tencentAccessKeyPlaceholder')" class="input-width" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="t('tencentSecretKey')" prop="secret_key"> <el-form-item :label="t('tencentSecretKey')" prop="secret_key">
<el-input v-model="formData.secret_key" :placeholder="t('tencentSecretKeyPlaceholder')" class="input-width" clearable /> <el-input v-model.trim="formData.secret_key" :placeholder="t('tencentSecretKeyPlaceholder')" class="input-width" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="t('region')" prop="region"> <el-form-item :label="t('region')" prop="region">
<el-input v-model="formData.region" :placeholder="t('regionPlaceholder')" class="input-width" clearable /> <el-input v-model.trim="formData.region" :placeholder="t('regionPlaceholder')" class="input-width" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="t('domain')" prop="domain"> <el-form-item :label="t('domain')" prop="domain">
<el-input v-model="formData.domain" :placeholder="t('domainPlaceholder')" class="input-width" clearable /> <el-input v-model.trim="formData.domain" :placeholder="t('domainPlaceholder')" class="input-width" clearable />
</el-form-item> </el-form-item>
</el-form> </el-form>

View File

@ -9,13 +9,13 @@
<upload-image v-model="formData.logo" /> <upload-image v-model="formData.logo" />
</el-form-item> </el-form-item>
<el-form-item :label="t('companyName')" prop="company_name"> <el-form-item :label="t('companyName')" prop="company_name">
<el-input v-model="formData.company_name" :placeholder="t('companyNamePlaceholder')" class="input-width" clearable maxlength="30"/> <el-input v-model.trim="formData.company_name" :placeholder="t('companyNamePlaceholder')" class="input-width" clearable maxlength="30"/>
</el-form-item> </el-form-item>
<el-form-item :label="t('copyrightLink')" > <el-form-item :label="t('copyrightLink')" >
<el-input v-model="formData.copyright_link" :placeholder="t('copyrightLinkPlaceholder')" class="input-width" clearable /> <el-input v-model.trim="formData.copyright_link" :placeholder="t('copyrightLinkPlaceholder')" class="input-width" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="t('copyrightDesc')" > <el-form-item :label="t('copyrightDesc')" >
<el-input v-model="formData.copyright_desc" type="textarea" rows="4" clearable :placeholder="t('copyrightDescPlaceholder')" class="input-width" maxlength="150" /> <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-form-item>
</el-card> </el-card>
@ -23,16 +23,16 @@
<h3 class="panel-title !text-sm">{{ t('putOnRecordEdit') }}</h3> <h3 class="panel-title !text-sm">{{ t('putOnRecordEdit') }}</h3>
<el-form-item :label="t('icp')" prop="icp"> <el-form-item :label="t('icp')" prop="icp">
<el-input v-model="formData.icp" :placeholder="t('icpPlaceholder')" class="input-width" clearable maxlength="20"/> <el-input v-model.trim="formData.icp" :placeholder="t('icpPlaceholder')" class="input-width" clearable maxlength="20"/>
</el-form-item> </el-form-item>
<el-form-item :label="t('govRecord')" > <el-form-item :label="t('govRecord')" >
<el-input v-model="formData.gov_record" :placeholder="t('govRecordPlaceholder')" class="input-width" clearable maxlength="50"/> <el-input v-model.trim="formData.gov_record" :placeholder="t('govRecordPlaceholder')" class="input-width" clearable maxlength="50"/>
</el-form-item> </el-form-item>
<el-form-item :label="t('govUrl')" > <el-form-item :label="t('govUrl')" >
<el-input v-model="formData.gov_url" :placeholder="t('govUrlPlaceholder')" class="input-width" clearable /> <el-input v-model.trim="formData.gov_url" :placeholder="t('govUrlPlaceholder')" class="input-width" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="t('marketSupervisionUrl')" > <el-form-item :label="t('marketSupervisionUrl')" >
<el-input v-model="formData.market_supervision_url" rows="4" clearable :placeholder="t('marketSupervisionUrlPlaceholder')" class="input-width" /> <el-input v-model.trim="formData.market_supervision_url" rows="4" clearable :placeholder="t('marketSupervisionUrlPlaceholder')" class="input-width" />
</el-form-item> </el-form-item>
</el-card> </el-card>
</el-form> </el-form>

View File

@ -6,7 +6,7 @@
<el-form-item label="" prop="token"> <el-form-item label="" prop="token">
<div> <div>
<el-input v-model="formData.token" :placeholder="t('tokenPlaceholder')" class="input-width" clearable maxlength="30"/> <el-input v-model.trim="formData.token" :placeholder="t('tokenPlaceholder')" class="input-width" clearable maxlength="30"/>
</div> </div>
<div class="text-[14px] text-[#a9a9a9] leading-tight mt-[10px]">{{ t('tokenTips') }}</div> <div class="text-[14px] text-[#a9a9a9] leading-tight mt-[10px]">{{ t('tokenTips') }}</div>
</el-form-item> </el-form-item>
@ -32,7 +32,7 @@ const formData = ref({
getDeveloperToken().then(({ data }) => { getDeveloperToken().then(({ data }) => {
loading.value = false loading.value = false
data.token && (formData.value = data) data.token && (formData.value = data)
}).catch() })
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()

View File

@ -6,19 +6,19 @@
<h3 class="panel-title !text-sm">{{ t('commonSetting') }}</h3> <h3 class="panel-title !text-sm">{{ t('commonSetting') }}</h3>
<el-form-item :label="t('logonMode')" prop="type"> <el-form-item :label="t('logonMode')" prop="type">
<el-checkbox v-model="formData.is_username" :label="t('isUsername')" :true-value="1" :false-value="0" @change="switchChange($event, 'is_username')" /> <el-checkbox v-model="formData.is_username" :true-value="1" :false-value="0" :label="t('isUsername')" />
<div class="form-tip">{{ t('isUsernameTip') }}</div> <div class="form-tip mb-[10px]">{{ t('isUsernameTip') }}</div>
<el-checkbox v-model="formData.is_mobile" :label="t('isMobile')" :true-value="1" :false-value="0" @change="switchChange($event, 'is_mobile')" /> <el-checkbox v-model="formData.is_mobile" :true-value="1" :false-value="0" :label="t('isMobile')" />
<div class="form-tip">{{ t('isMobileTip') }}</div> <div class="form-tip">{{ t('isMobileTip') }}</div>
</el-form-item> </el-form-item>
<el-form-item :label="t('isBindMobile')" prop="formData.is_bind_mobile"> <el-form-item :label="t('isBindMobile')" prop="formData.is_bind_mobile">
<el-switch v-model="formData.is_bind_mobile" :active-value="1" :inactive-value="0" @change="switchChange($event, 'is_bind_mobile')" /> <el-switch v-model="formData.is_bind_mobile" :active-value="1" :inactive-value="0" />
<div class="form-tip">{{ t('isBindMobileTip') }}</div> <div class="form-tip">{{ t('isBindMobileTip') }}</div>
</el-form-item> </el-form-item>
<el-form-item :label="t('agreement')" prop="formData.agreement_show"> <el-form-item :label="t('agreement')" prop="formData.agreement_show">
<el-switch v-model="formData.agreement_show" :active-value="1" :inactive-value="0" @change="switchChange($event, 'agreement_show')" /> <el-switch v-model="formData.agreement_show" :active-value="1" :inactive-value="0" />
<div class="form-tip">{{ t('agreementTips') }}</div> <div class="form-tip">{{ t('agreementTips') }}</div>
</el-form-item> </el-form-item>
</el-card> </el-card>
@ -27,10 +27,24 @@
<h3 class="panel-title !text-sm">{{ t('tripartiteSetting') }}</h3> <h3 class="panel-title !text-sm">{{ t('tripartiteSetting') }}</h3>
<el-form-item :label="t('isAuthRegister')" prop="formData.is_auth_register"> <el-form-item :label="t('isAuthRegister')" prop="formData.is_auth_register">
<el-switch v-model="formData.is_auth_register" :active-value="1" :inactive-value="0" @change="switchChange($event, 'is_auth_register')" /> <el-switch v-model="formData.is_auth_register" :active-value="1" :inactive-value="0" />
<div class="form-tip">{{ t('isAuthRegisterTip') }}</div> <div class="form-tip">{{ t('isAuthRegisterTip') }}</div>
</el-form-item> </el-form-item>
</el-card> </el-card>
<el-card class="box-card mt-[15px] !border-none" shadow="never">
<h3 class="panel-title !text-sm">{{ t('loginPageSet') }}</h3>
<el-form-item :label="t('bgUrl')">
<div>
<upload-image v-model="formData.bg_url" />
<p class="text-[12px] text-[#a9a9a9]">{{ t('bgUrlPlaceholder') }}</p>
</div>
</el-form-item>
<el-form-item :label="t('desc')">
<el-input v-model.trim="formData.desc" :placeholder="t('descPlaceholder')" class="input-width" clearable maxlength="20" show-word-limit />
</el-form-item>
</el-card>
</el-form> </el-form>
<div class="fixed-footer-wrap"> <div class="fixed-footer-wrap">
@ -54,12 +68,15 @@ const pageName = route.meta.title
const loading = ref(true) const loading = ref(true)
const ruleFormRef = ref<FormInstance>() const ruleFormRef = ref<FormInstance>()
const formData = reactive<Record<string, number | boolean>>({ const formData:any = reactive({
is_username: 0, is_username: 0,
is_mobile: 0, is_mobile: 0,
is_auth_register: 0, is_auth_register: 0,
is_bind_mobile: 0, is_bind_mobile: 0,
agreement_show: 0 agreement_show: 0,
bg_url: '',
logo: '',
desc: ''
}) })
const formRules = computed(() => { const formRules = computed(() => {
@ -83,24 +100,17 @@ const formRules = computed(() => {
const setFormData = async () => { const setFormData = async () => {
const data = await (await getLoginConfig()).data const data = await (await getLoginConfig()).data
Object.keys(formData).forEach((key: string) => { Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = Number(data[key]) if (data[key] != undefined) formData[key] = data[key]
}) })
loading.value = false loading.value = false
} }
setFormData() setFormData()
const switchChange = (val, key) => {
formData[key] = val
}
const onSave = async (formEl: FormInstance | undefined) => { const onSave = async (formEl: FormInstance | undefined) => {
if (loading.value || !formEl) return if (loading.value || !formEl) return
await formEl.validate((valid) => { await formEl.validate((valid) => {
if (valid) { if (valid) {
const save = cloneDeep(formData) const save = cloneDeep(formData)
Object.keys(save).forEach((key) => {
save[key] = Number(save[key])
})
setLoginConfig(save).then(() => { setLoginConfig(save).then(() => {
loading.value = false loading.value = false

View File

@ -38,11 +38,11 @@ import { t } from '@/lang'
import { setMap, getMap } from '@/app/api/sys' import { setMap, getMap } from '@/app/api/sys'
import { FormInstance } from 'element-plus' import { FormInstance } from 'element-plus'
const loading = ref(false) const loading = ref(true)
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()
const formData = reactive<Record<string, string>>({ const formData = reactive({
key: '', key: '',
is_open: 1, is_open: 0,
valid_time: 0 valid_time: 0
}) })
@ -69,8 +69,12 @@ const formRules = computed(() => {
}); });
const setFormData = async () => { const setFormData = async () => {
loading.value = true
const service_data = await (await getMap()).data const service_data = await (await getMap()).data
formData.key = service_data.key formData.key = service_data.key
formData.is_open = service_data.is_open
formData.valid_time = service_data.valid_time
loading.value = false
} }
setFormData() setFormData()

View File

@ -6,7 +6,7 @@
<h3 class="panel-title !text-sm">{{ t('memberNoRule') }}</h3> <h3 class="panel-title !text-sm">{{ t('memberNoRule') }}</h3>
<el-form-item :label="t('prefix')" prop="prefix"> <el-form-item :label="t('prefix')" prop="prefix">
<el-input v-model="formData.prefix" :placeholder="t('prefixPlaceholder')" class="input-width" clearable maxlength="20" @change="getMemberNo(ruleFormRef)"/> <el-input v-model.trim="formData.prefix" :placeholder="t('prefixPlaceholder')" class="input-width" clearable maxlength="20" @change="getMemberNo(ruleFormRef)"/>
</el-form-item> </el-form-item>
<el-form-item :label="t('length')" prop="length"> <el-form-item :label="t('length')" prop="length">
<el-input v-model.trim="formData.length" :placeholder="t('lengthPlaceholder')" class="input-width" clearable @keyup="filterNumber($event)" @change="getMemberNo(ruleFormRef)" @blur="formData.length = $event.target.value"/> <el-input v-model.trim="formData.length" :placeholder="t('lengthPlaceholder')" class="input-width" clearable @keyup="filterNumber($event)" @change="getMemberNo(ruleFormRef)" @blur="formData.length = $event.target.value"/>

View File

@ -46,25 +46,19 @@
<el-table-column :label="t('operation')" align="right" fixed="right" min-width="300"> <el-table-column :label="t('operation')" align="right" fixed="right" min-width="300">
<template #default="{ row }"> <template #default="{ row }">
<div class="flex"> <div class="flex">
<div class="text-sm mr-1 flex items-center cursor-pointer" <div class="text-sm mr-1 flex items-center cursor-pointer" v-if="row.support_type.indexOf('sms') != -1" @click="setNotice(row, 'sms')">
v-if="row.support_type.indexOf('sms') != -1"
@click="setNotice(row, 'sms')">
<el-icon class="text-[15px] mr-[3px]" :class="row.is_sms ? 'open' : ''"> <el-icon class="text-[15px] mr-[3px]" :class="row.is_sms ? 'open' : ''">
<SuccessFilled /> <SuccessFilled />
</el-icon> </el-icon>
<span class="ml-0.5">{{ t('sms') }}</span> <span class="ml-0.5">{{ t('sms') }}</span>
</div> </div>
<div class="text-sm flex items-center cursor-pointer ml-[20px]" <div class="text-sm flex items-center cursor-pointer ml-[20px]" v-if="row.support_type.indexOf('wechat') != -1" @click="setNotice(row, 'wechat')">
v-if="row.support_type.indexOf('wechat') != -1"
@click="setNotice(row, 'wechat')">
<el-icon class="text-[15px] mr-[3px]" :class="row.is_wechat ? 'open' : ''"> <el-icon class="text-[15px] mr-[3px]" :class="row.is_wechat ? 'open' : ''">
<SuccessFilled /> <SuccessFilled />
</el-icon> </el-icon>
<span class="ml-0.5">{{ t('wechat') }}</span> <span class="ml-0.5">{{ t('wechat') }}</span>
</div> </div>
<div class="text-sm flex items-center cursor-pointer ml-[20px]" <div class="text-sm flex items-center cursor-pointer ml-[20px]" v-if="row.support_type.indexOf('weapp') != -1" @click="setNotice(row, 'weapp')">
v-if="row.support_type.indexOf('weapp') != -1"
@click="setNotice(row, 'weapp')">
<el-icon class="text-[15px] mr-[3px]" :class="row.is_weapp ? 'open' : ''"> <el-icon class="text-[15px] mr-[3px]" :class="row.is_weapp ? 'open' : ''">
<SuccessFilled /> <SuccessFilled />
</el-icon> </el-icon>
@ -135,7 +129,6 @@ const loadNoticeList = () => {
}) })
noticeTableData.loading = false noticeTableData.loading = false
}).catch((e) => { }).catch((e) => {
console.log(e)
noticeTableData.loading = false noticeTableData.loading = false
}) })
} }

View File

@ -21,20 +21,20 @@
</div> </div>
</el-form-item> </el-form-item>
<el-form-item :label="t('keywords')"> <el-form-item :label="t('keywords')">
<el-input v-model="formData.keywords" :placeholder="t('keywordsPlaceholder')" class="input-width" clearable maxlength="20" show-word-limit /> <el-input v-model.trim="formData.keywords" :placeholder="t('keywordsPlaceholder')" class="input-width" clearable maxlength="20" show-word-limit />
</el-form-item> </el-form-item>
<el-form-item :label="t('desc')"> <el-form-item :label="t('desc')">
<el-input v-model="formData.desc" type="textarea" :rows="4" clearable :placeholder="t('descPlaceholder')" class="input-width" maxlength="100" show-word-limit /> <el-input v-model.trim="formData.desc" type="textarea" :rows="4" clearable :placeholder="t('descPlaceholder')" class="input-width" maxlength="100" show-word-limit />
</el-form-item> </el-form-item>
</el-card> </el-card>
<el-card class="box-card mt-[15px] !border-none" shadow="never"> <el-card class="box-card mt-[15px] !border-none" shadow="never">
<h3 class="panel-title !text-sm">{{ t('frontEndInfo') }}</h3> <h3 class="panel-title !text-sm">{{ t('frontEndInfo') }}</h3>
<el-form-item :label="t('frontEndName')"> <el-form-item :label="t('frontEndName')">
<el-input v-model="formData.front_end_name" :placeholder="t('frontEndNamePlaceholder')" class="input-width" clearable maxlength="20" show-word-limit /> <el-input v-model.trim="formData.front_end_name" :placeholder="t('frontEndNamePlaceholder')" class="input-width" clearable maxlength="20" show-word-limit />
</el-form-item> </el-form-item>
<el-form-item :label="t('phone')"> <el-form-item :label="t('phone')">
<el-input v-model="formData.phone" :placeholder="t('phonePlaceholder')" class="input-width" clearable maxlength="20" show-word-limit /> <el-input v-model.trim="formData.phone" :placeholder="t('phonePlaceholder')" class="input-width" clearable maxlength="20" show-word-limit />
</el-form-item> </el-form-item>
<el-form-item :label="t('logo')"> <el-form-item :label="t('logo')">
<upload-image v-model="formData.front_end_logo" /> <upload-image v-model="formData.front_end_logo" />
@ -48,7 +48,7 @@
<h3 class="panel-title !text-sm">{{ t('serviceInformation') }}</h3> <h3 class="panel-title !text-sm">{{ t('serviceInformation') }}</h3>
<el-form-item :label="t('contactsTel')"> <el-form-item :label="t('contactsTel')">
<el-input v-model="formData.tel" :placeholder="t('contactsTelPlaceholder')" class="input-width" clearable maxlength="20" show-word-limit /> <el-input v-model.trim="formData.tel" :placeholder="t('contactsTelPlaceholder')" class="input-width" clearable maxlength="20" show-word-limit />
</el-form-item> </el-form-item>
<el-form-item :label="t('wechatCode')"> <el-form-item :label="t('wechatCode')">
<upload-image v-model="formData.wechat_code" /> <upload-image v-model="formData.wechat_code" />

View File

@ -17,11 +17,11 @@
<h3 class="panel-title !text-sm">{{t('wechatpay')}}</h3> <h3 class="panel-title !text-sm">{{t('wechatpay')}}</h3>
<el-form-item :label="t('mchId')" prop="wechatpay_config.mch_id"> <el-form-item :label="t('mchId')" prop="wechatpay_config.mch_id">
<el-input v-model="formData.wechatpay_config.mch_id" :placeholder="t('mchIdPlaceholder')" class="input-width" maxlength="32" show-word-limit clearable /> <el-input v-model.trim="formData.wechatpay_config.mch_id" :placeholder="t('mchIdPlaceholder')" class="input-width" maxlength="32" show-word-limit clearable />
<div class="form-tip">{{ t('mchIdTips') }}</div> <div class="form-tip">{{ t('mchIdTips') }}</div>
</el-form-item> </el-form-item>
<el-form-item :label="t('mchSecretKey')" prop="wechatpay_config.mch_secret_key"> <el-form-item :label="t('mchSecretKey')" prop="wechatpay_config.mch_secret_key">
<el-input v-model="formData.wechatpay_config.mch_secret_key" :placeholder="t('mchSecretKeyPlaceholder')" class="input-width" maxlength="32" show-word-limit clearable /> <el-input v-model.trim="formData.wechatpay_config.mch_secret_key" :placeholder="t('mchSecretKeyPlaceholder')" class="input-width" maxlength="32" show-word-limit clearable />
<div class="form-tip">{{ t('mchSecretKeyTips') }}</div> <div class="form-tip">{{ t('mchSecretKeyTips') }}</div>
</el-form-item> </el-form-item>
<el-form-item :label="t('mchSecretCert')" prop="wechatpay_config.mch_secret_cert"> <el-form-item :label="t('mchSecretCert')" prop="wechatpay_config.mch_secret_cert">
@ -42,11 +42,11 @@
<h3 class="panel-title !text-sm">{{t('alipay')}}</h3> <h3 class="panel-title !text-sm">{{t('alipay')}}</h3>
<el-form-item :label="t('appId')" prop="alipay_config.app_id"> <el-form-item :label="t('appId')" prop="alipay_config.app_id">
<el-input v-model="formData.alipay_config.app_id" :placeholder="t('appIdPlaceholder')" class="input-width" maxlength="32" show-word-limit clearable /> <el-input v-model.trim="formData.alipay_config.app_id" :placeholder="t('appIdPlaceholder')" class="input-width" maxlength="32" show-word-limit clearable />
<div class="form-tip">{{ t('appIdTips') }}</div> <div class="form-tip">{{ t('appIdTips') }}</div>
</el-form-item> </el-form-item>
<el-form-item :label="t('appSecretCert')" prop="alipay_config.app_secret_cert"> <el-form-item :label="t('appSecretCert')" prop="alipay_config.app_secret_cert">
<el-input v-model="formData.alipay_config.app_secret_cert" :placeholder="t('appSecretCertPlaceholder')" class="input-width" type="textarea" rows="4" clearable /> <el-input v-model.trim="formData.alipay_config.app_secret_cert" :placeholder="t('appSecretCertPlaceholder')" class="input-width" type="textarea" rows="4" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="t('appPublicCertPath')" prop="alipay_config.app_public_cert_path"> <el-form-item :label="t('appPublicCertPath')" prop="alipay_config.app_public_cert_path">
<div class="input-width"> <div class="input-width">

View File

@ -36,13 +36,13 @@
<el-dialog v-model="showDialog" :title="t('editVersion')" width="550px" :destroy-on-close="true"> <el-dialog v-model="showDialog" :title="t('editVersion')" width="550px" :destroy-on-close="true">
<el-form :model="formData" label-width="110px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading"> <el-form :model="formData" label-width="110px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
<el-form-item :label="t('version')" prop="version"> <el-form-item :label="t('version')" prop="version">
<el-input v-model="formData.version" :placeholder="t('versionPlaceholder')" class="input-width" /> <el-input v-model.trim="formData.version" :placeholder="t('versionPlaceholder')" class="input-width" />
</el-form-item> </el-form-item>
<el-form-item :label="t('file')" prop="path"> <el-form-item :label="t('file')" prop="path">
<upload-file v-model="formData.path" class="input-width" api="applet/upload" /> <upload-file v-model="formData.path" class="input-width" api="applet/upload" />
</el-form-item> </el-form-item>
<el-form-item :label="t('desc')"> <el-form-item :label="t('desc')">
<el-input type="textarea" v-model="formData.desc" class="input-width" clearable></el-input> <el-input type="textarea" v-model.trim="formData.desc" class="input-width" clearable></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>

View File

@ -18,7 +18,7 @@
</el-form-item> </el-form-item>
<el-form-item :label="t('key')" prop="key"> <el-form-item :label="t('key')" prop="key">
<div> <div>
<el-input v-model="form.key" clearable :disabled="route.query.key" :placeholder="t('keyPlaceholder')" class="input-width mr-[15px]" /> <el-input v-model.trim="form.key" clearable :disabled="route.query.key" :placeholder="t('keyPlaceholder')" class="input-width mr-[15px]" />
<el-button v-if="!route.query.key" type="primary" :disabled="form.key == ''" @click="getAddonDevelopCheckFn(form.key)">官方市场标识检测</el-button> <el-button v-if="!route.query.key" type="primary" :disabled="form.key == ''" @click="getAddonDevelopCheckFn(form.key)">官方市场标识检测</el-button>
<p class="text-[12px] text-[#a9a9a9] leading-normal mt-[5px]">{{ t('keyPlaceholder1') }}</p> <p class="text-[12px] text-[#a9a9a9] leading-normal mt-[5px]">{{ t('keyPlaceholder1') }}</p>
<p class="text-[12px] text-[#a9a9a9] leading-normal">{{ t('keyPlaceholder2') }}</p> <p class="text-[12px] text-[#a9a9a9] leading-normal">{{ t('keyPlaceholder2') }}</p>
@ -28,14 +28,14 @@
</div> </div>
</el-form-item> </el-form-item>
<el-form-item :label="t('desc')" prop="desc"> <el-form-item :label="t('desc')" prop="desc">
<el-input type="textarea" v-model="form.desc" clearable :placeholder="t('descPlaceholder')" class="input-width" /> <el-input type="textarea" v-model.trim="form.desc" clearable :placeholder="t('descPlaceholder')" class="input-width" />
</el-form-item> </el-form-item>
<el-form-item :label="t('author')" prop="author"> <el-form-item :label="t('author')" prop="author">
<el-input v-model.trim="form.author" clearable :placeholder="t('authorPlaceholder')" class="input-width" /> <el-input v-model.trim="form.author" clearable :placeholder="t('authorPlaceholder')" class="input-width" />
</el-form-item> </el-form-item>
<el-form-item :label="t('version')" prop="version"> <el-form-item :label="t('version')" prop="version">
<div> <div>
<el-input v-model="form.version" clearable :placeholder="t('versionPlaceholder')" class="input-width" onkeyup="this.value = this.value.replace(/[^\d\.]/g,'');" /> <el-input v-model.trim="form.version" clearable :placeholder="t('versionPlaceholder')" class="input-width" onkeyup="this.value = this.value.replace(/[^\d\.]/g,'');" />
<p class="text-[12px] text-[#a9a9a9] leading-normal mt-[5px]">{{ t('versionPlaceholder1') }}</p> <p class="text-[12px] text-[#a9a9a9] leading-normal mt-[5px]">{{ t('versionPlaceholder1') }}</p>
</div> </div>
</el-form-item> </el-form-item>
@ -70,7 +70,7 @@
</el-form-item> </el-form-item>
</template> </template>
<!-- <el-form-item v-if="form.type != 'app'" :label="t('supportApp')" prop="support_app"> <!-- <el-form-item v-if="form.type != 'app'" :label="t('supportApp')" prop="support_app">
<el-input v-model="form.support_app" clearable :placeholder="t('supportAppPlaceholder')" <el-input v-model.trim="form.support_app" clearable :placeholder="t('supportAppPlaceholder')"
class="input-width" /> class="input-width" />
</el-form-item> --> </el-form-item> -->
</el-form> </el-form>

View File

@ -88,7 +88,7 @@
<div class="flex justify-between"> <div class="flex justify-between">
<el-form :inline="true" :model="params" ref="searchFormRef"> <el-form :inline="true" :model="params" ref="searchFormRef">
<el-form-item :label="t('title')" prop="search"> <el-form-item :label="t('title')" prop="search">
<el-input v-model="params.search" :placeholder="t('titlePlaceholder')" /> <el-input v-model.trim="params.search" :placeholder="t('titlePlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="getAddonDevelopFn">{{ t('search') }}</el-button> <el-button type="primary" @click="getAddonDevelopFn">{{ t('search') }}</el-button>

View File

@ -12,7 +12,7 @@
<el-table-column align="right" min-width="150"> <el-table-column align="right" min-width="150">
<template #header> <template #header>
<el-input v-model="search" size="small" :placeholder="t('searchPlaceholder')" /> <el-input v-model.trim="search" size="small" :placeholder="t('searchPlaceholder')" />
</template> </template>
<template #default="scope"> <template #default="scope">
<el-button size="small" type="primary" @click="confirm(scope.row)">{{ t('addBtn') }}</el-button> <el-button size="small" type="primary" @click="confirm(scope.row)">{{ t('addBtn') }}</el-button>

View File

@ -205,19 +205,19 @@
:render-after-expand="false" /> :render-after-expand="false" />
</el-form-item> </el-form-item>
<!-- <el-form-item :label="t('controller')"> <!-- <el-form-item :label="t('controller')">
<el-input v-model="controller" disabled class="input-width" /> <el-input v-model.trim="controller" disabled class="input-width" />
</el-form-item> </el-form-item>
<el-form-item :label="t('dataModel')"> <el-form-item :label="t('dataModel')">
<el-input v-model="dataModel" disabled class="input-width" /> <el-input v-model.trim="dataModel" disabled class="input-width" />
</el-form-item> </el-form-item>
<el-form-item :label="t('validator')"> <el-form-item :label="t('validator')">
<el-input v-model="validator" disabled class="input-width" /> <el-input v-model.trim="validator" disabled class="input-width" />
</el-form-item> </el-form-item>
<el-form-item :label="t('webView')"> <el-form-item :label="t('webView')">
<el-input v-model="webView" disabled class="input-width" /> <el-input v-model.trim="webView" disabled class="input-width" />
</el-form-item> </el-form-item>
<el-form-item :label="t('routerView')"> <el-form-item :label="t('routerView')">
<el-input v-model="routerView" disabled class="input-width" /> <el-input v-model.trim="routerView" disabled class="input-width" />
</el-form-item> --> </el-form-item> -->
</el-form> </el-form>
</el-tab-pane> </el-tab-pane>
@ -327,6 +327,14 @@ const viewType = [
label: t('formImageSelect'), label: t('formImageSelect'),
value: 'imageSelect' value: 'imageSelect'
}, },
{
label: t('formFileSelect'),
value: 'fileSelect'
},
{
label: t('formVideoSelect'),
value: 'videoSelect'
},
{ {
label: t('formEditor'), label: t('formEditor'),
value: 'editor' value: 'editor'

View File

@ -85,7 +85,7 @@
</el-form-item> </el-form-item>
<el-form-item :label="t('tableName')" prop="table_name"> <el-form-item :label="t('tableName')" prop="table_name">
<el-input v-model="codeTableData.searchParam.table_name" :placeholder="t('tableNamePlaceholder')" /> <el-input v-model.trim="codeTableData.searchParam.table_name" :placeholder="t('tableNamePlaceholder')" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="loadGenerateTableList()">{{ t('search') }}</el-button> <el-button type="primary" @click="loadGenerateTableList()">{{ t('search') }}</el-button>

View File

@ -22,6 +22,30 @@
</template> </template>
</el-alert> </el-alert>
<el-card class="box-card !border-none mb-[10px] table-search-wrap" shadow="never">
<div class="flex justify-between">
<el-form :inline="true" :model="cronTableData.searchParam" ref="searchFormRef">
<el-form-item :label="t('title')" prop="key">
<el-select v-model="cronTableData.searchParam.key" placeholder="全部" filterable remote clearable :remote-method="getAddonDevelopFn">
<el-option label="全部" value="all" />
<el-option v-for="item in templateList" :key="item.key" :label="item.name" :value="item.key" />
</el-select>
</el-form-item>
<el-form-item :label="t('status')" prop="status">
<el-select v-model="cronTableData.searchParam.status" placeholder="全部" filterable remote clearable :remote-method="getAddonDevelopFn">
<el-option label="全部" value="all" />
<el-option label="启用" value="1" />
<el-option label="关闭" value="0" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadCronList()">{{ t('search') }}</el-button>
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
</el-form-item>
</el-form>
</div>
</el-card>
<div class="mt-[20px]"> <div class="mt-[20px]">
<el-table :data="cronTableData.data" size="large" v-loading="cronTableData.loading"> <el-table :data="cronTableData.data" size="large" v-loading="cronTableData.loading">
<template #empty> <template #empty>
@ -36,10 +60,23 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="status_name" :label="t('openStatus')" min-width="100" /> <el-table-column prop="status_name" :label="t('openStatus')" min-width="100" />
<el-table-column :label="t('operation')" align="right" fixed="right" width="130"> <el-table-column :label="t('operation')" align="right" fixed="right" width="180">
<template #default="{ row }"> <template #default="{ row }">
<div class="flex items-center">
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button> <el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button> <el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button>
<el-dropdown class="ml-[12px]">
<span class="el-dropdown-link text-primary">
{{ t('more') }}
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="doEvent(row)">{{ t('doOne') }}</el-dropdown-item>
<el-dropdown-item @click="toLogList(row.id)">{{ t('cronLog') }}</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -68,13 +105,13 @@
<el-select v-model="formData.time.week" class="ml-2 w-[120px]" v-if="formData.time.type == 'week'"> <el-select v-model="formData.time.week" class="ml-2 w-[120px]" v-if="formData.time.type == 'week'">
<el-option v-for="(item, index) in week_list" :key="index" :label="item" :value="index" /> <el-option v-for="(item, index) in week_list" :key="index" :label="item" :value="index" />
</el-select> </el-select>
<el-input v-model="formData.time.day" class="ml-2 w-[120px]" v-if="['month', 'day'].indexOf(formData.time.type) != -1"> <el-input v-model.trim="formData.time.day" class="ml-2 w-[120px]" v-if="['month', 'day'].indexOf(formData.time.type) != -1">
<template #append>{{ t('day') }}</template> <template #append>{{ t('day') }}</template>
</el-input> </el-input>
<el-input v-model="formData.time.hour" class="ml-2 w-[120px]" v-if="['month', 'day', 'hour', 'week'].indexOf(formData.time.type) != -1"> <el-input v-model.trim="formData.time.hour" class="ml-2 w-[120px]" v-if="['month', 'day', 'hour', 'week'].indexOf(formData.time.type) != -1">
<template #append>{{ t('hour') }}</template> <template #append>{{ t('hour') }}</template>
</el-input> </el-input>
<el-input v-model="formData.time.min" class="ml-2 w-[120px]" v-if="['month', 'day', 'hour', 'week', 'min'].indexOf(formData.time.type) != -1"> <el-input v-model.trim="formData.time.min" class="ml-2 w-[120px]" v-if="['month', 'day', 'hour', 'week', 'min'].indexOf(formData.time.type) != -1">
<template #append>{{ t('min') }}</template> <template #append>{{ t('min') }}</template>
</el-input> </el-input>
</div> </div>
@ -108,7 +145,8 @@ import {
getWeek, getWeek,
addCron, addCron,
editCron, editCron,
deleteCron deleteCron,
doCron
} from '@/app/api/sys' } from '@/app/api/sys'
import { ElMessageBox, FormInstance } from 'element-plus' import { ElMessageBox, FormInstance } from 'element-plus'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
@ -124,9 +162,8 @@ const cronTableData = reactive({
loading: true, loading: true,
data: [], data: [],
searchParam: { searchParam: {
title: '',
type: '', type: '',
last_time: '' status: 'all'
} }
}) })
const templateList = ref([]) const templateList = ref([])
@ -134,6 +171,12 @@ const date_type = ref([])
const week_list = ref([]) const week_list = ref([])
const searchFormRef = ref<FormInstance>() const searchFormRef = ref<FormInstance>()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadCronList()
}
const setTypeList = async () => { const setTypeList = async () => {
templateList.value = await (await getCronTemplate()).data templateList.value = await (await getCronTemplate()).data
date_type.value = await (await getCronDateType()).data date_type.value = await (await getCronDateType()).data
@ -264,6 +307,20 @@ const deleteEvent = (id: number) => {
}) })
} }
const doEvent = (row: any) => {
ElMessageBox.confirm(t(`确认要立即执行一次"${row.name}"任务吗?`), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning'
}
).then(() => {
doCron({id: row.id}).then((res) => {
}).catch(() => {
})
})
}
const cronDialog: Record<string, any> | null = ref(null) const cronDialog: Record<string, any> | null = ref(null)
/** /**
* 查看任务 * 查看任务
@ -274,6 +331,10 @@ const infoEvent = (data: any) => {
cronDialog.value.showDialog = true cronDialog.value.showDialog = true
} }
const toLogList = (id: number) => {
router.push({ path: '/tools/schedule_log', query: { id: id } })
}
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>

View File

@ -0,0 +1,204 @@
<template>
<div class="main-container">
<el-card class="card !border-none" shadow="never">
<el-page-header :icon="ArrowLeft" @back="$router.back()">
<template #content>
<span class="text-large font-600 mr-3">{{ pageName }}</span>
</template>
</el-page-header>
</el-card>
<el-card class="box-card !border-none" shadow="never">
<el-card class="box-card !border-none mb-[10px] table-search-wrap" shadow="never">
<div class="flex justify-between">
<el-form :inline="true" :model="cronTableData.searchParam" ref="searchFormRef">
<el-form-item :label="t('name')" prop="key">
<el-select v-model="cronTableData.searchParam.key" placeholder="全部" filterable remote clearable>
<el-option label="全部" value="all" />
<el-option v-for="item in templateList" :key="item.key" :label="item.name" :value="item.key" />
</el-select>
</el-form-item>
<el-form-item :label="t('status')" prop="status">
<el-select v-model="cronTableData.searchParam.status" placeholder="全部" filterable remote clearable>
<el-option label="全部" value="all" />
<el-option label="成功" value="success" />
<el-option label="失败" value="error" />
</el-select>
</el-form-item>
<el-form-item :label="t('executeTime')" prop="execute_time">
<el-date-picker v-model="cronTableData.searchParam.execute_time" type="datetimerange" value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="t('startDate')" :end-placeholder="t('endDate')" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadCronLogList()">{{ t('search') }}</el-button>
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
</el-form-item>
</el-form>
</div>
</el-card>
<div class="mt-[20px]">
<el-table :data="cronTableData.data" size="large" v-loading="cronTableData.loading">
<template #empty>
<span>{{ !cronTableData.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column prop="id" :label="t('id')" min-width="80" />
<el-table-column prop="name" :label="t('name')" min-width="150" />
<el-table-column prop="key" :label="t('key')" min-width="150" />
<el-table-column prop="class" :label="t('class')" min-width="150" />
<el-table-column :label="t('executeResult')" min-width="150">
<template #default="{ row }">
{{ row.execute_result }}
</template>
</el-table-column>
<el-table-column prop="status_name" :label="t('status')" min-width="100" />
<el-table-column prop="execute_time" :label="t('executeTime')" min-width="100" />
<el-table-column :label="t('operation')" align="right" fixed="right" width="130">
<template #default="{ row }">
<el-button type="primary" link @click="infoEvent(row)">{{ t('info') }}</el-button>
</template>
</el-table-column>
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination v-model:current-page="cronTableData.page" v-model:page-size="cronTableData.limit"
layout="total, sizes, prev, pager, next, jumper" :total="cronTableData.total"
@size-change="loadCronLogList()" @current-change="loadCronLogList" />
</div>
</div>
</el-card>
<el-dialog v-model="showDialog" :title="t('cronInfo')" width="550px" :destroy-on-close="true">
<el-form :model="formData" label-width="110px" ref="formRef" class="page-form" v-loading="loading">
<el-form-item :label="t('name')" >
<div class="input-width"> {{ formData.name }} </div>
</el-form-item>
<el-form-item :label="t('key')" >
<div class="input-width"> {{ formData.key }} </div>
</el-form-item>
<el-form-item :label="t('class')" >
<div class="input-width"> {{ formData.class }} </div>
</el-form-item>
<el-form-item :label="t('executeResult')" >
<div class="input-width"> {{ formData.execute_result }} </div>
</el-form-item>
<el-form-item :label="t('status')" >
<div class="input-width"> {{ formData.status_name }} </div>
</el-form-item>
<el-form-item :label="t('executeTime')" >
<div class="input-width"> {{ formData.execute_time }} </div>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="showDialog = false">{{ t('confirm') }}</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, computed } from 'vue'
import { t } from '@/lang'
import { getCronLogList, getCronTemplate } from '@/app/api/sys'
import { ElMessageBox, FormInstance } from 'element-plus'
import { useRouter, useRoute } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title
const cronTableData = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
schedule_id: route.query.id,
key: '',
status: 'all',
execute_time: []
}
})
const templateList = ref([])
const searchFormRef = ref<FormInstance>()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadCronLogList()
}
const setTypeList = async () => {
templateList.value = await (await getCronTemplate()).data
}
setTypeList()
/**
* 获取日志列表
*/
const loadCronLogList = (page: number = 1) => {
cronTableData.loading = true
cronTableData.page = page
getCronLogList({
page: cronTableData.page,
limit: cronTableData.limit,
...cronTableData.searchParam
}).then(res => {
cronTableData.loading = false
cronTableData.data = res.data.data
cronTableData.total = res.data.total
}).catch(() => {
cronTableData.loading = false
})
}
loadCronLogList()
const showDialog = ref(false)
const loading = ref(true)
/**
* 表单数据
*/
const initialFormData = {
id: '',
name: '',
key: '',
execute_result: '',
status_name: '',
class: '',
job: '',
execute_time: ''
}
const formData: Record<string, any> = reactive({ ...initialFormData })
/**
* 查看日志详情
* @param row
*/
const infoEvent = (row: any) => {
loading.value = true
Object.assign(formData, initialFormData)
if (row) {
Object.keys(formData).forEach((key: string) => {
if (row[key] != undefined) formData[key] = row[key]
})
}
loading.value = false
showDialog.value = true
}
</script>
<style lang="scss" scoped></style>

View File

@ -168,7 +168,6 @@ const getLinkFn = (callback:any=null)=> {
} }
} }
} }
console.log('link',link.value)
childList.value = Object.values(link.value)[0].child_list childList.value = Object.values(link.value)[0].child_list
if (value.value.name != '') { if (value.value.name != '') {

Some files were not shown because too many files have changed in this diff Show More