mirror of
https://gitee.com/niucloud-team/niucloud.git
synced 2026-09-18 18:06:37 +00:00
up
This commit is contained in:
parent
0e6dac960d
commit
e927a7cf8c
@ -35,11 +35,6 @@ onMounted(() => {
|
|||||||
// 设置主题色
|
// 设置主题色
|
||||||
toggleDark(systemStore.dark)
|
toggleDark(systemStore.dark)
|
||||||
setThemeColor(systemStore.theme, systemStore.dark ? 'dark' : 'light')
|
setThemeColor(systemStore.theme, systemStore.dark ? 'dark' : 'light')
|
||||||
|
|
||||||
// importIconFontCss();
|
|
||||||
|
|
||||||
// getIcon()
|
|
||||||
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -91,6 +91,10 @@ export function getInstalledAddonList() {
|
|||||||
return request.get('addon/list/install')
|
return request.get('addon/list/install')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getGroupAppList() {
|
||||||
|
return request.get('home/site/group/app_list')
|
||||||
|
}
|
||||||
|
|
||||||
export function getAddonInit() {
|
export function getAddonInit() {
|
||||||
return request.get('addon/init')
|
return request.get('addon/init')
|
||||||
}
|
}
|
||||||
|
|||||||
@ -125,6 +125,14 @@ export function editMemberDetail(params: Record<string, any>) {
|
|||||||
return request.put(`member/member/modify/${params.member_id}/${params.field}`, params, { showSuccessMessage: true })
|
return request.put(`member/member/modify/${params.member_id}/${params.field}`, params, { showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员批量操作
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export function memberBatchModify(params: Record<string, any>) {
|
||||||
|
return request.post(`member/member/batch_modify`, params, { showSuccessMessage: true })
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************** 会员零钱 ****************************************************/
|
/***************************************************** 会员零钱 ****************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -286,4 +286,12 @@ export function templateSync(sms_type: string, username: string) {
|
|||||||
*/
|
*/
|
||||||
export function resetPassword(username: string,params: Record<string, any>) {
|
export function resetPassword(username: string,params: Record<string, any>) {
|
||||||
return request.post(`notice/niusms/account/reset/password/${username}`,params,{ showSuccessMessage: true})
|
return request.post(`notice/niusms/account/reset/password/${username}`,params,{ showSuccessMessage: true})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除模版报备
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export function clearTemplate(username: string,template_id: string) {
|
||||||
|
return request.delete(`notice/niusms/template/${username}/${template_id}`)
|
||||||
|
}
|
||||||
|
|||||||
@ -54,6 +54,15 @@ export function closeSite(params: Record<string, any>) {
|
|||||||
return request.put(`site/closesite/${ params.site_id }`, params, { showSuccessMessage: true })
|
return request.put(`site/closesite/${ params.site_id }`, params, { showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化站点
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export function initSite(params: Record<string, any>) {
|
||||||
|
return request.post(`site/init`, params, { showSuccessMessage: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打开站点
|
* 打开站点
|
||||||
* @param params
|
* @param params
|
||||||
@ -214,7 +223,6 @@ export function getLogInfo(id: number) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 清空操作日志列表
|
* 清空操作日志列表
|
||||||
* @param params
|
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function logDestroy() {
|
export function logDestroy() {
|
||||||
@ -271,3 +279,11 @@ export function getSiteAddons() {
|
|||||||
export function getShowApp() {
|
export function getShowApp() {
|
||||||
return request.get('site/showApp')
|
return request.get('site/showApp')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取营销列表
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getShowMarketing() {
|
||||||
|
return request.get('site/showMarketing')
|
||||||
|
}
|
||||||
|
|||||||
@ -61,6 +61,14 @@ export function deleteRole(roleId: number) {
|
|||||||
return request.delete(`sys/role/${ roleId }`, { showSuccessMessage: true })
|
return request.delete(`sys/role/${ roleId }`, { showSuccessMessage: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改角色状态
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export function modifyRoleStatus(params: Record<string, any>) {
|
||||||
|
return request.put(`sys/role/status`, params, { showSuccessMessage: true })
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全部分组
|
* 全部分组
|
||||||
* @returns
|
* @returns
|
||||||
@ -277,24 +285,6 @@ export function getAuthMenu() {
|
|||||||
return request.get(`auth/site/showmenu`)
|
return request.get(`auth/site/showmenu`)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取图标库分类列表
|
|
||||||
* @param params
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function getIconCategoryList(params: Record<string, any>) {
|
|
||||||
return request.get(`sys/attachment/icon_category`, { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取图标库列表
|
|
||||||
* @param params
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function getIconList(params: Record<string, any>) {
|
|
||||||
return request.get(`sys/attachment/icon`, { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取evn
|
* 获取evn
|
||||||
* @returns
|
* @returns
|
||||||
|
|||||||
@ -65,28 +65,32 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- </el-scrollbar> -->
|
<!-- </el-scrollbar> -->
|
||||||
</div>
|
</div>
|
||||||
<div class="h-[45vh]" v-show="cloudBuildTask && !errorLog">
|
<div class="h-[45vh]" v-show="cloudBuildTask">
|
||||||
<terminal ref="terminalRef" context="" :init-log="null" :show-header="false" :show-log-time="true" @exec-cmd="onExecCmd"/>
|
<terminal ref="terminalRef" context="" :init-log="null" :show-header="false" :show-log-time="true" @exec-cmd="onExecCmd"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-end mt-[20px]" v-show="cloudBuildTask && !errorLog">
|
<div class="flex justify-end mt-[20px]" v-show="cloudBuildTask">
|
||||||
<el-button @click="dialogCancel()" class="!w-[90px]">取消</el-button>
|
<el-button @click="dialogCancel()" class="!w-[90px]">取消</el-button>
|
||||||
<el-button type="primary" :loading="timeloading" class="!w-[140px]">已用时 {{ formattedDuration }}</el-button>
|
<el-button type="primary" :loading="timeloading" class="!w-[140px]">已用时 {{ formattedDuration }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="h-[50vh] flex flex-col" v-show="errorLog">
|
</div>
|
||||||
<div class="flex-1 h-0">
|
<div v-show="active == 'error'">
|
||||||
<el-result icon="error" :title="t('编译失败')" :sub-title="errorInfo">
|
<div class="h-[50vh] flex flex-col">
|
||||||
|
<div class="flex-1 h-0 flex justify-center items-center flex-col">
|
||||||
|
<el-result icon="error" :title="t('编译失败')">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<img src="@/app/assets/images/error_icon.png" alt="">
|
<img src="@/app/assets/images/error_icon.png" alt="">
|
||||||
</template>
|
</template>
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<el-button @click="errorLog=false" class="!w-[90px]">错误信息</el-button>
|
<el-scrollbar class="max-h-[150px] overflow-auto text-[15px] text-[#4F516D] mb-[15px] mt-[-15px]">
|
||||||
|
{{errorInfo}}
|
||||||
|
</el-scrollbar>
|
||||||
|
<el-button @click="handleReturn" class="!w-[90px]">错误信息</el-button>
|
||||||
<el-button @click="showDialog=false" type="primary" class="!w-[90px]">完成</el-button>
|
<el-button @click="showDialog=false" type="primary" class="!w-[90px]">完成</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-result>
|
</el-result>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-show="active == 'complete'">
|
<div v-show="active == 'complete'">
|
||||||
<div class="h-[50vh] flex flex-col">
|
<div class="h-[50vh] flex flex-col">
|
||||||
<div class="flex-1 h-0 flex justify-center items-center flex-col">
|
<div class="flex-1 h-0 flex justify-center items-center flex-col">
|
||||||
@ -150,7 +154,6 @@ const getCloudBuildTaskFn = () => {
|
|||||||
}).catch()
|
}).catch()
|
||||||
}
|
}
|
||||||
getCloudBuildTaskFn()
|
getCloudBuildTaskFn()
|
||||||
const errorLog = ref(false)
|
|
||||||
const errorInfo = ref('')
|
const errorInfo = ref('')
|
||||||
const timeloading = ref(false)
|
const timeloading = ref(false)
|
||||||
const getCloudBuildLogFn = () => {
|
const getCloudBuildLogFn = () => {
|
||||||
@ -205,7 +208,9 @@ const getCloudBuildLogFn = () => {
|
|||||||
error = item.msg
|
error = item.msg
|
||||||
terminalRef.value.pushMessage({ content: item.msg, class: 'error' })
|
terminalRef.value.pushMessage({ content: item.msg, class: 'error' })
|
||||||
timeloading.value = false
|
timeloading.value = false
|
||||||
errorLog.value = true
|
active.value = 'error'
|
||||||
|
terminalRef.value.execute('clear')
|
||||||
|
clearCloudBuildTask()
|
||||||
errorInfo.value = item.msg
|
errorInfo.value = item.msg
|
||||||
// 停止计时器
|
// 停止计时器
|
||||||
if (buildTimer) {
|
if (buildTimer) {
|
||||||
@ -235,7 +240,6 @@ const getCloudBuildLogFn = () => {
|
|||||||
const closeType = ref('normal')
|
const closeType = ref('normal')
|
||||||
const handleReturn = () => {
|
const handleReturn = () => {
|
||||||
active.value = 'build'
|
active.value = 'build'
|
||||||
errorLog.value = false
|
|
||||||
closeType.value = 'success'
|
closeType.value = 'success'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,6 +432,6 @@ defineExpose({
|
|||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
}
|
}
|
||||||
:deep(.el-result){
|
:deep(.el-result){
|
||||||
margin-top: -100px !important;
|
margin-top: -80px !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"ip":"登录IP",
|
"ip":"登录IP",
|
||||||
"username":"管理员姓名",
|
"username":"管理员姓名",
|
||||||
|
"operation": "操作日志",
|
||||||
"url":"链接",
|
"url":"链接",
|
||||||
"detail": "详情",
|
"detail": "详情",
|
||||||
"params":"参数",
|
"params":"参数",
|
||||||
|
|||||||
@ -14,6 +14,14 @@
|
|||||||
"statusBarStyle": "导航栏样式",
|
"statusBarStyle": "导航栏样式",
|
||||||
"statusBarSwitchTips": "此处控制当前页面导航栏是否显示",
|
"statusBarSwitchTips": "此处控制当前页面导航栏是否显示",
|
||||||
"bottomNavContent": "底部导航内容",
|
"bottomNavContent": "底部导航内容",
|
||||||
|
"popWindowAds": "弹窗广告",
|
||||||
|
"popAdsLink": "广告链接",
|
||||||
|
"popAdsImage": "广告图",
|
||||||
|
"popAdsType": "显示类型",
|
||||||
|
"popAdsIsEnabled": "是否显示",
|
||||||
|
"firstPop": "首次弹出",
|
||||||
|
"popWindowCountTips": "建议上传图片大小:290px * 410px",
|
||||||
|
"everyTimePops": "每次弹出",
|
||||||
"diyPageTitle": "页面名称",
|
"diyPageTitle": "页面名称",
|
||||||
"diyPageTitlePlaceholder": "请输入页面名称",
|
"diyPageTitlePlaceholder": "请输入页面名称",
|
||||||
"pageTitleTips": "页面名称用于后台显示",
|
"pageTitleTips": "页面名称用于后台显示",
|
||||||
|
|||||||
@ -362,7 +362,7 @@
|
|||||||
"imageLimitErrorTips":"限制数量格式输入错误",
|
"imageLimitErrorTips":"限制数量格式输入错误",
|
||||||
"imageLimitErrorTipsTwo":"限制数量不能小于0",
|
"imageLimitErrorTipsTwo":"限制数量不能小于0",
|
||||||
"imageLimitErrorTipsThree":"限制数量必须大于0",
|
"imageLimitErrorTipsThree":"限制数量必须大于0",
|
||||||
"imafeLimitErrorTipsFour":"限制数量最大不能超过9",
|
"imageLimitErrorTipsFour":"限制数量最大不能超过9",
|
||||||
|
|
||||||
"defaultValueTips":"设置后,默认值会自动填充到输入框,填表人可在此基础上进行修改。",
|
"defaultValueTips":"设置后,默认值会自动填充到输入框,填表人可在此基础上进行修改。",
|
||||||
"defaultErrorTips":"默认值格式输入错误",
|
"defaultErrorTips":"默认值格式输入错误",
|
||||||
|
|||||||
@ -23,6 +23,7 @@
|
|||||||
"verifier": "核销员",
|
"verifier": "核销员",
|
||||||
"createTime": "添加时间",
|
"createTime": "添加时间",
|
||||||
"addVerifier": "添加核销员",
|
"addVerifier": "添加核销员",
|
||||||
|
"editVerifier":"编辑核销员",
|
||||||
"verifierDeleteTips": "确定要删除该核销员吗?",
|
"verifierDeleteTips": "确定要删除该核销员吗?",
|
||||||
"memberInfo": "会员信息",
|
"memberInfo": "会员信息",
|
||||||
"memberIdPlaceholder": "请选择会员",
|
"memberIdPlaceholder": "请选择会员",
|
||||||
|
|||||||
@ -1,82 +1,86 @@
|
|||||||
{
|
{
|
||||||
"registerChannel":"注册来源",
|
"registerChannel": "注册来源",
|
||||||
"nickname":"会员昵称",
|
"nickname": "会员昵称",
|
||||||
"memberNo":"会员编号",
|
"memberNo": "会员编号",
|
||||||
"mobile":"手机号",
|
"mobile": "手机号",
|
||||||
"createTime":"注册时间",
|
"createTime": "注册时间",
|
||||||
"lastVisitTime":"最后访问时间",
|
"lastVisitTime": "最后访问时间",
|
||||||
"addMember":"添加会员",
|
"addMember": "添加会员",
|
||||||
"nickNamePlaceholder":"请输入会员昵称",
|
"nickNamePlaceholder": "请输入会员昵称",
|
||||||
"mobilePlaceholder":"请输入手机号",
|
"mobilePlaceholder": "请输入手机号",
|
||||||
"channelPlaceholder":"请选择注册类型",
|
"channelPlaceholder": "请选择注册类型",
|
||||||
"memberNoPlaceholder":"请选择会员编号",
|
"memberNoPlaceholder": "请选择会员编号",
|
||||||
"memberDeleteTips" : "确定要删除该会员吗?",
|
"memberDeleteTips": "确定要删除该会员吗?",
|
||||||
"edit": "编辑",
|
"edit": "编辑",
|
||||||
"memberDelete":"删除",
|
"memberDelete": "删除",
|
||||||
"adjust":"调整",
|
"adjust": "调整",
|
||||||
"startDate": "开始时间",
|
"startDate": "开始时间",
|
||||||
"endDate": "结束时间",
|
"endDate": "结束时间",
|
||||||
"essentialInfo": "基本信息",
|
"essentialInfo": "基本信息",
|
||||||
"accountInfo": "账户信息",
|
"accountInfo": "账户信息",
|
||||||
"registeredSource": "注册来源",
|
"registeredSource": "注册来源",
|
||||||
"memberLabel": "会员标签",
|
"memberLabel": "会员标签",
|
||||||
"urserName": "用户名",
|
"urserName": "用户名",
|
||||||
"point": "积分",
|
"point": "积分",
|
||||||
"balance": "余额",
|
"balance": "余额",
|
||||||
"growth": "成长值",
|
"growth": "成长值",
|
||||||
"memo":"备注",
|
"memo": "备注",
|
||||||
"adjustPoint":"调整积分",
|
"adjustPoint": "调整积分",
|
||||||
"detaBirth": "出生日期",
|
"detaBirth": "出生日期",
|
||||||
"sex": "性别",
|
"sex": "性别",
|
||||||
"wxUnionid": "微信unionid",
|
"wxUnionid": "微信unionid",
|
||||||
"weappOpenid": "微信小程序openid",
|
"weappOpenid": "微信小程序openid",
|
||||||
"wxOpenid": "微信用户openid",
|
"wxOpenid": "微信用户openid",
|
||||||
"head": "会员头像",
|
"head": "会员头像",
|
||||||
"username": "用户名",
|
"username": "用户名",
|
||||||
"usernamePlaceholder": "请输入用户名",
|
"usernamePlaceholder": "请输入用户名",
|
||||||
"password": "密码",
|
"password": "密码",
|
||||||
"passwordCopy": "确认密码",
|
"passwordCopy": "确认密码",
|
||||||
"passwordPlaceholder": "请输入密码",
|
"passwordPlaceholder": "请输入密码",
|
||||||
"doubleCipherHint": "输入的两次密码不一致",
|
"doubleCipherHint": "输入的两次密码不一致",
|
||||||
"memberNoHint":"会员编号只能输入字母和数字",
|
"memberNoHint": "会员编号只能输入字母和数字",
|
||||||
"mobileHint": "请输入正确的手机号!",
|
"mobileHint": "请输入正确的手机号!",
|
||||||
"memberLabelTag": "标签",
|
"memberLabelTag": "标签",
|
||||||
"setLabel": "标签",
|
"setLabel": "标签",
|
||||||
"memberLabelPlaceholder": "请选择会员标签",
|
"memberLabelPlaceholder": "请选择会员标签",
|
||||||
"memberInfo":"会员信息",
|
"memberInfo": "会员信息",
|
||||||
"memberInfoPlaceholder":"请输入会员编号/昵称/手机号",
|
"memberInfoPlaceholder": "请输入会员编号/昵称/手机号",
|
||||||
"lock": "锁定",
|
"lock": "锁定",
|
||||||
"normal": "正常",
|
"normal": "正常",
|
||||||
"memberLevel": "会员等级",
|
"memberLevel": "会员等级",
|
||||||
"memberLevelPlaceholder": "请选择会员等级",
|
"memberLevelPlaceholder": "请选择会员等级",
|
||||||
"adjustType":"调整类型",
|
"adjustType": "调整类型",
|
||||||
"adjustReduceBalance":"减少余额",
|
"adjustReduceBalance": "减少余额",
|
||||||
"adjustAddBalance":"增加余额",
|
"adjustAddBalance": "增加余额",
|
||||||
"adjustReducePoint":"减少积分",
|
"adjustReducePoint": "减少积分",
|
||||||
"adjustAddPoint":"增加积分",
|
"adjustAddPoint": "增加积分",
|
||||||
"adjustBalance":"调整余额",
|
"adjustBalance": "调整余额",
|
||||||
"currBalance":"当前余额",
|
"currBalance": "当前余额",
|
||||||
"currPoint":"当前积分",
|
"currPoint": "当前积分",
|
||||||
"adjustPlaceholder":"请输入调整数量",
|
"adjustPlaceholder": "请输入调整数量",
|
||||||
"memoPlaceholder":"请输入备注",
|
"memoPlaceholder": "请输入备注",
|
||||||
"adjustBalancePlaceholder":"请输入调整余额",
|
"adjustBalancePlaceholder": "请输入调整余额",
|
||||||
"adjustPointPlaceholder":"请输入调整积分",
|
"adjustPointPlaceholder": "请输入调整积分",
|
||||||
"adjustBalanceMaxAccountMessage":"调整后余额需大于0",
|
"adjustBalanceMaxAccountMessage": "调整后余额需大于0",
|
||||||
"adjustPointMaxAccountMessage":"调整后积分需大于0",
|
"adjustPointMaxAccountMessage": "调整后积分需大于0",
|
||||||
"birthday": "出生日期",
|
"birthday": "出生日期",
|
||||||
"birthdayTip": "请输入出生日期",
|
"birthdayTip": "请输入出生日期",
|
||||||
"headimg": "会员头像",
|
"headimg": "会员头像",
|
||||||
"updateMember": "编辑会员信息",
|
"updateMember": "编辑会员信息",
|
||||||
"notAvailable":"暂无",
|
"notAvailable": "暂无",
|
||||||
"girlSex":"女",
|
"girlSex": "女",
|
||||||
"manSex":"男",
|
"manSex": "男",
|
||||||
"secrecySex":"保密",
|
"secrecySex": "保密",
|
||||||
"detail":"详情",
|
"detail": "详情",
|
||||||
"accumulative":"累计",
|
"accumulative": "累计",
|
||||||
"money":"可提现余额",
|
"money": "可提现余额",
|
||||||
"commission":"佣金",
|
"commission": "佣金",
|
||||||
"memberNull":"未读取到会员详情信息",
|
"memberNull": "未读取到会员详情信息",
|
||||||
"memberLevelUpdate": "修改等级至",
|
"memberLevelUpdate": "修改等级至",
|
||||||
"memberLevelUpdateTips": "该操作只会修改会员等级不会发放等级礼包"
|
"memberLevelUpdateTips": "该操作只会修改会员等级不会发放等级礼包",
|
||||||
|
"idCard": "身份证",
|
||||||
|
"idCardPlaceholder": "请输入身份证号",
|
||||||
|
"remark": "备注",
|
||||||
|
"remarkPlaceholder": "请输入备注",
|
||||||
|
"batchEmptySelectedTips": "请选择要操作的数据"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,55 +1,59 @@
|
|||||||
{
|
{
|
||||||
"adjustType":"调整类型",
|
"adjustType": "调整类型",
|
||||||
"adjustReduceBalance":"减少余额",
|
"adjustReduceBalance": "减少余额",
|
||||||
"adjustAddBalance":"增加余额",
|
"adjustAddBalance": "增加余额",
|
||||||
"adjustReducePoint":"减少积分",
|
"adjustReducePoint": "减少积分",
|
||||||
"adjustAddPoint":"增加积分",
|
"adjustAddPoint": "增加积分",
|
||||||
"adjustBalance":"调整余额",
|
"adjustBalance": "调整余额",
|
||||||
"memberNo":"会员编号",
|
"memberNo": "会员编号",
|
||||||
"currBalance":"当前余额",
|
"currBalance": "当前余额",
|
||||||
"currPoint":"当前积分",
|
"currPoint": "当前积分",
|
||||||
"memo":"备注",
|
"memo": "备注",
|
||||||
"adjustPlaceholder":"请输入调整数量",
|
"adjustPlaceholder": "请输入调整数量",
|
||||||
"memoPlaceholder":"请输入备注",
|
"memoPlaceholder": "请输入备注",
|
||||||
"adjustBalancePlaceholder":"请输入调整余额",
|
"adjustBalancePlaceholder": "请输入调整余额",
|
||||||
"adjustPointPlaceholder":"请输入调整积分",
|
"adjustPointPlaceholder": "请输入调整积分",
|
||||||
"adjustBalanceMaxAccountMessage":"调整后余额需大于0",
|
"adjustBalanceMaxAccountMessage": "调整后余额需大于0",
|
||||||
"adjustPointMaxAccountMessage":"调整后积分需大于0",
|
"adjustPointMaxAccountMessage": "调整后积分需大于0",
|
||||||
"birthday": "出生日期",
|
"birthday": "出生日期",
|
||||||
"birthdayTip": "请输入出生日期",
|
"birthdayTip": "请输入出生日期",
|
||||||
"sex": "性别",
|
"sex": "性别",
|
||||||
"sexPlaceholder": "请选择性别",
|
"sexPlaceholder": "请选择性别",
|
||||||
"headimg": "会员头像",
|
"headimg": "会员头像",
|
||||||
"wxUnionid": "微信unionid",
|
"wxUnionid": "微信unionid",
|
||||||
"weappOpenid": "微信小程序openid",
|
"weappOpenid": "微信小程序openid",
|
||||||
"wxOpenid": "微信公众号openid",
|
"wxOpenid": "微信公众号openid",
|
||||||
"memberLabel": "会员标签",
|
"memberLabel": "会员标签",
|
||||||
"memberLabelPlaceholder": "请选择会员标签",
|
"memberLabelPlaceholder": "请选择会员标签",
|
||||||
"nickNamePlaceholder": "请输入会员名称",
|
"nickNamePlaceholder": "请输入会员名称",
|
||||||
"updateMember": "编辑会员信息",
|
"updateMember": "编辑会员信息",
|
||||||
"notAvailable":"暂无",
|
"notAvailable": "暂无",
|
||||||
"girlSex":"女",
|
"girlSex": "女",
|
||||||
"manSex":"男",
|
"manSex": "男",
|
||||||
"secrecySex":"保密",
|
"secrecySex": "保密",
|
||||||
"essentialInfo": "基本信息",
|
"essentialInfo": "基本信息",
|
||||||
"accountInfo": "账户信息",
|
"accountInfo": "账户信息",
|
||||||
"urserName": "用户名",
|
"urserName": "用户名",
|
||||||
"nickname":"会员昵称",
|
"nickname": "会员昵称",
|
||||||
"registeredSource": "注册来源",
|
"registeredSource": "注册来源",
|
||||||
"lastVisitTime":"最后登录时间",
|
"lastVisitTime": "最后登录时间",
|
||||||
"point": "积分",
|
"point": "积分",
|
||||||
"balance": "余额",
|
"balance": "余额",
|
||||||
"growth": "成长值",
|
"growth": "成长值",
|
||||||
"adjust":"调整",
|
"adjust": "调整",
|
||||||
"mobile":"手机号",
|
"mobile": "手机号",
|
||||||
"detail":"详情",
|
"detail": "详情",
|
||||||
"accumulative":"累计",
|
"accumulative": "累计",
|
||||||
"money":"可提现余额",
|
"money": "可提现余额",
|
||||||
"adjustPoint":"调整积分",
|
"adjustPoint": "调整积分",
|
||||||
"commission":"佣金",
|
"commission": "佣金",
|
||||||
"memberNull":"未读取到会员详情信息",
|
"memberNull": "未读取到会员详情信息",
|
||||||
"memberLevel": "会员等级",
|
"memberLevel": "会员等级",
|
||||||
"memberLevelUpdate": "修改等级至",
|
"memberLevelUpdate": "修改等级至",
|
||||||
"memberLevelUpdateTips": "该操作只会修改会员等级不会发放等级礼包",
|
"memberLevelUpdateTips": "该操作只会修改会员等级不会发放等级礼包",
|
||||||
"memberLevelPlaceholder": "请选择会员等级"
|
"memberLevelPlaceholder": "请选择会员等级",
|
||||||
|
"idCard": "身份证",
|
||||||
|
"idCardPlaceholder": "请输入身份证号",
|
||||||
|
"remark": "备注",
|
||||||
|
"remarkPlaceholder": "请输入备注"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
"orderInfo":"订单详情",
|
|
||||||
"orderDiscountMoney":"优惠金额",
|
|
||||||
"ip":"下单IP",
|
|
||||||
"payTime":"支付时间",
|
|
||||||
"remark":"商家留言",
|
|
||||||
"memberMessage":"买家留言",
|
|
||||||
"orderNo":"订单编号",
|
|
||||||
"orderStatus":"订单状态",
|
|
||||||
"orderNoPlaceholder":"请输入订单编号",
|
|
||||||
"createTime":"创建时间",
|
|
||||||
"rechargeMoney":"充值金额",
|
|
||||||
"orderMoney":"订单金额",
|
|
||||||
"member":"买家",
|
|
||||||
"orderFromName":"订单来源",
|
|
||||||
"payTypeName":"支付方式",
|
|
||||||
"startDate":"开始时间",
|
|
||||||
"endDate":"结束时间"
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
"totalRechargeRefundMoney":"充值退款(元)",
|
|
||||||
"totalRechargeMoney":"充值金额(元)",
|
|
||||||
"rechargeRefundMoney":"充值退款",
|
|
||||||
"rechargeNo":"充值单号",
|
|
||||||
"orderStatus":"订单状态",
|
|
||||||
"rechargeNoPlaceholder":"请输入充值单号",
|
|
||||||
"createTime":"充值时间",
|
|
||||||
"rechargeMoney":"充值金额",
|
|
||||||
"orderMoney":"订单金额",
|
|
||||||
"member":"会员信息",
|
|
||||||
"orderFromName":"订单来源",
|
|
||||||
"payTypeName":"支付方式",
|
|
||||||
"startDate":"开始时间",
|
|
||||||
"endDate":"结束时间",
|
|
||||||
"namePlaceholder":"请选择",
|
|
||||||
"refundBtn":"退款",
|
|
||||||
"refundContent":"是否确认退款",
|
|
||||||
"payTime": "支付时间",
|
|
||||||
"refundStatus": "退款状态",
|
|
||||||
"startMoney": "起始金额",
|
|
||||||
"endMoney": "结束金额"
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
{
|
|
||||||
"refundNumber":"退款单号",
|
|
||||||
"userInfo":"用户信息",
|
|
||||||
"sourceNumber":"来源单号",
|
|
||||||
"refundAmount":"退款金额",
|
|
||||||
"refundTime":"退款时间",
|
|
||||||
"detail": "详情",
|
|
||||||
"statusName": "状态",
|
|
||||||
"memberInfo": "会员信息",
|
|
||||||
"refundSource": "退款来源",
|
|
||||||
"startDate":"开始时间",
|
|
||||||
"endDate":"结束时间",
|
|
||||||
"refundStatus": "退款状态",
|
|
||||||
"accumulateRefundMoney": "累计退款金额(元)",
|
|
||||||
"haveRefundMoney": "退款中金额(元)",
|
|
||||||
"refundSuccessMonry": "退款成功金额(元)",
|
|
||||||
"refundFailMoney": "退款失败金额(元)",
|
|
||||||
"memberInfoPlaceholder":"请输入会员编号/昵称/手机号",
|
|
||||||
"refundNumberPlaceholder":"请输入退款单号",
|
|
||||||
"orderNumber": "来源单号",
|
|
||||||
"orderNumberPlaceholder": "请输入来源单号",
|
|
||||||
"refundDetail": "退款详情",
|
|
||||||
"nickname": "会员昵称"
|
|
||||||
}
|
|
||||||
@ -7,5 +7,9 @@
|
|||||||
"prefixTips": "编码格式如:",
|
"prefixTips": "编码格式如:",
|
||||||
"length": "编码长度",
|
"length": "编码长度",
|
||||||
"lengthPlaceholder": "请输入编码长度",
|
"lengthPlaceholder": "请输入编码长度",
|
||||||
"lengthTips": "编码长度包含前缀,去除前缀最少不能低于4位,最多不能超过30位"
|
"lengthTips": "编码长度包含前缀,去除前缀最少不能低于4位,最多不能超过30位",
|
||||||
|
"diyForm": "万能表单",
|
||||||
|
"diyFormPlaceholder": "请选择万能表单",
|
||||||
|
"addDiyForm": "添加表单",
|
||||||
|
"personalForm": "个人资料"
|
||||||
}
|
}
|
||||||
@ -73,5 +73,6 @@
|
|||||||
"search": "搜索",
|
"search": "搜索",
|
||||||
"foldText":"展开/折叠",
|
"foldText":"展开/折叠",
|
||||||
"appName": "套餐内含应用",
|
"appName": "套餐内含应用",
|
||||||
"addonName": "套餐内含插件"
|
"addonName": "套餐内含插件",
|
||||||
|
"siteInitTips":"确定要初始化站点吗?该操作将删除站点内所有数据,该操作无法退回,确定要继续初始化吗?"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,7 +27,7 @@
|
|||||||
"min": "分",
|
"min": "分",
|
||||||
"cronDeleteTips": "你确定要删除任务吗",
|
"cronDeleteTips": "你确定要删除任务吗",
|
||||||
"addCron": "添加任务",
|
"addCron": "添加任务",
|
||||||
"cronTimeTips": "任务周期时间不能为空",
|
"cronTimeTips": "任务周期时间不能为空并且大于0",
|
||||||
"cronTipsOne": "启动计划任务方式:",
|
"cronTipsOne": "启动计划任务方式:",
|
||||||
"cronTipsTwo": "1、使用命令启动:php think workerman 如果更改了任务周期、状态、删除任务等操作后,需要重新启动下 php think workerman 确保生效",
|
"cronTipsTwo": "1、使用命令启动:php think workerman 如果更改了任务周期、状态、删除任务等操作后,需要重新启动下 php think workerman 确保生效",
|
||||||
"doOne": "执行一次",
|
"doOne": "执行一次",
|
||||||
|
|||||||
@ -6,11 +6,11 @@
|
|||||||
<template v-if="Object.keys(appList).length">
|
<template v-if="Object.keys(appList).length">
|
||||||
|
|
||||||
<template v-for="(item, index) in appList" :key="index + 'b'">
|
<template v-for="(item, index) in appList" :key="index + 'b'">
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center" v-if="item.list.length">
|
||||||
<span class="text-page-title">{{ item.title }}</span>
|
<span class="text-page-title">{{ item.title }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-wrap plug-list pb-10 plug-large">
|
<div class="flex flex-wrap plug-list pb-10 plug-large" v-if="item.list.length">
|
||||||
<div class="cursor-pointer mt-[20px] mr-4 bg-[#f7f7f7]" v-for="(childItem,childIndex) in item.list" :key="childIndex" @click="toLink(childItem)">
|
<div class="cursor-pointer mt-[20px] mr-4 bg-[#f7f7f7]" v-for="(childItem,childIndex) in item.list" :key="childIndex" @click="toLink(childItem)">
|
||||||
<div class="w-[264px] flex py-[20px] px-[17px] app-item relative">
|
<div class="w-[264px] flex py-[20px] px-[17px] app-item relative">
|
||||||
<el-image class="w-[40px] h-[40px] mr-[10px]" :src="img(childItem.icon)" fit="contain">
|
<el-image class="w-[40px] h-[40px] mr-[10px]" :src="img(childItem.icon)" fit="contain">
|
||||||
|
|||||||
88
admin/src/app/views/app/marketing.vue
Normal file
88
admin/src/app/views/app/marketing.vue
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
<template>
|
||||||
|
<!--营销管理-->
|
||||||
|
<div class="main-container" v-loading="loading">
|
||||||
|
<el-card class="box-card !border-none" shadow="never">
|
||||||
|
|
||||||
|
<template v-if="Object.keys(marketingList).length">
|
||||||
|
|
||||||
|
<template v-for="(item, index) in marketingList" :key="index + 'b'">
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<span class="text-page-title">{{ item.title }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-wrap plug-list pb-10 plug-large">
|
||||||
|
<div class="cursor-pointer mt-[20px] mr-4 bg-[#f7f7f7]" v-for="(childItem,childIndex) in item.list" :key="childIndex" @click="toLink(childItem)">
|
||||||
|
<div class="w-[264px] flex py-[20px] px-[17px] app-item relative">
|
||||||
|
<el-image class="w-[40px] h-[40px] mr-[10px]" :src="img(childItem.icon)" fit="contain">
|
||||||
|
<template #error>
|
||||||
|
<div class="image-slot">
|
||||||
|
<img class="w-[40px] h-[40px]" src="@/app/assets/images/index/app_default.png" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-image>
|
||||||
|
<div class="flex flex-col justify-between w-[180px]">
|
||||||
|
<div class="text-[14px] flex items-center">
|
||||||
|
<span class="app-text max-w-[170px]">{{ childItem.title }}</span>
|
||||||
|
<!-- <span class="iconfont iconxiaochengxu2 text-[#00b240] ml-[4px] !text-[14px]"></span>-->
|
||||||
|
</div>
|
||||||
|
<!-- <el-icon color="#666">
|
||||||
|
<QuestionFilled />
|
||||||
|
</el-icon> -->
|
||||||
|
<p class="app-text text-[12px] text-[#999]">{{childItem.desc}}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="empty flex items-center justify-center" v-if="!loading && !Object.keys(marketingList).length">
|
||||||
|
<el-empty :description="t('emptyAppData')" />
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { getShowMarketing } from '@/app/api/site'
|
||||||
|
import { img } from '@/utils/common'
|
||||||
|
import useUserStore from '@/stores/modules/user'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { t } from '@/lang'
|
||||||
|
|
||||||
|
const addonIndexRoute = useUserStore().addonIndexRoute
|
||||||
|
const router = useRouter()
|
||||||
|
const marketingList = ref<Record<string, any>[]>([])
|
||||||
|
|
||||||
|
const loading = ref(true)
|
||||||
|
const getMarketingList = async () => {
|
||||||
|
const res = await getShowMarketing()
|
||||||
|
marketingList.value = res.data
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
getMarketingList()
|
||||||
|
|
||||||
|
const toLink = (item: any) => {
|
||||||
|
if (item.url) {
|
||||||
|
router.push(item.url)
|
||||||
|
} else {
|
||||||
|
addonIndexRoute[item.key] && router.push({ name: addonIndexRoute[item.key] })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.app-text {
|
||||||
|
overflow: hidden;
|
||||||
|
/* 超出部分隐藏 */
|
||||||
|
white-space: nowrap;
|
||||||
|
/* 禁止文本换行 */
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
/* 显示省略号 */
|
||||||
|
}
|
||||||
|
.app-item:hover{
|
||||||
|
transition: 0.5s;
|
||||||
|
box-shadow: 0px 2px 8px 0px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -4,6 +4,7 @@
|
|||||||
<el-descriptions :column="1">
|
<el-descriptions :column="1">
|
||||||
<el-descriptions-item :label="t('username')" label-align="right">{{logData.username}}</el-descriptions-item>
|
<el-descriptions-item :label="t('username')" label-align="right">{{logData.username}}</el-descriptions-item>
|
||||||
<el-descriptions-item :label="t('ip')" label-align="right">{{logData.ip}}</el-descriptions-item>
|
<el-descriptions-item :label="t('ip')" label-align="right">{{logData.ip}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item :label="t('operation')" label-align="right">{{logData.operation}}</el-descriptions-item>
|
||||||
<el-descriptions-item :label="t('url')" label-align="right"><span class="break-all">{{logData.url}}</span></el-descriptions-item>
|
<el-descriptions-item :label="t('url')" label-align="right"><span class="break-all">{{logData.url}}</span></el-descriptions-item>
|
||||||
<el-descriptions-item :label="t('type')" label-align="right">{{logData.type}}</el-descriptions-item>
|
<el-descriptions-item :label="t('type')" label-align="right">{{logData.type}}</el-descriptions-item>
|
||||||
<el-descriptions-item :label="t('params')" label-align="right">
|
<el-descriptions-item :label="t('params')" label-align="right">
|
||||||
|
|||||||
@ -39,6 +39,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<el-table-column prop="username" :label="t('username')" min-width="120" />
|
<el-table-column prop="username" :label="t('username')" min-width="120" />
|
||||||
<el-table-column prop="ip" :label="t('ip')" min-width="100" align="left"/>
|
<el-table-column prop="ip" :label="t('ip')" min-width="100" align="left"/>
|
||||||
|
<el-table-column prop="operation" :label="t('operation')" min-width="200" align="left"/>
|
||||||
<el-table-column prop="url" :label="t('url')" min-width="180" />
|
<el-table-column prop="url" :label="t('url')" min-width="180" />
|
||||||
<el-table-column prop="type" :label="t('type')" min-width="100" align="center"/>
|
<el-table-column prop="type" :label="t('type')" min-width="100" align="center"/>
|
||||||
<el-table-column :label="t('createTime')" min-width="180" align="center">
|
<el-table-column :label="t('createTime')" min-width="180" align="center">
|
||||||
|
|||||||
@ -28,8 +28,8 @@
|
|||||||
<el-table-column prop="role_name" :label="t('roleName')" />
|
<el-table-column prop="role_name" :label="t('roleName')" />
|
||||||
<el-table-column :label="t('status')">
|
<el-table-column :label="t('status')">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-tag type="success" v-if="row.status == 1">{{ row.status_name }}</el-tag>
|
<el-tag type="success" v-if="row.status == 1" @click="modifyRoleStatusEvent(row.role_id, 0)" class="cursor-pointer">{{ row.status_name }}</el-tag>
|
||||||
<el-tag type="error" v-if="row.status == 0">{{ row.status_name }}</el-tag>
|
<el-tag type="error" v-else @click="modifyRoleStatusEvent(row.role_id, 1)" class="cursor-pointer">{{ row.status_name }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="create_time" :label="t('createTime')"></el-table-column>
|
<el-table-column prop="create_time" :label="t('createTime')"></el-table-column>
|
||||||
@ -54,7 +54,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive } from 'vue'
|
import { ref, reactive } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getRoleList, deleteRole } from '@/app/api/sys'
|
import { getRoleList, deleteRole, modifyRoleStatus} from '@/app/api/sys'
|
||||||
import { ElMessageBox, FormInstance } from 'element-plus'
|
import { ElMessageBox, FormInstance } from 'element-plus'
|
||||||
import EditRole from '@/app/views/auth/components/edit-role.vue'
|
import EditRole from '@/app/views/auth/components/edit-role.vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
@ -136,6 +136,22 @@ const deleteEvent = (id: number) => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isRepeat = ref(false)
|
||||||
|
|
||||||
|
// 修改状态
|
||||||
|
const modifyRoleStatusEvent = (role_id: any, status: any) => {
|
||||||
|
if (isRepeat.value) return
|
||||||
|
isRepeat.value = true
|
||||||
|
|
||||||
|
modifyRoleStatus({
|
||||||
|
role_id,
|
||||||
|
status
|
||||||
|
}).then((res) => {
|
||||||
|
loadRoleList()
|
||||||
|
isRepeat.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -223,5 +223,4 @@ const deleteEvent = (uid: number) => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -3,31 +3,6 @@
|
|||||||
<div class="content-wrap float-btn" v-show="diyStore.editTab == 'content'">
|
<div class="content-wrap float-btn" v-show="diyStore.editTab == 'content'">
|
||||||
|
|
||||||
<div class="edit-attr-item-wrap">
|
<div class="edit-attr-item-wrap">
|
||||||
<!-- <h3 class="mb-[10px]">{{ t('selectStyle') }}</h3>
|
|
||||||
<el-form label-width="80px" class="px-[10px]">
|
|
||||||
<el-form-item :label="t('selectStyle')" class="flex">
|
|
||||||
<span class="text-primary flex-1 cursor-pointer" @click="showCouponStyle">{{ diyStore.editComponent.styleName }}</span>
|
|
||||||
<el-icon>
|
|
||||||
<ArrowRight />
|
|
||||||
</el-icon>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<el-dialog v-model="showCouponDialog" :title="t('selectStyle')" width="500px">
|
|
||||||
<div class="flex flex-wrap">
|
|
||||||
<template v-for="(item,index) in couponStyleList" :key="index">
|
|
||||||
<div :class="{ 'border-primary': selectCouponStyle.value == item.value }" @click="changeCouponStyle(item)" class="flex items-center justify-center overflow-hidden w-[200px] h-[100px] mr-[12px] cursor-pointer border bg-gray-50">
|
|
||||||
<img :src="img(item.url)" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
<template #footer>
|
|
||||||
<span class="dialog-footer">
|
|
||||||
<el-button @click="showCouponDialog = false">{{ t('cancel') }}</el-button>
|
|
||||||
<el-button type="primary" @click="confirmCouponStyle">{{ t('confirm') }}</el-button>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
</el-dialog> -->
|
|
||||||
<h3 class="mb-[10px]">{{ t('floatBtnButton') }}</h3>
|
<h3 class="mb-[10px]">{{ t('floatBtnButton') }}</h3>
|
||||||
<el-form label-width="80px" class="px-[10px]">
|
<el-form label-width="80px" class="px-[10px]">
|
||||||
<el-form-item :label="t('floatBtnButton')">
|
<el-form-item :label="t('floatBtnButton')">
|
||||||
@ -98,7 +73,6 @@ import { ref, reactive, onMounted, nextTick } from 'vue'
|
|||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import Sortable from 'sortablejs'
|
import Sortable from 'sortablejs'
|
||||||
import useDiyStore from '@/stores/modules/diy'
|
import useDiyStore from '@/stores/modules/diy'
|
||||||
import { img } from '@/utils/common'
|
|
||||||
import { range } from 'lodash-es'
|
import { range } from 'lodash-es'
|
||||||
|
|
||||||
const diyStore = useDiyStore()
|
const diyStore = useDiyStore()
|
||||||
@ -117,48 +91,6 @@ diyStore.editComponent.verify = (index: number) => {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********** 风格样式 **********/
|
|
||||||
|
|
||||||
const showCouponDialog = ref(false)
|
|
||||||
const selectCouponStyle = reactive({
|
|
||||||
title: diyStore.editComponent.styleName,
|
|
||||||
value: diyStore.editComponent.style
|
|
||||||
})
|
|
||||||
const showCouponStyle = () => {
|
|
||||||
showCouponDialog.value = true
|
|
||||||
selectCouponStyle.title = diyStore.editComponent.styleName;
|
|
||||||
selectCouponStyle.value = diyStore.editComponent.style;
|
|
||||||
}
|
|
||||||
// const couponStyleList = reactive([
|
|
||||||
// {
|
|
||||||
// url: 'addon/shop/diy/goods_coupon/style-1.png',
|
|
||||||
// title: '风格1',
|
|
||||||
// value: 'style-1'
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// url: 'addon/shop/diy/goods_coupon/style-2.png',
|
|
||||||
// title: '风格2',
|
|
||||||
// value: 'style-2'
|
|
||||||
// }
|
|
||||||
// ])
|
|
||||||
//风格点击
|
|
||||||
const changeCouponStyle = (item: any) => {
|
|
||||||
selectCouponStyle.title = item.title;
|
|
||||||
selectCouponStyle.value = item.value;
|
|
||||||
}
|
|
||||||
//确认风格
|
|
||||||
const confirmCouponStyle = () => {
|
|
||||||
diyStore.editComponent.styleName = selectCouponStyle.title;
|
|
||||||
diyStore.editComponent.style = selectCouponStyle.value;
|
|
||||||
showCouponDialog.value = false
|
|
||||||
selectTemplate.value = {
|
|
||||||
name: '右下',
|
|
||||||
src: 'iconyouxiajiao',
|
|
||||||
className: 'lowerRight'
|
|
||||||
};
|
|
||||||
diyStore.editComponent.bottomPosition = 'lowerRight'
|
|
||||||
}
|
|
||||||
/******** end *******/
|
|
||||||
const templateList = ref([
|
const templateList = ref([
|
||||||
{
|
{
|
||||||
name: '左上',
|
name: '左上',
|
||||||
|
|||||||
@ -65,6 +65,29 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="edit-attr-item-wrap">
|
||||||
|
<h3 class="mb-[10px]">{{ t('popWindowAds') }}</h3>
|
||||||
|
<el-form label-width="80px" class="px-[10px]">
|
||||||
|
<el-form-item :label="t('popAdsIsEnabled')" class="display-block">
|
||||||
|
<el-switch v-model="diyStore.global.popWindow.show" />
|
||||||
|
</el-form-item>
|
||||||
|
<div v-show="diyStore.global.popWindow.show">
|
||||||
|
<el-form-item :label="t('popAdsType')">
|
||||||
|
<el-radio-group v-model="diyStore.global.popWindow.count">
|
||||||
|
<el-radio label="once">{{ t('firstPop') }}</el-radio>
|
||||||
|
<el-radio label="always">{{ t('everyTimePops') }}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
<div class="text-sm text-gray-400">{{ t('popWindowCountTips') }}</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('popAdsImage')">
|
||||||
|
<upload-image v-model="diyStore.global.popWindow.imgUrl" :limit="1" @change="selectImg" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('popAdsLink')">
|
||||||
|
<diy-link v-model="diyStore.global.popWindow.link" />
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
<el-dialog v-model="showDialog" :title="t('selectStyle')" width="800px">
|
<el-dialog v-model="showDialog" :title="t('selectStyle')" width="800px">
|
||||||
|
|
||||||
@ -180,7 +203,6 @@ const inputBoth = (value: any) => {
|
|||||||
diyStore.value.forEach((item, index) => {
|
diyStore.value.forEach((item, index) => {
|
||||||
item.margin.both = value;
|
item.margin.both = value;
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@ -215,6 +237,15 @@ const changeStyle = () => {
|
|||||||
showDialog.value = false
|
showDialog.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const selectImg = (url: any) => {
|
||||||
|
const image = new Image()
|
||||||
|
image.src = img(url)
|
||||||
|
image.onload = async() => {
|
||||||
|
diyStore.global.popWindow.imgWidth = image.width
|
||||||
|
diyStore.global.popWindow.imgHeight = image.height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
defineExpose({})
|
defineExpose({})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -215,6 +215,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive, toRaw, watch, inject } from 'vue'
|
import { ref, reactive, toRaw, watch, inject } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
|
import { ArrowLeft } from "@element-plus/icons-vue"
|
||||||
import { img } from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import { getDiyTemplatePages, addDiyPage, editDiyPage, initPage } from '@/app/api/diy'
|
import { getDiyTemplatePages, addDiyPage, editDiyPage, initPage } from '@/app/api/diy'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
|||||||
@ -48,7 +48,7 @@
|
|||||||
<el-input class="!w-[215px]" v-model.trim="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" :ignore="['DIY_JUMP_OTHER_APPLET']" @confirm="diyLinkFn" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-icon class="close-icon cursor-pointer -top-[11px] -right-[8px]" @click="deleteNav(index)">
|
<el-icon class="close-icon cursor-pointer -top-[11px] -right-[8px]" @click="deleteNav(index)">
|
||||||
<CircleCloseFilled />
|
<CircleCloseFilled />
|
||||||
|
|||||||
@ -67,7 +67,7 @@ diyStore.editComponent.verify = (index: number) => {
|
|||||||
}
|
}
|
||||||
if (diyStore.value[index].limit > 9) {
|
if (diyStore.value[index].limit > 9) {
|
||||||
res.code = false
|
res.code = false
|
||||||
res.message = t('imafeLimitErrorTipsFour')
|
res.message = t('imageLimitErrorTipsFour')
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
|
|||||||
@ -370,6 +370,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive, toRaw, watch, inject, computed } from 'vue'
|
import { ref, reactive, toRaw, watch, inject, computed } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
|
import { ArrowLeft } from "@element-plus/icons-vue"
|
||||||
import { img } from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import { getDiyTemplatePages, addDiyForm, editDiyForm, initPage } from '@/app/api/diy_form'
|
import { getDiyTemplatePages, addDiyForm, editDiyForm, initPage } from '@/app/api/diy_form'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-drawer v-model="showDialog" :title="t('dataAndStatistics')" direction="rtl" size="70%" :before-close="handleClose" class="member-detail-drawer">
|
<el-drawer v-model="showDialog" :title="t('dataAndStatistics')" direction="rtl" size="70%" :before-close="handleClose" class="member-detail-drawer">
|
||||||
<el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
|
<el-tabs v-model="activeName" class="demo-tabs">
|
||||||
<el-tab-pane :label="t('detailData')" name="detail_data">
|
<el-tab-pane :label="t('detailData')" name="detail_data">
|
||||||
<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="formData.searchParam" ref="searchFormDiyFormRef">
|
<el-form :inline="true" :model="formData.searchParam" ref="searchFormDiyFormRef">
|
||||||
|
|||||||
@ -177,7 +177,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column align="right" fixed="right" width="120">
|
<el-table-column align="right" fixed="right" width="120">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button type="primary" link @click="successfulAuditFn(row)" v-if="row.status == 1"> {{ t('successfulAudit') }}</el-button>
|
<el-button type="primary" link @click="successfulAuditFn(row)" v-if="row.status == 1"> {{ t('successfulAudit') }}</el-button>
|
||||||
<el-button type="primary" link @click="auditFailureFn(row)" v-if="row.status == 1"> {{ t('auditFailure') }}</el-button>
|
<el-button type="primary" link @click="auditFailureFn(row)" v-if="row.status == 1"> {{ t('auditFailure') }}</el-button>
|
||||||
|
|||||||
@ -52,7 +52,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref, computed,defineEmits } from 'vue'
|
import { reactive, ref, computed,defineEmits } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getPayRefundInfo, getRefundType, getRefundTransfer } from '@/app/api/pay'
|
import { getPayRefundInfo, getRefundType, getRefundTransfer } from '@/app/api/pay'
|
||||||
import { FormInstance } from 'element-plus'
|
import { FormInstance } from 'element-plus'
|
||||||
|
|||||||
@ -10,8 +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.trim="payRefundTable.searchParam.refund_no"
|
<el-input v-model.trim="payRefundTable.searchParam.refund_no" :placeholder="t('refundNoPlaceholder')" />
|
||||||
:placeholder="t('refundNoPlaceholder')" />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('status')" prop="status">
|
<el-form-item :label="t('status')" prop="status">
|
||||||
<el-select v-model="payRefundTable.searchParam.status" clearable class="input-width">
|
<el-select v-model="payRefundTable.searchParam.status" clearable class="input-width">
|
||||||
|
|||||||
@ -156,7 +156,7 @@
|
|||||||
class="mx-1">联系我们</span> | <span class="mx-1">Cookies</span>
|
class="mx-1">联系我们</span> | <span class="mx-1">Cookies</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -178,7 +178,7 @@
|
|||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="text-[18px] text-[#333333]">站点名称</div>
|
<div class="text-[18px] text-[#333333]">站点名称</div>
|
||||||
<div class="w-[350px] h-[34px] ml-[10px]">
|
<div class="w-[350px] h-[34px] ml-[10px]">
|
||||||
<el-form :model="createSiteData.formData" ref="formRef" :rules="formRules">
|
<el-form :model="createSiteData.formData" ref="formRef">
|
||||||
<el-form-item prop="username">
|
<el-form-item prop="username">
|
||||||
<el-input class="create-site-name" v-model.trim="createSiteData.formData.site_name" maxlength="20" placeholder="请输入站点名称" autocomplete="off"></el-input>
|
<el-input class="create-site-name" v-model.trim="createSiteData.formData.site_name" maxlength="20" placeholder="请输入站点名称" autocomplete="off"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -227,7 +227,7 @@ import { getHomeSite, getSiteGroup, createSite } from '@/app/api/home'
|
|||||||
import useUserStore from '@/stores/modules/user'
|
import useUserStore from '@/stores/modules/user'
|
||||||
import useSystemStore from '@/stores/modules/system'
|
import useSystemStore from '@/stores/modules/system'
|
||||||
import { getWebCopyright } from '@/app/api/sys'
|
import { getWebCopyright } from '@/app/api/sys'
|
||||||
import { getInstalledAddonList } from '@/app/api/addon'
|
import { getGroupAppList } from '@/app/api/addon'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { AnyObject } from '@/types/global'
|
import { AnyObject } from '@/types/global'
|
||||||
import Test from '@/utils/test'
|
import Test from '@/utils/test'
|
||||||
@ -379,7 +379,7 @@ const addonList = ref<{
|
|||||||
key: string,
|
key: string,
|
||||||
title: string
|
title: string
|
||||||
}[]>([])
|
}[]>([])
|
||||||
getInstalledAddonList().then(({ data }) => {
|
getGroupAppList().then(({ data }) => {
|
||||||
const apps:any = []
|
const apps:any = []
|
||||||
Object.keys(data).forEach(key => {
|
Object.keys(data).forEach(key => {
|
||||||
const addon = data[key]
|
const addon = data[key]
|
||||||
|
|||||||
@ -65,10 +65,9 @@ const getUserInfoFn = () => {
|
|||||||
saveInfo.password = data.password
|
saveInfo.password = data.password
|
||||||
saveInfo.password_copy = data.password
|
saveInfo.password_copy = data.password
|
||||||
saveInfo.username = data.username
|
saveInfo.username = data.username
|
||||||
|
}).catch(() => {
|
||||||
|
loading.value = false
|
||||||
})
|
})
|
||||||
.catch(() => {
|
|
||||||
loading.value = false
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
getUserInfoFn()
|
getUserInfoFn()
|
||||||
|
|
||||||
|
|||||||
@ -59,7 +59,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="bg-[#EDEEF4] p-[20px] rounded-[6px] cursor-pointer flex flex-col items-start quick-action-card relative" @click="toHref('/app_manage/app_store','uninstalled')">
|
<div class="bg-[#EDEEF4] p-[20px] rounded-[6px] cursor-pointer flex flex-col items-start quick-action-card relative" @click="toHref('/app_manage/app_store','uninstalled')">
|
||||||
<div class="title flex items-center">
|
<div class="title flex items-center">
|
||||||
<span class="iconfont iconanzhuangyigechajianc !text-[20px] mr-[10px]"></span>
|
<span class="iconfont iconanzhuangyigechajian1 !text-[20px] mr-[10px]"></span>
|
||||||
<span class="text-[14px] text-[#1D1F3A]">安装一个插件</span>
|
<span class="text-[14px] text-[#1D1F3A]">安装一个插件</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="absolute bottom-3 left-5 right-4 desc">
|
<div class="absolute bottom-3 left-5 right-4 desc">
|
||||||
@ -248,7 +248,7 @@
|
|||||||
import { ref, watch ,onMounted} from 'vue'
|
import { ref, watch ,onMounted} from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getStatInfo } from '@/app/api/stat'
|
import { getStatInfo } from '@/app/api/stat'
|
||||||
import { getAppIndex} from '@/app/api/addon'
|
import { getAppIndex } from '@/app/api/addon'
|
||||||
import * as echarts from 'echarts'
|
import * as echarts from 'echarts'
|
||||||
import { getFrameworkNewVersion } from '@/app/api/module'
|
import { getFrameworkNewVersion } from '@/app/api/module'
|
||||||
import { getWebCopyright } from '@/app/api/sys'
|
import { getWebCopyright } from '@/app/api/sys'
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
<span class="text-page-title">{{ t("localAppText") }}</span>
|
<span class="text-page-title">{{ t("localAppText") }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-tabs v-model="activeName" class="mt-[10px]" @tab-click="handleClick">
|
<el-tabs v-model="activeName" class="mt-[10px]">
|
||||||
<el-tab-pane :label="t('installLabel')" name="installed"></el-tab-pane>
|
<el-tab-pane :label="t('installLabel')" name="installed"></el-tab-pane>
|
||||||
<el-tab-pane :label="t('uninstalledLabel')" name="uninstalled"></el-tab-pane>
|
<el-tab-pane :label="t('uninstalledLabel')" name="uninstalled"></el-tab-pane>
|
||||||
<el-tab-pane :label="t('buyLabel')" name="all"></el-tab-pane>
|
<el-tab-pane :label="t('buyLabel')" name="all"></el-tab-pane>
|
||||||
@ -66,8 +66,8 @@
|
|||||||
<div class="w-[236px] truncate leading-[18px] mt-[6px]" v-else>{{ row.version }}</div>
|
<div class="w-[236px] truncate leading-[18px] mt-[6px]" v-else>{{ row.version }}</div>
|
||||||
<div class="mt-[3px] flex flex-nowrap">
|
<div class="mt-[3px] flex flex-nowrap">
|
||||||
<el-tag type="danger" size="small" v-if="activeName == 'recentlyUpdated' && row.install_info && Object.keys(row.install_info)?.length && row.install_info.version != row.version">{{ t("newVersion") }}{{ row.version }}</el-tag>
|
<el-tag type="danger" size="small" v-if="activeName == 'recentlyUpdated' && row.install_info && Object.keys(row.install_info)?.length && row.install_info.version != row.version">{{ t("newVersion") }}{{ row.version }}</el-tag>
|
||||||
<el-tooltip v-if="versionJudge(row)" effect="dark" :content="`该插件适配框架版本为${ row.support_version },与已安装框架版本不完全兼容`" placement="top-start">
|
<el-tooltip v-if="versionJudge(row)" effect="dark" :content="`该插件适配框架版本为${ row.support_version },与已安装框架版本${frameworkVersion}不完全兼容`" placement="top-start">
|
||||||
<el-tag type="warning" size="small" class="ml-[3px]">该插件适配框架版本为{{ row.support_version }},与已安装框架版本不完全兼容</el-tag>
|
<el-tag type="warning" size="small" class="ml-[3px]">该插件适配框架版本为{{ row.support_version }},与已安装框架版本{{frameworkVersion}}不完全兼容</el-tag>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -332,10 +332,20 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- </el-scrollbar> -->
|
<!-- </el-scrollbar> -->
|
||||||
<div class="flex justify-end">
|
<div class="flex justify-end">
|
||||||
<el-tooltip effect="dark" :content="t('installTips')" placement="top">
|
<el-tooltip effect="dark" placement="top">
|
||||||
|
<template #content>
|
||||||
|
<div class="w-[400px]">
|
||||||
|
{{t("installTips")}}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<el-button :disabled="!installCheckResult.is_pass || cloudInstalling" :loading="localInstalling" @click="handleInstall">{{ t("localInstall") }}</el-button>
|
<el-button :disabled="!installCheckResult.is_pass || cloudInstalling" :loading="localInstalling" @click="handleInstall">{{ t("localInstall") }}</el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip effect="dark" :content="t('cloudInstallTips')" placement="top">
|
<el-tooltip effect="dark" placement="top">
|
||||||
|
<template #content>
|
||||||
|
<div class="w-[400px]">
|
||||||
|
{{t("cloudInstallTips")}}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<el-button type="primary" :disabled="!installCheckResult.is_pass || localInstalling" :loading="cloudInstalling" @click="handleCloudInstall">{{ t("cloudInstall") }}</el-button>
|
<el-button type="primary" :disabled="!installCheckResult.is_pass || localInstalling" :loading="cloudInstalling" @click="handleCloudInstall">{{ t("cloudInstall") }}</el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
@ -505,10 +515,6 @@ getVersions().then((res) => {
|
|||||||
frameworkVersion.value = res.data.version.version
|
frameworkVersion.value = res.data.version.version
|
||||||
})
|
})
|
||||||
|
|
||||||
const treeProps = reactive({
|
|
||||||
checkStrictly: false
|
|
||||||
})
|
|
||||||
|
|
||||||
const typeList = ref({})
|
const typeList = ref({})
|
||||||
const getAddonInitFn = () => {
|
const getAddonInitFn = () => {
|
||||||
getAddonInit().then((res) => {
|
getAddonInit().then((res) => {
|
||||||
@ -606,7 +612,7 @@ const buildInfo = (list: any[]) => {
|
|||||||
// const filteredUninstalled = localList.value.uninstalled.filter((el: any) => el.title.indexOf(search_name.value) != -1)
|
// const filteredUninstalled = localList.value.uninstalled.filter((el: any) => el.title.indexOf(search_name.value) != -1)
|
||||||
// const filteredAll = localList.value.all.filter((el: any) => el.title.indexOf(search_name.value) != -1)
|
// const filteredAll = localList.value.all.filter((el: any) => el.title.indexOf(search_name.value) != -1)
|
||||||
// const filteredRecentlyUpdated = localList.value.recentlyUpdated.filter((el: any) => el.title.indexOf(search_name.value) != -1)
|
// const filteredRecentlyUpdated = localList.value.recentlyUpdated.filter((el: any) => el.title.indexOf(search_name.value) != -1)
|
||||||
|
|
||||||
// // 构建父子关系
|
// // 构建父子关系
|
||||||
// info.value.installed = buildInfo(filteredInstalled)
|
// info.value.installed = buildInfo(filteredInstalled)
|
||||||
// info.value.uninstalled = buildInfo(filteredUninstalled)
|
// info.value.uninstalled = buildInfo(filteredUninstalled)
|
||||||
@ -895,17 +901,15 @@ const handleCloudInstall = () => {
|
|||||||
cloudInstalling.value = true
|
cloudInstalling.value = true
|
||||||
installType.value = 'cloud'
|
installType.value = 'cloud'
|
||||||
|
|
||||||
cloudInstallAddon({ addon: currAddon.value })
|
cloudInstallAddon({ addon: currAddon.value }).then((res) => {
|
||||||
.then((res) => {
|
installStep.value = 1
|
||||||
installStep.value = 1
|
terminalRef.value.execute('clear')
|
||||||
terminalRef.value.execute('clear')
|
terminalRef.value.execute('开始安装插件')
|
||||||
terminalRef.value.execute('开始安装插件')
|
getInstallTask()
|
||||||
getInstallTask()
|
cloudInstalling.value = false
|
||||||
cloudInstalling.value = false
|
}).catch((res) => {
|
||||||
})
|
cloudInstalling.value = false
|
||||||
.catch((res) => {
|
})
|
||||||
cloudInstalling.value = false
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const authElMessageBox = () => {
|
const authElMessageBox = () => {
|
||||||
@ -1162,7 +1166,7 @@ const batchUpgrade = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const visibleRowKeys = computed(() => {
|
const visibleRowKeys = computed(() => {
|
||||||
return new Set((info.value[activeName.value] || []).map(row => row.key));
|
return new Set((info.value[activeName.value] || []).map(row => row.key));
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -1442,6 +1446,7 @@ html.dark .table-head-bg {
|
|||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@ -215,11 +215,11 @@ const loginFn = (data = {}) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
.form-two .el-input__wrapper{
|
.form-two .el-input__wrapper {
|
||||||
// border: none !important;
|
// border: none !important;
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
border-bottom: 1px solid #DCDEE0 !important;
|
border-bottom: 1px solid #DCDEE0 !important;
|
||||||
padding:10px 0 !important;
|
padding: 10px 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 750px) {
|
@media only screen and (max-width: 750px) {
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<el-input class="input-width" v-model.trim="formData.continue_sign" @keyup="filterNumber($event)" :maxlength="3" clearable />
|
<el-input class="input-width" v-model.trim="formData.continue_sign" @keyup="filterNumber($event)" :maxlength="3" clearable />
|
||||||
<span class="ml-[10px]">{{ t('day') }}</span>
|
<span class="ml-[10px]">{{ t('day') }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('continueSignAward')" >
|
<el-form-item :label="t('continueSignAward')">
|
||||||
<div class="flex-1">
|
<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" />
|
||||||
@ -92,15 +92,15 @@ const regExp = {
|
|||||||
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: any) => {
|
validator: (rule: any, value: any, callback: any) => {
|
||||||
if (isNaN(value) || !regExp.number.test(value)) {
|
if (isNaN(value) || !regExp.number.test(value)) {
|
||||||
callback(t('continueSignFormatError'))
|
callback(t('continueSignFormatError'))
|
||||||
} else if (value < 2 || value > 365) {
|
} else if (value < 2 || value > 365) {
|
||||||
callback(t('continueSignBerweenDays'))
|
callback(t('continueSignBerweenDays'))
|
||||||
} else if (Number(value) > Number(props.sign_period)) {
|
} else if (Number(value) > Number(props.sign_period)) {
|
||||||
callback(t('continueSignMustLessThanSignPeriod')) // 添加这个校验
|
callback(t('continueSignMustLessThanSignPeriod')) // 添加这个校验
|
||||||
} else{
|
} else {
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -98,22 +98,18 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref, computed } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getVerifyDetail } from '@/app/api/verify'
|
import { getVerifyDetail } from '@/app/api/verify'
|
||||||
import { FormInstance, ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { ArrowLeft } from '@element-plus/icons-vue'
|
import { useRouter } from 'vue-router'
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
import { img } from '@/utils/common'
|
||||||
import { img, filterNumber } from '@/utils/common'
|
|
||||||
import useAppStore from '@/stores/modules/app'
|
|
||||||
|
|
||||||
const showDialog = ref(false)
|
const showDialog = ref(false)
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const appStore = useAppStore()
|
|
||||||
const activeName = ref('verifyInfo')
|
const activeName = ref('verifyInfo')
|
||||||
const formData:Record<string, any> = ref({})
|
|
||||||
|
|
||||||
const handleClick = (data:string) => {
|
const handleClick = (data:string) => {
|
||||||
activeName.value = data
|
activeName.value = data
|
||||||
|
|||||||
@ -141,7 +141,7 @@ const regExp: any = {
|
|||||||
// 表单验证规则
|
// 表单验证规则
|
||||||
const formRules = reactive<FormRules>({
|
const formRules = reactive<FormRules>({
|
||||||
day_award: [
|
day_award: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
trigger: 'change',
|
trigger: 'change',
|
||||||
validator: (rule: any, value: any, callback: any) => {
|
validator: (rule: any, value: any, callback: any) => {
|
||||||
@ -157,15 +157,15 @@ const formRules = reactive<FormRules>({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
sign_period:[{
|
sign_period: [{
|
||||||
required: true,
|
required: true,
|
||||||
trigger: 'blur',
|
trigger: 'blur',
|
||||||
validator: (rule: any, value: any, callback: any) => {
|
validator: (rule: any, value: any, callback: any) => {
|
||||||
if (value === null || value === '') {
|
if (value === null || value === '') {
|
||||||
callback(t('signPeriodTip'))
|
callback(t('signPeriodTip'))
|
||||||
}else if (isNaN(value) || !regExp.number.test(value)) {
|
} else if (isNaN(value) || !regExp.number.test(value)) {
|
||||||
callback(t('signPeriodLimitTips'))
|
callback(t('signPeriodLimitTips'))
|
||||||
}else if (value < 2 || value > 365) {
|
} else if (value < 2 || value > 365) {
|
||||||
callback(t('signPeriodMustZeroTips'))
|
callback(t('signPeriodMustZeroTips'))
|
||||||
} else {
|
} else {
|
||||||
callback()
|
callback()
|
||||||
|
|||||||
@ -53,7 +53,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-dialog v-model="showDialog" :title="t('addVerifier')" width="500px" :destroy-on-close="true">
|
<el-dialog v-model="showDialog" :title="formData.id ? t('editVerifier') : 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 @focus="handleSelectFocus" :disabled="isEditMode" :placeholder="t('searchPlaceholder')" :remote-method="searchMember" :loading="searchLoading" class="input-width">
|
<el-select v-model="formData.member_id" filterable remote reserve-keyword clearable @focus="handleSelectFocus" :disabled="isEditMode" :placeholder="t('searchPlaceholder')" :remote-method="searchMember" :loading="searchLoading" class="input-width">
|
||||||
|
|||||||
@ -93,10 +93,6 @@ import { getVerifyDetail } from '@/app/api/verify'
|
|||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { ArrowLeft } from '@element-plus/icons-vue'
|
import { ArrowLeft } from '@element-plus/icons-vue'
|
||||||
import { img } from '@/utils/common'
|
import { img } 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 route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@ -105,7 +101,6 @@ const back = () => {
|
|||||||
router.push('/marketing/verify')
|
router.push('/marketing/verify')
|
||||||
}
|
}
|
||||||
|
|
||||||
const appStore = useAppStore()
|
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
|
|
||||||
// 获取核销信息
|
// 获取核销信息
|
||||||
|
|||||||
@ -166,7 +166,7 @@ const memberAccountLogTableData = reactive({
|
|||||||
from_type: '',
|
from_type: '',
|
||||||
create_time: '',
|
create_time: '',
|
||||||
mobile: '',
|
mobile: '',
|
||||||
member_id: member_id,
|
member_id,
|
||||||
balance_type: ''
|
balance_type: ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -49,11 +49,11 @@ const formRules = reactive<FormRules>({
|
|||||||
if (!Test.decimal(formData.value.discount, 1)) {
|
if (!Test.decimal(formData.value.discount, 1)) {
|
||||||
callback('折扣格式错误')
|
callback('折扣格式错误')
|
||||||
}
|
}
|
||||||
if (parseFloat(formData.value.discount) < 0.1 || parseFloat(formData.value.discount) > 9.9) {
|
if (parseFloat(formData.value.discount) < 0 || parseFloat(formData.value.discount) > 9.9) {
|
||||||
callback('折扣只能输入0.1~9.9之间的值')
|
callback('折扣只能输入0~9.9之间的值')
|
||||||
}
|
}
|
||||||
if (formData.value.discount <= 0) {
|
if (formData.value.discount < 0) {
|
||||||
callback('折扣不能小于等于0')
|
callback('折扣不能小于0')
|
||||||
}
|
}
|
||||||
callback()
|
callback()
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -164,7 +164,9 @@
|
|||||||
<div class="flex mt-[15px] w-[33.3%] break-all leading-[21px]">
|
<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] w-[130px] text-right flex-shrink-0 mr-[20px]">{{ t('mobile') }}</span>
|
||||||
<span class="text-[14px] text-[#666666]">
|
<span class="text-[14px] text-[#666666]">
|
||||||
{{ formData.mobile || t('notAvailable') }}
|
{{ formData.mobile || t('notAvailable') }}<el-icon @click="editMemberInfo('mobile')" class="-bottom-[2px] -right-[4px] cursor-pointer">
|
||||||
|
<EditPen color="#273CE2" />
|
||||||
|
</el-icon>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex mt-[15px] w-[33.3%] break-all leading-[21px]">
|
<div class="flex mt-[15px] w-[33.3%] break-all leading-[21px]">
|
||||||
@ -199,6 +201,22 @@
|
|||||||
</el-icon>
|
</el-icon>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</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('身份证') }}</span>
|
||||||
|
<span class="text-[14px] text-[#666666]">
|
||||||
|
{{ formData.id_card || t('notAvailable') }}<el-icon @click="editMemberInfo('id_card')" 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('备注') }}</span>
|
||||||
|
<span class="text-[14px] text-[#666666]">
|
||||||
|
{{ formData.remark || t('notAvailable') }}<el-icon @click="editMemberInfo('remark')" 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]">
|
<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] w-[130px] text-right flex-shrink-0 mr-[20px]">{{ t('wxUnionid') }}</span>
|
||||||
<span class="text-[14px] text-[#666666]">
|
<span class="text-[14px] text-[#666666]">
|
||||||
@ -248,7 +266,7 @@
|
|||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getMemberInfo } from '@/app/api/member'
|
import { getMemberInfo } from '@/app/api/member'
|
||||||
import { FormInstance, ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { img } from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import PointEdit from '@/app/views/member/components/member-point-edit.vue'
|
import PointEdit from '@/app/views/member/components/member-point-edit.vue'
|
||||||
|
|||||||
@ -8,6 +8,15 @@
|
|||||||
<el-form-item :label="t('nickname')" v-if="type == 'nickname'">
|
<el-form-item :label="t('nickname')" v-if="type == 'nickname'">
|
||||||
<el-input v-model.trim="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('mobile')" v-if="type == 'mobile'" prop="mobile">
|
||||||
|
<el-input v-model.trim="saveData.mobile" clearable :placeholder="t('mobilePlaceholder')" maxlength="11" class="input-width" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('idCard')" v-if="type == 'id_card'" prop="id_card">
|
||||||
|
<el-input v-model.trim="saveData.id_card" clearable :placeholder="t('idCardPlaceholder')" maxlength="18" class="input-width" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('remark')" v-if="type == 'remark'" prop="remark">
|
||||||
|
<el-input v-model.trim="saveData.remark" type="textarea" clearable :placeholder="t('remarkPlaceholder')" maxlength="100" :rows="5" class="input-width" />
|
||||||
|
</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')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -23,7 +32,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<div v-if="type == 'member_level'">
|
<div v-if="type == 'member_level'">
|
||||||
<el-form-item :label="t('memberLevelUpdate')" prop="member_level">
|
<el-form-item :label="t('memberLevelUpdate')" prop="member_level">
|
||||||
<el-select v-model="saveData.member_level" :placeholder="t('memberLevelPlaceholder')" class="input-width">
|
<el-select v-model="saveData.member_level" :placeholder="t('memberLevelPlaceholder')" clearable class="input-width">
|
||||||
<el-option :label="t('memberLevelPlaceholder')" :value="0" />
|
<el-option :label="t('memberLevelPlaceholder')" :value="0" />
|
||||||
<el-option :label="item['level_name']" :value="item['level_id']" v-for="(item,index) in levelSelectData" :key="index"/>
|
<el-option :label="item['level_name']" :value="item['level_id']" v-for="(item,index) in levelSelectData" :key="index"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
@ -35,7 +44,8 @@
|
|||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
|
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
|
||||||
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{t('confirm')}}</el-button>
|
<el-button type="primary" :loading="loading" v-if="method=='batchSet'" @click="batchSetConfirm(formRef)">{{t('confirm')}}</el-button>
|
||||||
|
<el-button type="primary" :loading="loading" v-else @click="confirm(formRef)">{{t('confirm')}}</el-button>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@ -46,7 +56,7 @@ import { ref, reactive, computed } from 'vue'
|
|||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { deepClone } from '@/utils/common'
|
import { deepClone } from '@/utils/common'
|
||||||
import type { FormInstance } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
import { editMemberDetail, getMemberLabelAll, getMemberLevelAll } from '@/app/api/member'
|
import { editMemberDetail, getMemberLabelAll, getMemberLevelAll,memberBatchModify } from '@/app/api/member'
|
||||||
import Test from '@/utils/test'
|
import Test from '@/utils/test'
|
||||||
|
|
||||||
// 修改类型
|
// 修改类型
|
||||||
@ -87,16 +97,50 @@ getMemberLevelAll().then(({ data }) => {
|
|||||||
|
|
||||||
const formRules = computed(() => {
|
const formRules = computed(() => {
|
||||||
return {
|
return {
|
||||||
member_level: [
|
mobile: [
|
||||||
{
|
{
|
||||||
validator: (rule: any, value: any, callback: Function) => {
|
validator(rule, value, callback) {
|
||||||
if (Test.empty(saveData.member_level)) {
|
// 允许为空,直接通过验证
|
||||||
callback(t('memberLevelPlaceholder'))
|
if (!value) return callback();
|
||||||
}
|
|
||||||
callback()
|
// 非空值时,验证手机号格式
|
||||||
|
const reg = /^1[3-9]\d{9}$/;
|
||||||
|
if (!reg.test(value)) {
|
||||||
|
callback(new Error('请输入正确的手机号'));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
id_card:[
|
||||||
|
{
|
||||||
|
validator(rule, value, callback) {
|
||||||
|
// 允许为空,直接通过验证
|
||||||
|
if (!value) return callback();
|
||||||
|
|
||||||
|
// 非空值时,验证身份证号格式
|
||||||
|
const reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
|
||||||
|
if (!reg.test(value)) {
|
||||||
|
callback(new Error('请输入正确的身份证号'));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trigger: 'blur'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
// member_level: [
|
||||||
|
// {
|
||||||
|
// validator: (rule: any, value: any, callback: Function) => {
|
||||||
|
// if (Test.empty(saveData.member_level)) {
|
||||||
|
// callback(t('memberLevelPlaceholder'))
|
||||||
|
// }
|
||||||
|
// callback()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -151,7 +195,7 @@ const confirm = async (formEl: FormInstance | undefined) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// 修改
|
||||||
const setDialogType = async (row: any = null) => {
|
const setDialogType = async (row: any = null) => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
type.value = row.type
|
type.value = row.type
|
||||||
@ -178,9 +222,63 @@ const setDialogType = async (row: any = null) => {
|
|||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 批量设置
|
||||||
|
const method = ref(null)
|
||||||
|
const batchInfo = ref({
|
||||||
|
is_all: 0,
|
||||||
|
ids: [],
|
||||||
|
where: {}
|
||||||
|
})
|
||||||
|
const batchSetDialogType = (data)=>{
|
||||||
|
loading.value = true
|
||||||
|
type.value =data.type
|
||||||
|
method.value = data.method
|
||||||
|
batchInfo.value.is_all = data.data.is_all
|
||||||
|
batchInfo.value.ids = data.data.ids
|
||||||
|
batchInfo.value.where = data.data.where
|
||||||
|
title.value = data.title
|
||||||
|
saveData[type.value] = null
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const batchSetConfirm = async (formEl: FormInstance | undefined) => {
|
||||||
|
await formRef.value?.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
loading.value = true
|
||||||
|
|
||||||
|
if (repeat.value) return
|
||||||
|
repeat.value = true
|
||||||
|
|
||||||
|
let val = saveData[type.value];
|
||||||
|
if(type.value == 'member_label'){
|
||||||
|
val = saveData[type.value] && saveData[type.value].length ? deepClone(saveData[type.value]).join(',').split(',') : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = ref({
|
||||||
|
is_all: batchInfo.value.is_all,
|
||||||
|
member_ids:batchInfo.value.ids,
|
||||||
|
where: batchInfo.value.where,
|
||||||
|
field: type.value,
|
||||||
|
value: val
|
||||||
|
})
|
||||||
|
console.log(data.value)
|
||||||
|
memberBatchModify(data.value).then(res => {
|
||||||
|
loading.value = false
|
||||||
|
repeat.value = false
|
||||||
|
showDialog.value = false
|
||||||
|
emit('complete')
|
||||||
|
}).catch(() => {
|
||||||
|
loading.value = false
|
||||||
|
repeat.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
showDialog,
|
showDialog,
|
||||||
setDialogType
|
setDialogType,
|
||||||
|
batchSetDialogType
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, reactive, ref, watch } from 'vue'
|
import { computed, reactive, ref, watch } from 'vue'
|
||||||
import { FormRules } from 'element-plus'
|
import { FormRules } from 'element-plus'
|
||||||
import Test from '@/utils/test'
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
|
|||||||
@ -107,7 +107,6 @@ const confirm = async (formEl: FormInstance | undefined) => {
|
|||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
repeat.value = false
|
repeat.value = false
|
||||||
// showDialog.value = false
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -2,38 +2,38 @@
|
|||||||
<el-dialog v-model="showDialog" :title="t('balanceInfo')" width="550px" :destroy-on-close="true">
|
<el-dialog v-model="showDialog" :title="t('balanceInfo')" 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('headimg')" >
|
<el-form-item :label="t('headimg')">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<img class="w-[50px] h-[50px] mr-[10px]" v-if="formData.member.headimg" :src="img(formData.member.headimg)" alt="" >
|
<img class="w-[50px] h-[50px] mr-[10px]" v-if="formData.member.headimg" :src="img(formData.member.headimg)" alt="" >
|
||||||
<img class="w-[50px] h-[50px] mr-[10px] rounded-full" v-else src="@/app/assets/images/member_head.png" alt="">
|
<img class="w-[50px] h-[50px] mr-[10px] rounded-full" v-else src="@/app/assets/images/member_head.png" alt="">
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('memberId')" >
|
<el-form-item :label="t('memberId')">
|
||||||
<div class="input-width"> {{ formData.member.member_no }} </div>
|
<div class="input-width"> {{ formData.member.member_no }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('nickName')" >
|
<el-form-item :label="t('nickName')">
|
||||||
<div class="input-width"> {{ formData.member.nickname }} </div>
|
<div class="input-width"> {{ formData.member.nickname }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('mobile')" >
|
<el-form-item :label="t('mobile')">
|
||||||
<div class="input-width"> {{ formData.member.mobile }} </div>
|
<div class="input-width"> {{ formData.member.mobile }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('accountData')" >
|
<el-form-item :label="t('accountData')">
|
||||||
<div class="input-width"> {{ formData.account_data }} </div>
|
<div class="input-width"> {{ formData.account_data }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('fromType')" >
|
<el-form-item :label="t('fromType')">
|
||||||
<div class="input-width"> {{ formData.from_type_name }} </div>
|
<div class="input-width"> {{ formData.from_type_name }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('memo')" >
|
<el-form-item :label="t('memo')">
|
||||||
<div class="input-width"> {{ formData.memo }} </div>
|
<div class="input-width"> {{ formData.memo }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('createTime')" >
|
<el-form-item :label="t('createTime')">
|
||||||
<div class="input-width"> {{ formData.create_time }} </div>
|
<div class="input-width"> {{ formData.create_time }} </div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('adjustPoint')" prop="adjust">
|
<el-form-item :label="t('adjustPoint')" prop="adjust">
|
||||||
<el-input-number v-model="formData.adjust" clearable :min="0" :max="999999" :placeholder="t('adjustPlaceholder')"/>
|
<el-input-number v-model="formData.adjust" clearable :min="0" :max="999999" :placeholder="t('adjustPlaceholder')" @focus="formData.adjust = ''" class="!w-[200px]"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('memo')" prop="memo">
|
<el-form-item :label="t('memo')" prop="memo">
|
||||||
@ -94,7 +94,7 @@ const confirm = async (formEl: FormInstance | undefined) => {
|
|||||||
await formEl.validate(async (valid) => {
|
await formEl.validate(async (valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
||||||
if (repeat.value) return
|
if (repeat.value) return
|
||||||
repeat.value = true
|
repeat.value = true
|
||||||
|
|
||||||
|
|||||||
@ -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.trim="memberTableData.searchParam.keyword" class="w-[240px]" :placeholder="t('memberInfoPlaceholder')" />
|
<el-input v-model.trim="memberTableData.searchParam.keyword" class="!w-[200px]" :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">
|
||||||
@ -47,11 +47,29 @@
|
|||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<div class="mt-[10px]">
|
<div class="mt-[10px]">
|
||||||
<el-table :data="memberTableData.data" size="large" v-loading="memberTableData.loading">
|
<div class="mb-[10px] flex items-center">
|
||||||
|
<el-dropdown class="mr-[20px] !text-primary">
|
||||||
|
<span class="el-dropdown-link">
|
||||||
|
<span>{{ currentSelectMode === 'all' ? t('全选所有页') : t('全选当前页')}}</span>({{ selectedCount }})
|
||||||
|
<el-icon>
|
||||||
|
<arrow-down />
|
||||||
|
</el-icon>
|
||||||
|
</span>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item class="select-wrap" :class="{ active: currentSelectMode === 'all' }" @click="selectAllPages">全选所有页</el-dropdown-item>
|
||||||
|
<el-dropdown-item class="select-wrap" :class="{ active: currentSelectMode === 'page' }" @click="toggleChange">全选当前页</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
<el-button @click="batchSetLabel" size="small">{{ t('标签') }}</el-button>
|
||||||
|
<el-button @click="batchSetLevel" size="small">{{ t('等级') }}</el-button>
|
||||||
|
</div>
|
||||||
|
<el-table :data="memberTableData.data" size="large" ref="memberListTableRef" v-loading="memberTableData.loading" :row-key="row => row.member_id" :default-selection="defaultSelection" @selection-change="handleSelectionChange">
|
||||||
<template #empty>
|
<template #empty>
|
||||||
<span>{{ !memberTableData.loading ? t('emptyData') : '' }}</span>
|
<span>{{ !memberTableData.loading ? t('emptyData') : '' }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
<el-table-column type="selection" width="55" />
|
||||||
<el-table-column prop="member_no" :label="t('memberNo')" min-width="120" />
|
<el-table-column prop="member_no" :label="t('memberNo')" min-width="120" />
|
||||||
<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 }">
|
||||||
@ -120,9 +138,8 @@
|
|||||||
@size-change="loadMemberList()" @current-change="loadMemberList" />
|
@size-change="loadMemberList()" @current-change="loadMemberList" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<add-member ref="addMemberDialog" @complete="loadMemberList()" />
|
<add-member ref="addMemberDialog" @complete="loadMemberList()" />
|
||||||
<edit-member ref="editMemberDialog" @complete="loadMemberList()" />
|
<edit-member ref="editMemberDialog" @complete="loadMemberListReset()" />
|
||||||
<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>
|
<detail-member ref="detailMemberDialog" @load="loadMemberList()"></detail-member>
|
||||||
</el-card>
|
</el-card>
|
||||||
@ -130,7 +147,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref,nextTick ,computed } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { img } from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import { getRegisterChannelType, getMemberList, getMemberLabelAll, editMemberStatus, deleteMember, getMemberLevelAll } from '@/app/api/member'
|
import { getRegisterChannelType, getMemberList, getMemberLabelAll, editMemberStatus, deleteMember, getMemberLevelAll } from '@/app/api/member'
|
||||||
@ -183,9 +200,11 @@ getMemberLevelAll().then(({ data }) => {
|
|||||||
const resetForm = (formEl: FormInstance | undefined) => {
|
const resetForm = (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
formEl.resetFields()
|
formEl.resetFields()
|
||||||
|
isReset.value = true
|
||||||
loadMemberList()
|
loadMemberList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isReset = ref(false)
|
||||||
// 获取会员列表
|
// 获取会员列表
|
||||||
const loadMemberList = (page: number = 1) => {
|
const loadMemberList = (page: number = 1) => {
|
||||||
memberTableData.loading = true
|
memberTableData.loading = true
|
||||||
@ -199,12 +218,195 @@ const loadMemberList = (page: number = 1) => {
|
|||||||
memberTableData.loading = false
|
memberTableData.loading = false
|
||||||
memberTableData.data = res.data.data
|
memberTableData.data = res.data.data
|
||||||
memberTableData.total = res.data.total
|
memberTableData.total = res.data.total
|
||||||
|
if (isReset.value) {
|
||||||
|
isSelectAllPages.value = false
|
||||||
|
excludedIds.value = []
|
||||||
|
currentSelectMode.value = null
|
||||||
|
multipleSelection.value = []
|
||||||
|
}
|
||||||
|
if (isSelectAllPages.value && !isReset.value) {
|
||||||
|
restoringSelection.value = true
|
||||||
|
nextTick(() => {
|
||||||
|
memberTableData.data.forEach(item => {
|
||||||
|
if (!excludedIds.value.includes(item.member_id)) {
|
||||||
|
memberListTableRef.value?.toggleRowSelection(item, true)
|
||||||
|
} else {
|
||||||
|
memberListTableRef.value?.toggleRowSelection(item, false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
restoringSelection.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
isReset.value = false
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
|
isReset.value = false
|
||||||
memberTableData.loading = false
|
memberTableData.loading = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
loadMemberList()
|
loadMemberList()
|
||||||
|
|
||||||
|
// 全选所有页时排除的 ID
|
||||||
|
const excludedIds = ref<number[]>([])
|
||||||
|
// 是否全选所有页
|
||||||
|
const isSelectAllPages = ref(false)
|
||||||
|
|
||||||
|
const currentSelectMode = ref<'all' | 'page' | null>(null)
|
||||||
|
|
||||||
|
// 全选当前页
|
||||||
|
const toggleChange = () => {
|
||||||
|
restoringSelection.value = true // 加锁
|
||||||
|
if (currentSelectMode.value === 'page') {
|
||||||
|
isSelectAllPages.value = false
|
||||||
|
currentSelectMode.value = null
|
||||||
|
excludedIds.value = []
|
||||||
|
multipleSelection.value = []
|
||||||
|
memberListTableRef.value.clearSelection()
|
||||||
|
} else {
|
||||||
|
isSelectAllPages.value = false
|
||||||
|
currentSelectMode.value = 'page'
|
||||||
|
excludedIds.value = []
|
||||||
|
multipleSelection.value = []
|
||||||
|
memberTableData.data.forEach(row => {
|
||||||
|
memberListTableRef.value.toggleRowSelection(row, true)
|
||||||
|
})
|
||||||
|
multipleSelection.value = [...memberTableData.data]
|
||||||
|
}
|
||||||
|
nextTick(() => {
|
||||||
|
restoringSelection.value = false // 解锁
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全选所有页
|
||||||
|
const selectAllPages = () => {
|
||||||
|
restoringSelection.value = true // 加锁
|
||||||
|
if (currentSelectMode.value === 'all') {
|
||||||
|
isSelectAllPages.value = false
|
||||||
|
currentSelectMode.value = null
|
||||||
|
excludedIds.value = []
|
||||||
|
multipleSelection.value = []
|
||||||
|
memberListTableRef.value.clearSelection()
|
||||||
|
} else {
|
||||||
|
// memberListTableRef.value.clearSelection()
|
||||||
|
excludedIds.value = []
|
||||||
|
multipleSelection.value = []
|
||||||
|
isSelectAllPages.value = true
|
||||||
|
currentSelectMode.value = 'all'
|
||||||
|
memberTableData.data.forEach(row => {
|
||||||
|
memberListTableRef.value.toggleRowSelection(row, true)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
nextTick(() => {
|
||||||
|
restoringSelection.value = false // 解锁
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const defaultSelection = computed(() => {
|
||||||
|
if (isSelectAllPages.value) {
|
||||||
|
return memberTableData.data.filter(item => !excludedIds.value.includes(item.member_id))
|
||||||
|
} else {
|
||||||
|
return multipleSelection.value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const memberListTableRef = ref()
|
||||||
|
|
||||||
|
// 选中数据
|
||||||
|
const multipleSelection: any = ref([])
|
||||||
|
const restoringSelection = ref(false)
|
||||||
|
|
||||||
|
const handleSelectionChange = (val: any[]) => {
|
||||||
|
if (restoringSelection.value) return // 阻止自动恢复触发逻辑
|
||||||
|
|
||||||
|
if (isSelectAllPages.value) {
|
||||||
|
const currentPageIds = memberTableData.data.map(item => item.member_id)
|
||||||
|
const selectedIds = val.map(item => item.member_id)
|
||||||
|
const unselected = currentPageIds.filter(id => !selectedIds.includes(id))
|
||||||
|
|
||||||
|
excludedIds.value = Array.from(new Set([...excludedIds.value, ...unselected]))
|
||||||
|
excludedIds.value = excludedIds.value.filter(id => !selectedIds.includes(id))
|
||||||
|
} else {
|
||||||
|
multipleSelection.value = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const selectedCount = computed(() => {
|
||||||
|
if (isSelectAllPages.value) {
|
||||||
|
return memberTableData.total - excludedIds.value.length
|
||||||
|
} else {
|
||||||
|
return multipleSelection.value.length
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const getBatchPayload = () => {
|
||||||
|
if (isSelectAllPages.value) {
|
||||||
|
return {
|
||||||
|
is_all: 1,
|
||||||
|
ids: excludedIds.value,
|
||||||
|
where: {
|
||||||
|
...memberTableData.searchParam
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
is_all: 0,
|
||||||
|
ids: multipleSelection.value.map(item => item.member_id),
|
||||||
|
where: {
|
||||||
|
...memberTableData.searchParam
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** ***************** 批量设置-start *************************/
|
||||||
|
const batchSetLabel = () => {
|
||||||
|
const isNoneSelected =
|
||||||
|
(!isSelectAllPages.value && multipleSelection.value.length === 0) ||
|
||||||
|
(isSelectAllPages.value && excludedIds.value.length === memberTableData.total)
|
||||||
|
|
||||||
|
if (isNoneSelected) {
|
||||||
|
ElMessage({
|
||||||
|
type: 'warning',
|
||||||
|
message: `${ t('batchEmptySelectedTips') }`
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const info = getBatchPayload()
|
||||||
|
const data = ref({
|
||||||
|
method: 'batchSet',
|
||||||
|
type: 'member_label',
|
||||||
|
title: t('批量设置会员标签'),
|
||||||
|
data: info
|
||||||
|
})
|
||||||
|
editMemberDialog.value.batchSetDialogType(data.value)
|
||||||
|
editMemberDialog.value.showDialog = true
|
||||||
|
}
|
||||||
|
// 等级
|
||||||
|
const batchSetLevel = () => {
|
||||||
|
const isNoneSelected =
|
||||||
|
(!isSelectAllPages.value && multipleSelection.value.length === 0) ||
|
||||||
|
(isSelectAllPages.value && excludedIds.value.length === memberTableData.total)
|
||||||
|
|
||||||
|
if (isNoneSelected) {
|
||||||
|
ElMessage({
|
||||||
|
type: 'warning',
|
||||||
|
message: `${t('batchEmptySelectedTips')}`
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const info = getBatchPayload()
|
||||||
|
const data = ref({
|
||||||
|
method: 'batchSet',
|
||||||
|
type: 'member_level',
|
||||||
|
title: t('批量设置会员等级'),
|
||||||
|
data: info
|
||||||
|
})
|
||||||
|
editMemberDialog.value.batchSetDialogType(data.value)
|
||||||
|
editMemberDialog.value.showDialog = true
|
||||||
|
}
|
||||||
|
const loadMemberListReset = () => {
|
||||||
|
isReset.value = true
|
||||||
|
loadMemberList()
|
||||||
|
}
|
||||||
|
/** ***************** 批量设置-end *************************/
|
||||||
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)
|
const detailMemberDialog: Record<string, any> | null = ref(null)
|
||||||
@ -249,12 +451,6 @@ const addEvent = () => {
|
|||||||
addMemberDialog.value.showDialog = true
|
addMemberDialog.value.showDialog = true
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 编辑会员
|
|
||||||
* @param data
|
|
||||||
*/
|
|
||||||
const editEvent = (data: any) => { }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 会员详情
|
* 会员详情
|
||||||
*/
|
*/
|
||||||
@ -280,10 +476,11 @@ const exportEvent = () => {
|
|||||||
*/
|
*/
|
||||||
const lockMember = (res: any, status: any) => {
|
const lockMember = (res: any, status: any) => {
|
||||||
editMemberStatus({
|
editMemberStatus({
|
||||||
status: status,
|
status,
|
||||||
member_ids: [res.member_id]
|
member_ids: [res.member_id]
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
if (res.code >= 0) {
|
if (res.code >= 0) {
|
||||||
|
isReset.value = true
|
||||||
loadMemberList()
|
loadMemberList()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -199,6 +199,22 @@
|
|||||||
</el-icon>
|
</el-icon>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex items-center mt-[15px]">
|
||||||
|
<span class="text-[14px] w-[130px] text-right flex-shrink-0 mr-[20px]">{{ t('身份证') }}</span>
|
||||||
|
<span class="text-[14px] text-[#666666]">
|
||||||
|
{{ formData.id_card || t('notAvailable') }}<el-icon @click="editMemberInfo('id_card')" class="-bottom-[2px] -right-[4px] cursor-pointer">
|
||||||
|
<EditPen color="#273CE2" />
|
||||||
|
</el-icon>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center mt-[15px]">
|
||||||
|
<span class="text-[14px] w-[130px] text-right flex-shrink-0 mr-[20px]">{{ t('备注') }}</span>
|
||||||
|
<span class="text-[14px] text-[#666666]">
|
||||||
|
{{ formData.remark || t('notAvailable') }}<el-icon @click="editMemberInfo('remark')" class="-bottom-[2px] -right-[4px] cursor-pointer">
|
||||||
|
<EditPen color="#273CE2" />
|
||||||
|
</el-icon>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<div class="flex items-center mt-[15px]">
|
<div class="flex items-center mt-[15px]">
|
||||||
<span class="text-[14px] w-[130px] text-right mr-[20px]">{{ t('wxUnionid') }}</span>
|
<span class="text-[14px] w-[130px] text-right mr-[20px]">{{ t('wxUnionid') }}</span>
|
||||||
<span class="text-[14px] text-[#666666]">
|
<span class="text-[14px] text-[#666666]">
|
||||||
@ -360,12 +376,12 @@ const infoCommission = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const back = () => {
|
const back = () => {
|
||||||
if (window.history.length > 1){
|
if (window.history.length > 1) {
|
||||||
router.go(-1)
|
router.go(-1)
|
||||||
}else{
|
} else {
|
||||||
router.push(`/member/member`)
|
router.push(`/member/member`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -142,7 +142,7 @@ const memberAccountLogTableData = reactive({
|
|||||||
from_type: '',
|
from_type: '',
|
||||||
create_time: '',
|
create_time: '',
|
||||||
mobile: '',
|
mobile: '',
|
||||||
member_id: member_id
|
member_id
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -225,6 +225,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive, toRaw, watch, inject } from 'vue'
|
import { ref, reactive, toRaw, watch, inject } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
|
import { ArrowLeft } from "@element-plus/icons-vue"
|
||||||
import { img } from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
|
|||||||
@ -118,6 +118,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive, computed } from 'vue'
|
import { ref, reactive, computed } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
|
import { ArrowLeft } from "@element-plus/icons-vue"
|
||||||
import { FormInstance, ElMessage } from 'element-plus'
|
import { FormInstance, ElMessage } from 'element-plus'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { deepClone } from '@/utils/common';
|
import { deepClone } from '@/utils/common';
|
||||||
|
|||||||
@ -118,6 +118,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive, computed } from 'vue'
|
import { ref, reactive, computed } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
|
import { ArrowLeft } from "@element-plus/icons-vue"
|
||||||
import { FormInstance, ElMessage } from 'element-plus'
|
import { FormInstance, ElMessage } from 'element-plus'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { getPrinterType, addPrinterTemplate, editPrinterTemplate, getPrinterTemplateInfo } from '@/app/api/printer'
|
import { getPrinterType, addPrinterTemplate, editPrinterTemplate, getPrinterTemplateInfo } from '@/app/api/printer'
|
||||||
|
|||||||
@ -75,21 +75,21 @@ const formRules = computed(() => {
|
|||||||
{ required: true, message: t('titlePlaceholder'), trigger: 'blur' }
|
{ required: true, message: t('titlePlaceholder'), trigger: 'blur' }
|
||||||
],
|
],
|
||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
trigger: ['blur', 'change'],
|
trigger: ['blur', 'change'],
|
||||||
validator: (rule: any, value: any, callback: any) => {
|
validator: (rule: any, value: any, callback: any) => {
|
||||||
if (value === '') {
|
if (value === '') {
|
||||||
callback(new Error(t('contentPlaceholder')))
|
callback(new Error(t('contentPlaceholder')))
|
||||||
} else if (value.length < 5 || value.length > 100000) {
|
} else if (value.length < 5 || value.length > 100000) {
|
||||||
callback(new Error(t('contentMaxTips')))
|
callback(new Error(t('contentMaxTips')))
|
||||||
return false
|
return false
|
||||||
} else {
|
} else {
|
||||||
callback()
|
callback()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -7,10 +7,10 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('smsType')">
|
<el-form-item :label="t('smsType')">
|
||||||
<div class="input-width">
|
<div class="input-width">
|
||||||
<div v-if="formData.notice_type == 'sms'">{{ t('sms') }}</div>
|
<div v-if="formData.notice_type == 'sms'">{{ t('sms') }}</div>
|
||||||
<div v-if="formData.notice_type == 'wechat'">{{ t('wechat') }}</div>
|
<div v-if="formData.notice_type == 'wechat'">{{ t('wechat') }}</div>
|
||||||
<div v-if="formData.notice_type == 'weapp'">{{ t('weapp') }}</div>
|
<div v-if="formData.notice_type == 'weapp'">{{ t('weapp') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
|||||||
@ -89,7 +89,6 @@ const confirm = async (formEl: FormInstance | undefined) => {
|
|||||||
emit('complete')
|
emit('complete')
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
// showDialog.value = false
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -104,7 +104,6 @@ const confirm = async (formEl: FormInstance | undefined) => {
|
|||||||
emit('complete')
|
emit('complete')
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
// showDialog.value = false
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -5,33 +5,33 @@
|
|||||||
<span class="">还未注册牛云短信?</span>
|
<span class="">还未注册牛云短信?</span>
|
||||||
<span @click="toRegister" class="cursor-pointer text-primary">去注册</span>
|
<span @click="toRegister" class="cursor-pointer text-primary">去注册</span>
|
||||||
</div>
|
</div>
|
||||||
<el-form :model="formData" label-width="100px" ref="formRef" :rules="formRules" class="page-form mt-[20px] ml-[50px]">
|
<el-form :model="formData" label-width="150px" ref="formRef" :rules="formRules" class="page-form mt-[20px]">
|
||||||
<el-form-item label="用户名" prop="username">
|
<el-form-item label="用户名" prop="username">
|
||||||
<el-input placeholder="请输入用户名" class="input-width" v-model="formData.username" clearable autocomplete="off" />
|
<el-input placeholder="请输入用户名" class="input-width" v-model="formData.username" clearable maxlength="50" autocomplete="off" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="密码" prop="password">
|
<el-form-item label="密码" prop="password">
|
||||||
<el-input placeholder="请输入密码" type="password" show-password class="input-width" autocomplete="new-password" v-model="formData.password" clearable />
|
<el-input placeholder="请输入密码" type="password" show-password show-word-limit maxlength="16" class="input-width" autocomplete="new-password" v-model="formData.password" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="login">登录</el-button>
|
<el-button type="primary" @click="login">登录</el-button>
|
||||||
<el-button @click="editPass()">忘记密码</el-button>
|
<el-button @click="editPass()">忘记密码</el-button>
|
||||||
<el-button @click="back()" v-if="props.isLogin">返回</el-button>
|
<el-button @click="back()" v-if="props.isLogin">返回</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="type=='register'">
|
<div v-if="type=='register'" >
|
||||||
<div class="bg-[var(--el-color-primary-light-9)] p-2 text-[14px] rounded-[6px]">
|
<div class="bg-[var(--el-color-primary-light-9)] p-2 text-[14px] rounded-[6px]">
|
||||||
<span class="">已有账号,</span>
|
<span class="">已有账号,</span>
|
||||||
<span @click="type='login'" class="cursor-pointer text-primary">去登录</span>
|
<span @click="type='login'" class="cursor-pointer text-primary">去登录</span>
|
||||||
</div>
|
</div>
|
||||||
<el-form :model="registerFormData" label-width="100px" ref="registerFormRef" :rules="registerFormRules" class="page-form mt-[20px] ml-[50px]">
|
<el-form :model="registerFormData" label-width="150px" ref="registerFormRef" :rules="registerFormRules" class="page-form mt-[20px]">
|
||||||
|
<h3 class="panel-title !text-[14px]">{{ t('基本信息') }}</h3>
|
||||||
<el-form-item label="用户名" prop="username">
|
<el-form-item label="用户名" prop="username">
|
||||||
<el-input placeholder="请输入用户名" class="input-width" autocomplete="off" v-model="registerFormData.username" clearable />
|
<el-input placeholder="请输入用户名" class="input-width" autocomplete="off" maxlength="50" show-word-limit v-model="registerFormData.username" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<div class="mb-[10px] text-[12px] ml-[100px] text-[#999] leading-[20px]">子账户用户名,仅支持6~50位英文+数字组合</div>
|
<div class="mb-[10px] text-[12px] ml-[150px] text-[#999] leading-[20px]">子账户用户名,仅支持6~50位英文+数字组合</div>
|
||||||
<el-form-item label="公司名称" prop="company">
|
<el-form-item label="公司名称" prop="company">
|
||||||
<el-input placeholder="请输入公司名称" class="input-width" v-model="registerFormData.company" clearable />
|
<el-input placeholder="请输入公司名称" class="input-width" maxlength="50" show-word-limit v-model="registerFormData.company" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="手机号" prop="mobile">
|
<el-form-item label="手机号" prop="mobile">
|
||||||
<el-input placeholder="请输入手机号" class="input-width" maxlength="11" show-word-limit v-model="registerFormData.mobile" clearable />
|
<el-input placeholder="请输入手机号" class="input-width" maxlength="11" show-word-limit v-model="registerFormData.mobile" clearable />
|
||||||
@ -51,21 +51,66 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="初始密码" prop="password">
|
<el-form-item label="初始密码" prop="password">
|
||||||
<el-input placeholder="请输入初始密码" type="password" autocomplete="new-password" show-password class="input-width" v-model="registerFormData.password" clearable />
|
<el-input placeholder="请输入初始密码" type="password" autocomplete="new-password" maxlength="16" show-password class="input-width" v-model="registerFormData.password" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<div class="mb-[10px] text-[12px] ml-[150px] text-[#999] leading-[20px]">密码由数字、大小写字母组成,密码长度8-16位</div>
|
||||||
|
<el-form-item :label="t('默认签名')" prop="signature">
|
||||||
|
<el-input v-model="registerFormData.signature" placeholder="请输入默认签名" class="input-width" maxlength="20" show-word-limit clearable />
|
||||||
|
</el-form-item>
|
||||||
|
<div class="ml-[150px] text-[12px] text-[#999] leading-[20px]">必须由【】包裹,例如:【test】</div>
|
||||||
|
<div class="my-[5px] ml-[150px] text-[12px] text-[#999] leading-[20px]">字数要求在2-20个字符,不能使用空格和特殊符号“ - + = * & % # @ ~等;</div>
|
||||||
<el-form-item label="备注" prop="remark">
|
<el-form-item label="备注" prop="remark">
|
||||||
<el-input placeholder="请输入备注" class="input-width" v-model="registerFormData.remark" clearable />
|
<el-input placeholder="请输入备注" class="input-width" type="textarea" maxlength="50" show-word-limit v-model="registerFormData.remark" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<h3 class="panel-title !text-[14px">{{ t('实名信息') }}</h3>
|
||||||
<el-button type="primary" @click="register">注册</el-button>
|
<el-form-item :label="t('短信示例内容')" prop="contentExample">
|
||||||
|
<el-input v-model="registerFormData.contentExample" placeholder="请输入短信示例内容" clearable maxlength="50" show-word-limit class="input-width" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('企业名称')" prop="companyName">
|
||||||
|
<el-input v-model="registerFormData.companyName" placeholder="请输入企业名称" clearable maxlength="20" show-word-limit class="input-width" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('社会统一信用代码')" prop="creditCode">
|
||||||
|
<el-input v-model="registerFormData.creditCode" placeholder="请输入社会统一信用代码" clearable maxlength="20" show-word-limit class="input-width" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('法人姓名')" prop="legalPerson">
|
||||||
|
<el-input v-model="registerFormData.legalPerson" placeholder="请输入法人姓名" clearable maxlength="20" show-word-limit class="input-width" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('经办人姓名')" prop="principalName">
|
||||||
|
<el-input v-model="registerFormData.principalName" placeholder="请输入经办人姓名" clearable maxlength="20" show-word-limit class="input-width" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('经办人手机号')" prop="principalMobile">
|
||||||
|
<el-input v-model="registerFormData.principalMobile" placeholder="请输入经办人手机号" clearable maxlength="20" show-word-limit class="input-width" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('经办人身份证')" prop="principalIdCard">
|
||||||
|
<el-input v-model="registerFormData.principalIdCard" placeholder="请输入经办人身份证" clearable maxlength="18" show-word-limit class="input-width" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('签名来源')">
|
||||||
|
<el-radio-group v-model="registerFormData.signSource" >
|
||||||
|
<el-radio v-for="item in signConfig.signSourceList" :key="item.type" :label="item.type" >{{item.name}}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('签名类型')">
|
||||||
|
<el-radio-group v-model="registerFormData.signType">
|
||||||
|
<el-radio v-for="item in signConfig.signTypeList" :key="item.type" :label="item.type" >{{item.name}}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('上传图片')" prop="imgUrl">
|
||||||
|
<upload-image v-model="registerFormData.imgUrl" :limit="1" />
|
||||||
|
</el-form-item>
|
||||||
|
<div class="ml-[150px] text-[12px] text-[#999] leading-[20px]">当签名来源为商标、APP、小程序、事业单位简称或企业名称简称时,需必填此字段</div>
|
||||||
|
<div class="my-[5px] ml-[150px] text-[12px] text-[#999] leading-[20px]">当签名来源为事业单位全称或企业名称全称时,选填此字段。</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
<div class="fixed-footer-wrap">
|
||||||
|
<div class="fixed-footer">
|
||||||
|
<el-button type="primary" @click="register">注册</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="type=='password'">
|
<div v-if="type=='password'">
|
||||||
<div class="bg-[var(--el-color-primary-light-9)] p-2 text-[14px] rounded-[6px]">
|
<div class="bg-[var(--el-color-primary-light-9)] p-2 text-[14px] rounded-[6px]">
|
||||||
<span class="text-primary">忘记密码,快去修改</span>
|
<span class="text-primary">忘记密码,快去修改</span>
|
||||||
</div>
|
</div>
|
||||||
<el-form :model="changeFormData" label-width="100px" ref="changeFormRef" :rules="changeFormRules" class="page-form mt-[20px] ml-[50px]">
|
<el-form :model="changeFormData" label-width="150px" ref="changeFormRef" :rules="changeFormRules" class="page-form mt-[20px]">
|
||||||
<el-form-item label="手机号" prop="mobile">
|
<el-form-item label="手机号" prop="mobile">
|
||||||
<el-input placeholder="请输入手机号" class="input-width" maxlength="11" show-word-limit v-model="changeFormData.mobile" clearable />
|
<el-input placeholder="请输入手机号" class="input-width" maxlength="11" show-word-limit v-model="changeFormData.mobile" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -91,19 +136,19 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref ,computed } from 'vue'
|
import { ref ,computed,reactive} from 'vue'
|
||||||
import { loginAccount,getSmsCaptcha,getSmsSend,resetPassword,registerAccount } from '@/app/api/notice'
|
import { loginAccount,getSmsCaptcha,getSmsSend,resetPassword,registerAccount ,getSmsSignConfig} from '@/app/api/notice'
|
||||||
|
import { t } from "@/lang";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
info: {
|
info:{
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
},
|
},
|
||||||
isLogin: {
|
isLogin:{
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
}
|
}
|
||||||
@ -140,13 +185,27 @@ const login = async () => {
|
|||||||
emit('complete')
|
emit('complete')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
const back = () => {
|
const back = () => {
|
||||||
emit('complete')
|
emit('complete')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注册
|
// 注册
|
||||||
|
const signConfig = reactive({
|
||||||
|
signTypeList: [],
|
||||||
|
signSourceList:[]
|
||||||
|
})
|
||||||
|
const getSmsSignConfigFn = ()=> {
|
||||||
|
getSmsSignConfig().then(res => {
|
||||||
|
signConfig.signTypeList = res.data.sign_type_list
|
||||||
|
signConfig.signSourceList = res.data.sign_source_list
|
||||||
|
registerFormData.value.signSource = res.data.sign_source_list[0].type
|
||||||
|
registerFormData.value.signType = res.data.sign_type_list[0].type
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getSmsSignConfigFn()
|
||||||
const registerFormData = ref({
|
const registerFormData = ref({
|
||||||
code: '',
|
code: '',
|
||||||
key: '',
|
key: '',
|
||||||
@ -157,9 +216,19 @@ const registerFormData = ref({
|
|||||||
mobile: '',
|
mobile: '',
|
||||||
captcha_key: '',
|
captcha_key: '',
|
||||||
captcha_code: '',
|
captcha_code: '',
|
||||||
captcha_img: ''
|
captcha_img: '',
|
||||||
|
imgUrl: '',
|
||||||
|
contentExample: '',
|
||||||
|
signType: '',
|
||||||
|
signSource: '',
|
||||||
|
principalIdCard: '',
|
||||||
|
principalName: '',
|
||||||
|
principalMobile: '',
|
||||||
|
legalPerson: '',
|
||||||
|
creditCode: '',
|
||||||
|
companyName: '',
|
||||||
|
signature: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
const captchaType = ref('login')
|
const captchaType = ref('login')
|
||||||
const toRegister = async () => {
|
const toRegister = async () => {
|
||||||
captchaType.value = 'register'
|
captchaType.value = 'register'
|
||||||
@ -169,10 +238,8 @@ const toRegister = async () => {
|
|||||||
registerFormData.value.username = ''
|
registerFormData.value.username = ''
|
||||||
registerFormData.value.password = ''
|
registerFormData.value.password = ''
|
||||||
type.value = 'register'
|
type.value = 'register'
|
||||||
loading.value = false
|
|
||||||
} else {
|
|
||||||
loading.value = false
|
|
||||||
}
|
}
|
||||||
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const registerFormRef = ref()
|
const registerFormRef = ref()
|
||||||
@ -189,6 +256,11 @@ const registerFormRules = computed(() => {
|
|||||||
],
|
],
|
||||||
password: [
|
password: [
|
||||||
{ required: true, message: '请输入密码', trigger: 'blur' },
|
{ required: true, message: '请输入密码', trigger: 'blur' },
|
||||||
|
{
|
||||||
|
pattern: /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[A-Za-z\d]{8,16}$/,
|
||||||
|
message: '密码格式不正确',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
],
|
],
|
||||||
mobile: [
|
mobile: [
|
||||||
{ required: true, message: '请输入手机号', trigger: 'blur' },
|
{ required: true, message: '请输入手机号', trigger: 'blur' },
|
||||||
@ -201,36 +273,108 @@ const registerFormRules = computed(() => {
|
|||||||
],
|
],
|
||||||
company: [
|
company: [
|
||||||
{ required: true, message: '请输入公司名称', trigger: 'blur' },
|
{ required: true, message: '请输入公司名称', trigger: 'blur' },
|
||||||
]
|
],
|
||||||
}
|
signature: [
|
||||||
})
|
{ required: true, message: '请输入短信签名', trigger: 'blur' },
|
||||||
|
{
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
const singleBracketValid = /^【[^【】]*】$/.test(value);
|
||||||
|
if (!singleBracketValid) {
|
||||||
|
return callback(new Error('短信签名必须被【】包裹'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const content = value.slice(1, -1);
|
||||||
|
|
||||||
|
const lengthValid = content.length >= 2 && content.length <= 20;
|
||||||
|
if (!lengthValid) {
|
||||||
|
return callback(new Error('短信签名内容需在 2-20 个字符之间'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const invalidChars = /[\s\-+=*&%#@~;]/;
|
||||||
|
if (invalidChars.test(content)) {
|
||||||
|
return callback(new Error('短信签名不能包含空格或特殊字符 - + = * & % # @ ~ ;'));
|
||||||
|
}
|
||||||
|
|
||||||
|
callback();
|
||||||
|
},
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
principalMobile: [
|
||||||
|
{ required: true, message: '请输入经办人手机号', trigger: 'blur' },
|
||||||
|
{ validator: phoneVerify, trigger: 'blur' }
|
||||||
|
],
|
||||||
|
companyName: [
|
||||||
|
{ required: true, message: '请输入企业名称', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
contentExample: [
|
||||||
|
{ required: true, message: '请输入短信示例内容', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
creditCode: [
|
||||||
|
{ required: true, message: '请输入社会统一信用代码', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
legalPerson: [
|
||||||
|
{ required: true, message: '请输入法人姓名', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
principalName: [
|
||||||
|
{ required: true, message: '请输入经办人姓名', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
principalIdCard: [
|
||||||
|
{ required: true, message: '请输入经办人身份证', trigger: 'blur' },
|
||||||
|
{ validator: idCardVerify, trigger: 'blur' }
|
||||||
|
],
|
||||||
|
imgUrl: [
|
||||||
|
{
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
const needImage = [3, 4, 5].includes(registerFormData.value.signSource) || registerFormData.value.signType == 1;
|
||||||
|
if (needImage) {
|
||||||
|
if (!value || value.length === 0) {
|
||||||
|
callback(new Error('请上传图片'));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback(); // 不需要校验
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
});
|
||||||
|
const idCardVerify = (rule: any, value: any, callback: any) => {
|
||||||
|
if (value && !/^[1-9]\d{5}(19|20)\d{2}((0\d)|(1[0-2]))(([0-2]\d)|3[0-1])\d{3}([0-9Xx])$/.test(value)) {
|
||||||
|
callback(new Error(t('请输入正确的身份证号码')))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const phoneVerify = (rule: any, value: any, callback: any) => {
|
||||||
|
if (value && !/^1[3-9]\d{9}$/.test(value)) {
|
||||||
|
callback(new Error(t('请输入正确的手机号码')))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
const register = async () => {
|
const register = async () => {
|
||||||
await registerFormRef.value?.validate(async (valid) => {
|
await registerFormRef.value?.validate(async (valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
let params = {
|
const { captcha_key, captcha_code, captcha_img, ...params } = registerFormData.value;
|
||||||
code: registerFormData.value.code,
|
|
||||||
key: registerFormData.value.key,
|
|
||||||
remark: registerFormData.value.remark,
|
|
||||||
username: registerFormData.value.username,
|
|
||||||
password: registerFormData.value.password,
|
|
||||||
company: registerFormData.value.company,
|
|
||||||
mobile: registerFormData.value.mobile,
|
|
||||||
}
|
|
||||||
registerAccount(params).then((res) => {
|
registerAccount(params).then((res) => {
|
||||||
type.value = 'login'
|
type.value='login'
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
getSmsCaptchaFn()
|
getSmsCaptchaFn()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重置密码
|
// 重置密码
|
||||||
const changeFormRef = ref()
|
const changeFormRef = ref()
|
||||||
const changeFormData = ref({
|
const changeFormData = ref({
|
||||||
mobile: '',
|
mobile: '',
|
||||||
captcha_key: '',
|
captcha_key : '',
|
||||||
captcha_code: '',
|
captcha_code: '',
|
||||||
captcha_img: '',
|
captcha_img: '',
|
||||||
code: '',
|
code: '',
|
||||||
@ -261,8 +405,8 @@ const getSmsSendFn = () => {
|
|||||||
if (countdown.value > 0 || sending.value) return; // 正在倒计时或发送中,直接返回
|
if (countdown.value > 0 || sending.value) return; // 正在倒计时或发送中,直接返回
|
||||||
if (type.value === 'register') {
|
if (type.value === 'register') {
|
||||||
registerFormRef.value.validateField(['mobile', 'captcha_code'], (valid) => {
|
registerFormRef.value.validateField(['mobile', 'captcha_code'], (valid) => {
|
||||||
if (!valid) return;
|
if (!valid) return
|
||||||
sending.value = true; // 标记为发送中
|
sending.value = true // 标记为发送中
|
||||||
const params = {
|
const params = {
|
||||||
mobile: registerFormData.value.mobile,
|
mobile: registerFormData.value.mobile,
|
||||||
captcha_key: registerFormData.value.captcha_key,
|
captcha_key: registerFormData.value.captcha_key,
|
||||||
@ -276,13 +420,12 @@ const getSmsSendFn = () => {
|
|||||||
sending.value = false;
|
sending.value = false;
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
sending.value = false; // 无论成功失败都重置发送状态
|
sending.value = false; // 无论成功失败都重置发送状态
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
} else if (type.value === 'password') {
|
} else if (type.value === 'password') {
|
||||||
changeFormRef.value.validateField(['mobile', 'captcha_code'], (valid) => {
|
changeFormRef.value.validateField(['mobile', 'captcha_code'], (valid) => {
|
||||||
if (!valid) return;
|
if (!valid) return
|
||||||
sending.value = true; // 标记为发送中
|
sending.value = true // 标记为发送中
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
mobile: changeFormData.value.mobile,
|
mobile: changeFormData.value.mobile,
|
||||||
@ -337,12 +480,11 @@ const editPass = async () => {
|
|||||||
captchaType.value = 'password'
|
captchaType.value = 'password'
|
||||||
const success = await getSmsCaptchaFn()
|
const success = await getSmsCaptchaFn()
|
||||||
if (success) {
|
if (success) {
|
||||||
loading.value = false
|
|
||||||
type.value = 'password'
|
type.value = 'password'
|
||||||
} else {
|
|
||||||
loading.value = false
|
|
||||||
}
|
}
|
||||||
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const reset = async () => {
|
const reset = async () => {
|
||||||
await changeFormRef.value?.validate(async (valid) => {
|
await changeFormRef.value?.validate(async (valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
@ -351,21 +493,21 @@ const reset = async () => {
|
|||||||
code: changeFormData.value.code,
|
code: changeFormData.value.code,
|
||||||
mobile: changeFormData.value.mobile
|
mobile: changeFormData.value.mobile
|
||||||
}
|
}
|
||||||
resetPassword(props.info.username,{...params}).then((res) => {
|
resetPassword(props.info.username, { ...params }).then((res) => {
|
||||||
let newPassword = res.data.password
|
let newPassword = res.data.password
|
||||||
ElMessageBox.confirm(`新密码为:${newPassword}`, '请保存好新密码', {
|
ElMessageBox.confirm(`新密码为:${ newPassword }`, '请保存好新密码', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
showCancelButton: false,
|
showCancelButton: false,
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
type.value='login'
|
type.value = 'login'
|
||||||
emit('complete')
|
emit('complete')
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
type.value='login'
|
type.value = 'login'
|
||||||
emit('complete')
|
emit('complete')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-card class="box-card !border-none p-[10px]" shadow="never">
|
<el-card class="box-card !border-none p-[10px]" shadow="never" v-loading="loadingPackage">
|
||||||
<div class="panel-title">选择套餐</div>
|
<div class="panel-title">选择套餐</div>
|
||||||
<div class="flex flex-wrap mb-[30px]">
|
<div class="flex flex-wrap mb-[30px]">
|
||||||
<div v-for="(item,index) in smsPackages" :key="index" :span="4">
|
<div v-for="(item,index) in smsPackages" :key="index" :span="4">
|
||||||
<div class="package-card mr-[10px]" :class="{ active: selectedPackage?.id === item.id }" @click="selectPackage(item)">
|
<div class="package-card mr-[10px] mb-[10px]" :class="{ active: selectedPackage?.id === item.id }" @click="selectPackage(item)">
|
||||||
<div class="text-[14px] mb-1">{{ item.package_name }}</div>
|
<div class="text-[14px] mb-1 using-hidden">{{ item.package_name }}</div>
|
||||||
<div class="text-[24px] text-primary ">{{ item.sms_num }}条</div>
|
<div class="text-[24px] text-primary ">{{ item.sms_num }}条</div>
|
||||||
<div class="flex mt-2 text-[14px] justify-center items-center ">
|
<div class="flex mt-2 text-[14px] justify-center items-center ">
|
||||||
<div>¥{{ item.price }}</div>
|
<div>¥{{ item.price }}</div>
|
||||||
@ -32,28 +32,37 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from 'vue'
|
import { ref ,watch} from 'vue'
|
||||||
import { getSmsPackagesList, smsOrderCreate, getOrderPayInfo, getOrderPayStatus, calculateOrderPay } from '@/app/api/notice'
|
import { getSmsPackagesList, smsOrderCreate, getOrderPayInfo, getOrderPayStatus, calculateOrderPay } from '@/app/api/notice'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
username: {
|
username: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
|
},
|
||||||
|
isRecharge: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['back', 'complete'])
|
const emit = defineEmits(['back', 'complete'])
|
||||||
|
|
||||||
const smsPackages = ref<any[]>([])
|
const smsPackages = ref<any[]>([])
|
||||||
const selectedPackage = ref<any | null>(null)
|
const selectedPackage = ref<any | null>(null)
|
||||||
const payMethod = ref('alipay')
|
const payMethod = ref('alipay')
|
||||||
|
const loadingPackage = ref(false)
|
||||||
const totalAmount = ref(0)
|
const totalAmount = ref(0)
|
||||||
const getSmsPackagesListFn = () => {
|
const getSmsPackagesListFn = () => {
|
||||||
|
loadingPackage.value = true
|
||||||
getSmsPackagesList().then(res => {
|
getSmsPackagesList().then(res => {
|
||||||
smsPackages.value = res.data.data
|
smsPackages.value = res.data.data
|
||||||
|
loadingPackage.value = false
|
||||||
if (smsPackages.value.length > 0 && props.username) {
|
if (smsPackages.value.length > 0 && props.username) {
|
||||||
selectPackage(smsPackages.value[0])
|
selectPackage(smsPackages.value[0])
|
||||||
}
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
loadingPackage.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +115,13 @@ const goBack = () => {
|
|||||||
emit('back')
|
emit('back')
|
||||||
}
|
}
|
||||||
|
|
||||||
getSmsPackagesListFn()
|
const showRecharge = ref(false);
|
||||||
|
watch(() => props.isRecharge, (newVal) => {
|
||||||
|
showRecharge.value = newVal;
|
||||||
|
if (newVal) {
|
||||||
|
getSmsPackagesListFn();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -86,6 +86,7 @@
|
|||||||
<el-form-item :label="t('短信签名')" prop="signature">
|
<el-form-item :label="t('短信签名')" prop="signature">
|
||||||
<el-input v-model="formData.signature" placeholder="请输入短信签名" class="input-width" maxlength="20" show-word-limit clearable />
|
<el-input v-model="formData.signature" placeholder="请输入短信签名" class="input-width" maxlength="20" show-word-limit clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<div class="ml-[150px] text-[12px] text-[#999] leading-[20px]">必须由【】包裹,例如:【test】</div>
|
||||||
<div class="my-[5px] ml-[150px] text-[12px] text-[#999] leading-[20px]">字数要求在2-20个字符,不能使用空格和特殊符号“ - + = * & % # @ ~等;</div>
|
<div class="my-[5px] ml-[150px] text-[12px] text-[#999] leading-[20px]">字数要求在2-20个字符,不能使用空格和特殊符号“ - + = * & % # @ ~等;</div>
|
||||||
<el-form-item :label="t('短信示例内容')" prop="contentExample">
|
<el-form-item :label="t('短信示例内容')" prop="contentExample">
|
||||||
<el-input v-model="formData.contentExample" placeholder="请输入短信示例内容" clearable maxlength="50" show-word-limit class="input-width" />
|
<el-input v-model="formData.contentExample" placeholder="请输入短信示例内容" clearable maxlength="50" show-word-limit class="input-width" />
|
||||||
@ -102,22 +103,27 @@
|
|||||||
<el-form-item :label="t('经办人姓名')" prop="principalName">
|
<el-form-item :label="t('经办人姓名')" prop="principalName">
|
||||||
<el-input v-model="formData.principalName" placeholder="请输入经办人姓名" clearable maxlength="20" show-word-limit class="input-width" />
|
<el-input v-model="formData.principalName" placeholder="请输入经办人姓名" clearable maxlength="20" show-word-limit class="input-width" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('经办人手机号')" prop="principalMobile">
|
||||||
|
<el-input v-model="formData.principalMobile" placeholder="请输入经办人手机号" clearable maxlength="20" show-word-limit class="input-width" />
|
||||||
|
</el-form-item>
|
||||||
<el-form-item :label="t('经办人身份证')" prop="principalIdCard">
|
<el-form-item :label="t('经办人身份证')" prop="principalIdCard">
|
||||||
<el-input v-model="formData.principalIdCard" placeholder="请输入经办人身份证" clearable maxlength="18" show-word-limit class="input-width" />
|
<el-input v-model="formData.principalIdCard" placeholder="请输入经办人身份证" clearable maxlength="18" show-word-limit class="input-width" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('签名来源')">
|
<el-form-item :label="t('签名来源')">
|
||||||
<el-radio-group v-model="formData.signSource" >
|
<el-radio-group v-model="formData.signSource" >
|
||||||
<el-radio v-for="item in signCofig.signsourceList" :key="item.type" :label="item.type" >{{item.name}}</el-radio>
|
<el-radio v-for="item in signConfig.signSourceList" :key="item.type" :label="item.type" >{{item.name}}</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('签名类型')">
|
<el-form-item :label="t('签名类型')">
|
||||||
<el-radio-group v-model="formData.signType">
|
<el-radio-group v-model="formData.signType">
|
||||||
<el-radio v-for="item in signCofig.signTypeList" :key="item.type" :label="item.type" >{{item.name}}</el-radio>
|
<el-radio v-for="item in signConfig.signTypeList" :key="item.type" :label="item.type" >{{item.name}}</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('上传图片')" prop="imgUrl">
|
<el-form-item :label="t('上传图片')" prop="imgUrl">
|
||||||
<upload-image v-model="formData.imgUrl" :limit="1" />
|
<upload-image v-model="formData.imgUrl" :limit="1" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<div class="ml-[150px] text-[12px] text-[#999] leading-[20px]">当签名来源为商标、APP、小程序、事业单位简称或企业名称简称时,需必填此字段</div>
|
||||||
|
<div class="my-[5px] ml-[150px] text-[12px] text-[#999] leading-[20px]">当签名来源为事业单位全称或企业名称全称时,选填此字段。</div>
|
||||||
<el-form-item :label="t('是否默认')">
|
<el-form-item :label="t('是否默认')">
|
||||||
<el-radio-group v-model="formData.defaultSign" >
|
<el-radio-group v-model="formData.defaultSign" >
|
||||||
<el-radio :label="1">是</el-radio>
|
<el-radio :label="1">是</el-radio>
|
||||||
@ -155,6 +161,7 @@ const initialFormData = {
|
|||||||
signSource: '',
|
signSource: '',
|
||||||
principalIdCard: '',
|
principalIdCard: '',
|
||||||
principalName: '',
|
principalName: '',
|
||||||
|
principalMobile: '',
|
||||||
legalPerson: '',
|
legalPerson: '',
|
||||||
creditCode: '',
|
creditCode: '',
|
||||||
companyName: '',
|
companyName: '',
|
||||||
@ -162,15 +169,14 @@ const initialFormData = {
|
|||||||
}
|
}
|
||||||
const formData = reactive({ ...initialFormData })
|
const formData = reactive({ ...initialFormData })
|
||||||
|
|
||||||
|
const signConfig = reactive({
|
||||||
const signCofig = reactive({
|
|
||||||
signTypeList: [],
|
signTypeList: [],
|
||||||
signsourceList:[]
|
signSourceList:[]
|
||||||
})
|
})
|
||||||
const getSmsSignConfigFn = ()=> {
|
const getSmsSignConfigFn = ()=> {
|
||||||
getSmsSignConfig().then(res => {
|
getSmsSignConfig().then(res => {
|
||||||
signCofig.signTypeList = res.data.sign_type_list
|
signConfig.signTypeList = res.data.sign_type_list
|
||||||
signCofig.signsourceList = res.data.sign_source_list
|
signConfig.signSourceList = res.data.sign_source_list
|
||||||
formData.signSource = res.data.sign_source_list[0].type
|
formData.signSource = res.data.sign_source_list[0].type
|
||||||
formData.signType = res.data.sign_type_list[0].type
|
formData.signType = res.data.sign_type_list[0].type
|
||||||
})
|
})
|
||||||
@ -185,21 +191,32 @@ const formRules = computed(() => {
|
|||||||
{ required: true, message: '请输入短信签名', trigger: 'blur' },
|
{ required: true, message: '请输入短信签名', trigger: 'blur' },
|
||||||
{
|
{
|
||||||
validator: (rule, value, callback) => {
|
validator: (rule, value, callback) => {
|
||||||
const lengthValid = value.length >= 2 && value.length <= 20;
|
const singleBracketValid = /^【[^【】]*】$/.test(value);
|
||||||
const invalidChars = /[\s\-+=*&%#@~;]/;
|
if (!singleBracketValid) {
|
||||||
|
return callback(new Error('短信签名必须被【】包裹'));
|
||||||
if (!lengthValid) {
|
|
||||||
callback(new Error('短信签名字数需在 2-20 个字符之间'));
|
|
||||||
} else if (invalidChars.test(value)) {
|
|
||||||
callback(new Error('短信签名不能包含空格或特殊字符 - + = * & % # @ ~ ;'));
|
|
||||||
} else {
|
|
||||||
callback();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const content = value.slice(1, -1);
|
||||||
|
|
||||||
|
const lengthValid = content.length >= 2 && content.length <= 20;
|
||||||
|
if (!lengthValid) {
|
||||||
|
return callback(new Error('短信签名内容需在 2-20 个字符之间'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const invalidChars = /[\s\-+=*&%#@~;]/;
|
||||||
|
if (invalidChars.test(content)) {
|
||||||
|
return callback(new Error('短信签名不能包含空格或特殊字符 - + = * & % # @ ~ ;'));
|
||||||
|
}
|
||||||
|
|
||||||
|
callback();
|
||||||
},
|
},
|
||||||
trigger: 'blur'
|
trigger: 'blur'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
principalMobile: [
|
||||||
|
{ required: true, message: '请输入经办人手机号', trigger: 'blur' },
|
||||||
|
{ validator: phoneVerify, trigger: 'blur' }
|
||||||
|
],
|
||||||
companyName: [
|
companyName: [
|
||||||
{ required: true, message: '请输入企业名称', trigger: 'blur' },
|
{ required: true, message: '请输入企业名称', trigger: 'blur' },
|
||||||
],
|
],
|
||||||
@ -248,6 +265,14 @@ const idCardVerify = (rule: any, value: any, callback: any) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const phoneVerify = (rule: any, value: any, callback: any) => {
|
||||||
|
if (value && !/^1[3-9]\d{9}$/.test(value)) {
|
||||||
|
callback(new Error(t('请输入正确的手机号码')))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const onSave = async () => {
|
const onSave = async () => {
|
||||||
await formRef.value?.validate(async (valid) => {
|
await formRef.value?.validate(async (valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
@ -294,8 +319,8 @@ const loadSignList = () => {
|
|||||||
|
|
||||||
const addEvent = () => {
|
const addEvent = () => {
|
||||||
Object.assign(formData, initialFormData)
|
Object.assign(formData, initialFormData)
|
||||||
formData.signSource = signCofig.signsourceList[0].type
|
formData.signSource = signConfig.signSourceList[0].type
|
||||||
formData.signType = signCofig.signTypeList[0].type
|
formData.signType = signConfig.signTypeList[0].type
|
||||||
visibleAdd.value = true
|
visibleAdd.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,14 +396,13 @@ const batchDeleteEvent = () => {
|
|||||||
signatures.push(item.sign)
|
signatures.push(item.sign)
|
||||||
})
|
})
|
||||||
|
|
||||||
deleteSign(props.username,{
|
deleteSign(props.username, {
|
||||||
signatures: signatures
|
signatures
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
tableData.loading = true;
|
tableData.loading = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
loadSignList()
|
loadSignList()
|
||||||
},1000)
|
}, 1000)
|
||||||
// loadSignList()
|
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
<el-form-item :label="t('状态')" prop="status">
|
<el-form-item :label="t('状态')" prop="status">
|
||||||
<el-select v-model="tableData.searchParam.status" :placeholder="t('请选择状态')">
|
<el-select v-model="tableData.searchParam.status" :placeholder="t('请选择状态')">
|
||||||
<el-option :label="t('全部')" :value="''"></el-option>
|
<el-option :label="t('全部')" :value="''"></el-option>
|
||||||
<el-option v-for="(statusText, statusValue) in template_status_list" :key="statusValue" :label="statusText" :value="statusValue"></el-option>
|
<el-option v-for="(statusText, statusValue) in template_status_list" :key="statusValue" :label="statusText" :value="statusValue"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
@ -39,12 +39,13 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="audit_info" :label="t('审核状态')" min-width="130" >
|
<el-table-column prop="audit_info" :label="t('审核状态')" min-width="130" >
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div>{{ row.audit_info?.audit_status_name }}</div>
|
<div>{{ row.audit_info?.audit_status_name }} <span v-if="row.audit_info?.error_status_name" class="text-red-600">({{row.audit_info?.error_status_name}})</span> </div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column :label="t('operation')" fixed="right" align="right" min-width="120">
|
<el-table-column :label="t('operation')" fixed="right" align="right" min-width="120">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button type="primary" link @click="reportEvent(row)">{{ row.audit_info.audit_status!=1 && row.audit_info.audit_status!=2? t("报备") : t("修改") }}</el-button>
|
<el-button type="primary" v-if="row.audit_info.audit_status!=2" link @click="reportEvent(row)">{{ row.audit_info.audit_status!=1 && row.audit_info.audit_status!=2? t("报备") : t("修改") }}</el-button>
|
||||||
|
<el-button type="primary" v-if="row.audit_info.audit_status==2" link @click="clearEvent(row)">{{ t('清除报备信息') }}</el-button>
|
||||||
<el-button type="primary" link @click="editEvent(row)">{{ t("详情") }}</el-button>
|
<el-button type="primary" link @click="editEvent(row)">{{ t("详情") }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@ -98,8 +99,8 @@
|
|||||||
<div v-for="(label, key) in detail.variable" :key="key" class="mb-2 flex items-center">
|
<div v-for="(label, key) in detail.variable" :key="key" class="mb-2 flex items-center">
|
||||||
<div class="flex flex-1 items-center">
|
<div class="flex flex-1 items-center">
|
||||||
<div class="w-32 mr-1 ">{{ label }}</div>
|
<div class="w-32 mr-1 ">{{ label }}</div>
|
||||||
<el-select v-model="reportData.params_json[key]" placeholder="请选择类型" class="flex-1" filterable clearable>
|
<el-select v-model="reportData.params_json[key]" placeholder="请选择类型" class="flex-1" filterable clearable :disabled="isMarketingWithVariable">
|
||||||
<el-option v-for="item in template_params_type_list" :key="item.type" :label="item.name + '(' + item.desc + ')'" :value="item.type"/>
|
<el-option v-for="item in filteredParamTypes" :key="item.type" :label="item.name + '(' + item.desc + ')'" :value="item.type"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -109,7 +110,7 @@
|
|||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button @click="visibleReport = false">{{ t("cancel") }}</el-button>
|
<el-button @click="visibleReport = false">{{ t("cancel") }}</el-button>
|
||||||
<el-button type="primary" @click="reportTemplateFn()">{{ t("confirm") }}</el-button>
|
<el-button type="primary" @click="reportTemplateFn()" :disabled="isMarketingWithVariable">{{ t("confirm") }}</el-button>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@ -143,7 +144,7 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref ,computed,reactive,onMounted,watch} from 'vue'
|
import { ref ,computed,reactive,onMounted,watch} from 'vue'
|
||||||
import { getTemplateList,getTemplateReportConfig,reportTemplate,templateSync ,getreportTemplateInfo} from '@/app/api/notice'
|
import { getTemplateList,getTemplateReportConfig,reportTemplate,templateSync ,getreportTemplateInfo,clearTemplate} from '@/app/api/notice'
|
||||||
import { t } from "@/lang";
|
import { t } from "@/lang";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -171,20 +172,19 @@ const tableData = reactive({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
const filterData = () => {
|
const filterData = () => {
|
||||||
const { template_id, name, status } = tableData.searchParam;
|
const { template_id, name, status } = tableData.searchParam;
|
||||||
return tableData.allData.filter(item => {
|
return tableData.allData.filter(item => {
|
||||||
const matchId = !template_id || String(item.template_id || '').includes(template_id);
|
const matchId = !template_id || String(item.template_id || '').includes(template_id);
|
||||||
const matchName = !name || String(item.name || '').includes(name);
|
const matchName = !name || String(item.name || '').includes(name);
|
||||||
const matchStatus = !status || item.audit_info.audit_status == status;
|
const matchStatus = !status || item.audit_info.audit_status == status;
|
||||||
return matchId && matchName && matchStatus;
|
return matchId && matchName && matchStatus;
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
watch(() => [tableData.limit, tableData.page], () => {
|
watch(() => [tableData.limit, tableData.page], () => {
|
||||||
pagedDataChange()
|
pagedDataChange()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
// 获取列表
|
// 获取列表
|
||||||
const loadSmsTemplateList = () => {
|
const loadSmsTemplateList = () => {
|
||||||
tableData.loading = true;
|
tableData.loading = true;
|
||||||
@ -250,6 +250,19 @@ const editEvent = (row:any) => {
|
|||||||
detail.value = row
|
detail.value = row
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 清除报备
|
||||||
|
const clearEvent = (row:any) => {
|
||||||
|
ElMessageBox.confirm(t('确定要清除报备信息吗'), t('提示'), {
|
||||||
|
confirmButtonText: t('确定'),
|
||||||
|
cancelButtonText: t('取消'),
|
||||||
|
type: 'warning',
|
||||||
|
}).then(() => {
|
||||||
|
clearTemplate(props.username, row.template_id).then(() => {
|
||||||
|
loadSmsTemplateList()
|
||||||
|
})
|
||||||
|
}).catch(() => {
|
||||||
|
})
|
||||||
|
}
|
||||||
// 报备
|
// 报备
|
||||||
const template_params_type_list = ref({})
|
const template_params_type_list = ref({})
|
||||||
const template_type_list = ref({})
|
const template_type_list = ref({})
|
||||||
@ -269,15 +282,33 @@ const getTemplateReportConfigFn = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getTemplateReportConfigFn()
|
getTemplateReportConfigFn()
|
||||||
|
|
||||||
|
const filteredParamTypes = computed(() => {
|
||||||
|
if (reportData.value.template_type === 1) {
|
||||||
|
return template_params_type_list.value.filter(item => item.type === 'valid_code')
|
||||||
|
} else {
|
||||||
|
return template_params_type_list.value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const isMarketingWithVariable = computed(() => {
|
||||||
|
return reportData.value.template_type === 3 && detail.value.variable && Object.keys(detail.value.variable).length > 0
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(isMarketingWithVariable, (val) => {
|
||||||
|
if (val) {
|
||||||
|
ElMessage.error('营销推广类型不支持变量');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const reportLoading = ref(false)
|
const reportLoading = ref(false)
|
||||||
const reportEvent = (row:any) => {
|
const reportEvent = (row:any) => {
|
||||||
reportLoading.value = true
|
reportLoading.value = true
|
||||||
let signature = props.signature
|
let signature = props.signature
|
||||||
if(!signature){
|
if (!signature) {
|
||||||
ElMessage.error('请先配置签名')
|
ElMessage.error('请先配置签名')
|
||||||
return
|
return
|
||||||
}else{
|
} else {
|
||||||
if(row.template_id){
|
if (row.template_id) {
|
||||||
visibleReport.value = true;
|
visibleReport.value = true;
|
||||||
detail.value = row;
|
detail.value = row;
|
||||||
getreportTemplateInfo('niuyun', props.username, { template_key: row.key }).then((res) => {
|
getreportTemplateInfo('niuyun', props.username, { template_key: row.key }).then((res) => {
|
||||||
@ -292,7 +323,7 @@ const reportEvent = (row:any) => {
|
|||||||
}
|
}
|
||||||
reportLoading.value = false;
|
reportLoading.value = false;
|
||||||
});
|
});
|
||||||
}else{
|
} else {
|
||||||
visibleReport.value = true
|
visibleReport.value = true
|
||||||
reportLoading.value = false
|
reportLoading.value = false
|
||||||
detail.value = row
|
detail.value = row
|
||||||
@ -300,9 +331,10 @@ const reportEvent = (row:any) => {
|
|||||||
reportData.value.template_key = detail.value.key
|
reportData.value.template_key = detail.value.key
|
||||||
reportData.value.params_json = {}
|
reportData.value.params_json = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const reportTemplateFn = () => {
|
const reportTemplateFn = () => {
|
||||||
if (!detail.value.sms) {
|
if (!detail.value.sms) {
|
||||||
ElMessage.error('请先配置模版内容')
|
ElMessage.error('请先配置模版内容')
|
||||||
|
|||||||
@ -108,7 +108,6 @@ const confirm = async (formEl: FormInstance | undefined) => {
|
|||||||
emit('complete')
|
emit('complete')
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
// showDialog.value = false
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -68,7 +68,6 @@ const confirm = async (formEl: FormInstance | undefined) => {
|
|||||||
emit('complete')
|
emit('complete')
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
// showDialog.value = false
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -107,7 +107,6 @@ const confirm = async (formEl: FormInstance | undefined) => {
|
|||||||
emit('complete')
|
emit('complete')
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
// showDialog.value = false
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
<el-form-item :label="t('companyName')" prop="company_name">
|
<el-form-item :label="t('companyName')" prop="company_name">
|
||||||
<el-input v-model.trim="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')" prop="copyright_link">
|
||||||
<el-input v-model.trim="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')" >
|
||||||
@ -81,8 +81,22 @@ const formRef = ref<FormInstance>()
|
|||||||
|
|
||||||
// 表单验证规则
|
// 表单验证规则
|
||||||
const formRules = reactive<FormRules>({
|
const formRules = reactive<FormRules>({
|
||||||
site_name: [
|
copyright_link: [
|
||||||
{ required: true, message: t('siteNamePlaceholder'), trigger: 'blur' }
|
{
|
||||||
|
validator(rule, value, callback) {
|
||||||
|
// 允许为空,空值直接通过验证
|
||||||
|
if (!value) return callback();
|
||||||
|
|
||||||
|
// 非空时检查是否包含 http/https
|
||||||
|
const reg = /^.*?(http|https).*?$/i;
|
||||||
|
if (!reg.test(value)) {
|
||||||
|
callback(new Error('链接必须包含 http 或 https'));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,17 @@
|
|||||||
<el-form-item >
|
<el-form-item >
|
||||||
<div class="text-lg">{{ memberNo }}</div>
|
<div class="text-lg">{{ memberNo }}</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
<h3 class="panel-title">{{ t('diyForm') }}</h3>
|
||||||
|
<el-form-item :label="t('personalForm')">
|
||||||
|
<el-select v-model="formData.form_id" :placeholder="t('diyFormPlaceholder')" clearable>
|
||||||
|
<el-option v-for="item in diyFormOptions" :key="item.form_id" :label="item.page_title" :value="item.form_id" />
|
||||||
|
</el-select>
|
||||||
|
<div class="ml-[10px]">
|
||||||
|
<span class="cursor-pointer text-primary mr-[10px]" @click="refreshDiyForm(true)">{{ t('refresh') }}</span>
|
||||||
|
<span class="cursor-pointer text-primary" @click="toDiyFormEvent">{{ t('addDiyForm') }}</span>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
@ -32,7 +43,10 @@ import { t } from '@/lang'
|
|||||||
import { getMemberConfig, setMemberConfig } from '@/app/api/member'
|
import { getMemberConfig, setMemberConfig } from '@/app/api/member'
|
||||||
import { FormInstance, FormRules } from 'element-plus'
|
import { FormInstance, FormRules } from 'element-plus'
|
||||||
import { filterNumber } from '@/utils/common'
|
import { filterNumber } from '@/utils/common'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { getDiyFormList } from '@/app/api/diy_form'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const ruleFormRef = ref<FormInstance>({})
|
const ruleFormRef = ref<FormInstance>({})
|
||||||
const memberNo = ref('')
|
const memberNo = ref('')
|
||||||
@ -68,7 +82,8 @@ const formRules = reactive<FormRules>({
|
|||||||
|
|
||||||
const formData = reactive<Record<string, number | string>>({
|
const formData = reactive<Record<string, number | string>>({
|
||||||
prefix: '',
|
prefix: '',
|
||||||
length: 10
|
length: 10,
|
||||||
|
form_id: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
const setFormData = async () => {
|
const setFormData = async () => {
|
||||||
@ -92,6 +107,39 @@ const getMemberNo = async (formEl: FormInstance | undefined) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** ***************** 万能表单-start *************************/
|
||||||
|
// 万能表单列表下拉框
|
||||||
|
const diyFormOptions = reactive([])
|
||||||
|
// 跳转到万能表单列表,添加表单
|
||||||
|
const toDiyFormEvent = () => {
|
||||||
|
const url = router.resolve({
|
||||||
|
path: '/diy_form/list'
|
||||||
|
})
|
||||||
|
window.open(url.href)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新万能表单
|
||||||
|
const refreshDiyForm = (bool = false) => {
|
||||||
|
getDiyFormList({
|
||||||
|
type: 'DIY_FORM_MEMBER_INFO',
|
||||||
|
status: 1
|
||||||
|
}).then((res) => {
|
||||||
|
const data = res.data
|
||||||
|
if (data) {
|
||||||
|
diyFormOptions.splice(0, diyFormOptions.length, ...data)
|
||||||
|
if (bool) {
|
||||||
|
ElMessage({
|
||||||
|
message: t('refreshSuccess'),
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshDiyForm()
|
||||||
|
/** *****************万能表单-end *************************/
|
||||||
|
|
||||||
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) => {
|
||||||
|
|||||||
@ -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="recordsTableData.searchParam" ref="searchFormRef">
|
<el-form :inline="true" :model="recordsTableData.searchParam" ref="searchFormRef">
|
||||||
<el-form-item :label="t('searchReceiver')" prop="receiver">
|
<el-form-item :label="t('searchReceiver')" prop="receiver">
|
||||||
<el-input v-model.trim="recordsTableData.searchParam.receiver" :placeholder="t('receiverPlaceholder')" />
|
<el-input class="!w-[200px]" v-model.trim="recordsTableData.searchParam.receiver" :placeholder="t('receiverPlaceholder')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item :label="t('noticeKey')" prop="key">
|
<el-form-item :label="t('noticeKey')" prop="key">
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
<div class="flex justify-between items-center p-[20px]">
|
<div class="flex justify-between items-center p-[20px]">
|
||||||
<span class="text-page-title">{{ pageName }}</span>
|
<span class="text-page-title">{{ pageName }}</span>
|
||||||
</div>
|
</div>
|
||||||
<el-tabs v-model="activeName" class="">
|
<el-tabs v-model="activeName">
|
||||||
<el-tab-pane :label="t('小程序同步')" name="xcx">
|
<el-tab-pane :label="t('小程序同步')" name="xcx">
|
||||||
<weappVersion></weappVersion>
|
<weappVersion></weappVersion>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
@ -70,7 +70,7 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<div class="mt-[16px] flex justify-end">
|
<div class="mt-[16px] flex justify-end">
|
||||||
<el-pagination v-model:current-page="authRecordTableData.page" v-model:page-size="authRecordTableData.limit" layout="total, sizes, prev, pager, next, jumper" :total="authRecordTableData.total" @size-change="loadCommitRecordList()" @current-change="loadCommitRecordList" />
|
<el-pagination v-model:current-page="authRecordTableData.page" v-model:page-size="authRecordTableData.limit" layout="total, sizes, prev, pager, next, jumper" :total="authRecordTableData.total" @size-change="loadAuthRecordList()" @current-change="loadAuthRecordList" />
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|||||||
@ -74,13 +74,11 @@ const setSmsTypeRefs = (el, index) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadSmsList()
|
loadSmsList()
|
||||||
const isLogin = ref(false)
|
|
||||||
const editEvent = (data: any, index: number) => {
|
const editEvent = (data: any, index: number) => {
|
||||||
if (data.sms_type == 'niuyun') {
|
if (data.sms_type == 'niuyun') {
|
||||||
getAccountIsLogin().then((res: any) => {
|
getAccountIsLogin().then((res: any) => {
|
||||||
router.push('/setting/niusms/setting')
|
router.push('/setting/niusms/setting')
|
||||||
})
|
})
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
smsTypeRefs.value[index].setFormData(data)
|
smsTypeRefs.value[index].setFormData(data)
|
||||||
smsTypeRefs.value[index].showDialog = true
|
smsTypeRefs.value[index].showDialog = true
|
||||||
|
|||||||
@ -77,7 +77,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
|
<el-tabs v-model="activeName" class="demo-tabs">
|
||||||
<el-tab-pane label="短信模版" name="template">
|
<el-tab-pane label="短信模版" name="template">
|
||||||
<smsTemplate :username="username" :signature="formData.signature"></smsTemplate>
|
<smsTemplate :username="username" :signature="formData.signature"></smsTemplate>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
@ -92,7 +92,7 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
<smsNiuLogin v-show="!isLogin" :info="formData" :isLogin="isLoginStatus" @complete="getAccountIsLoginFn"></smsNiuLogin>
|
<smsNiuLogin v-show="!isLogin" :info="formData" :isLogin="isLoginStatus" @complete="getAccountIsLoginFn"></smsNiuLogin>
|
||||||
<smsRecharge v-show="isRecharge" @back="isRecharge = false" @complete="backRecharge" :username="username"></smsRecharge>
|
<smsRecharge v-show="isRecharge" @back="isRecharge = false" @complete="backRecharge" :username="username" :isRecharge="isRecharge"></smsRecharge>
|
||||||
<smsSignature ref="signatureDialogRef" :username="username" @select="handleSelectTemplate" ></smsSignature>
|
<smsSignature ref="signatureDialogRef" :username="username" @select="handleSelectTemplate" ></smsSignature>
|
||||||
<el-dialog v-model="visibleMobile" :title="t('更换手机号')" width="600px" destroy-on-close >
|
<el-dialog v-model="visibleMobile" :title="t('更换手机号')" width="600px" destroy-on-close >
|
||||||
<el-form label-width="120px" :model="changeFormData" ref="changeFormRef" :rules="changeFormRules" class="page-form ml-[20px]">
|
<el-form label-width="120px" :model="changeFormData" ref="changeFormRef" :rules="changeFormRules" class="page-form ml-[20px]">
|
||||||
@ -137,6 +137,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref ,computed, onMounted} from 'vue'
|
import { reactive, ref ,computed, onMounted} from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
|
import { ArrowLeft } from "@element-plus/icons-vue"
|
||||||
import { getAccountIsLogin,getAccountInfo,editAccount ,editSms,getSmsCaptcha,getSmsSend,enableNiusms} from '@/app/api/notice'
|
import { getAccountIsLogin,getAccountInfo,editAccount ,editSms,getSmsCaptcha,getSmsSend,enableNiusms} from '@/app/api/notice'
|
||||||
import { useRoute, useRouter} from 'vue-router'
|
import { useRoute, useRouter} from 'vue-router'
|
||||||
import smsNiuLogin from '@/app/views/setting/components/sms_niu_login.vue'
|
import smsNiuLogin from '@/app/views/setting/components/sms_niu_login.vue'
|
||||||
|
|||||||
@ -26,6 +26,7 @@
|
|||||||
import { onMounted, onBeforeUnmount, ref } from 'vue'
|
import { onMounted, onBeforeUnmount, ref } from 'vue'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
|
import { ArrowLeft } from "@element-plus/icons-vue"
|
||||||
import { getOrderPayStatus } from '@/app/api/notice'
|
import { getOrderPayStatus } from '@/app/api/notice'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@ -74,4 +75,4 @@ const checkStatus = async (orderNo: string) => {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
@ -135,7 +135,6 @@ const loading = ref(true)
|
|||||||
const groupList = ref([])
|
const groupList = ref([])
|
||||||
const siteUser = ref([])
|
const siteUser = ref([])
|
||||||
const siteType = ref([])
|
const siteType = ref([])
|
||||||
const domain = location.hostname
|
|
||||||
getUserListSelect({}).then(({ data }) => {
|
getUserListSelect({}).then(({ data }) => {
|
||||||
siteUser.value = data
|
siteUser.value = data
|
||||||
})
|
})
|
||||||
|
|||||||
@ -110,7 +110,6 @@ import { ElMessageBox, FormInstance } from 'element-plus'
|
|||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const searchFormRef = ref<FormInstance>()
|
const searchFormRef = ref<FormInstance>()
|
||||||
|
|
||||||
const siteGroupTableData = reactive({
|
const siteGroupTableData = reactive({
|
||||||
|
|||||||
@ -205,6 +205,7 @@ const confirm = async(formEl: FormInstance | undefined) => {
|
|||||||
}
|
}
|
||||||
const menuRefreshFn = () => {
|
const menuRefreshFn = () => {
|
||||||
menuRefresh({}).then(res => {
|
menuRefresh({}).then(res => {
|
||||||
|
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -67,79 +67,91 @@
|
|||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<div class="mt-[20px]">
|
<div class="mt-[20px]">
|
||||||
<el-table :data="siteTableData.data" size="large" v-loading="siteTableData.loading">
|
<div class="el-table--fit el-table--default el-table overflow-x-auto w-full" style="width: 100%;" v-loading="siteTableData.loading">
|
||||||
<template #empty>
|
|
||||||
<span>{{ !siteTableData.loading ? t('emptyData') : '' }}</span>
|
|
||||||
</template>
|
|
||||||
<el-table-column prop="site_id" :label="t('siteId')" width="100" :show-overflow-tooltip="true" />
|
|
||||||
|
|
||||||
<el-table-column :label="t('siteInfo')" width="300" align="left">
|
<div class="el-table__inner-wrapper">
|
||||||
<template #default="{ row }">
|
<div class="el-table__header-wrapper">
|
||||||
<div class="flex items-center">
|
<table class="el-table__header" border="0" cellpadding="0" cellspacing="0" style="width: 100%;">
|
||||||
<img class="w-[54px] h-[54px] mr-[10px] rounded-[4px]" v-if="row.logo" :src="img(row.logo)" alt="">
|
<thead>
|
||||||
<img class="w-[54px] h-[54px] mr-[10px] rounded-[4px]" v-else src="@/app/assets/images/site_default.png" alt="">
|
<tr>
|
||||||
<div class="flex flex-col">
|
<th class="el-table__cell !w-[100px] !h-[48px] border-b-[1px] !border-[var(--el-color-info-light-8)] border-solid"><div class="cell">{{ t('siteId') }}</div></th>
|
||||||
<span>{{ row.site_name || '' }}</span>
|
<th class="el-table__cell !w-[300px] !h-[48px] border-b-[1px] !border-[var(--el-color-info-light-8)] border-solid"><div class="cell">{{ t('siteInfo') }}</div></th>
|
||||||
</div>
|
<th class="el-table__cell !h-[48px] border-b-[1px] !border-[var(--el-color-info-light-8)] border-solid"><div class="cell">{{ t('manager') }}</div></th>
|
||||||
</div>
|
<th class="el-table__cell !h-[48px] border-b-[1px] !border-[var(--el-color-info-light-8)] border-solid"><div class="cell">{{ t('groupId') }}</div></th>
|
||||||
</template>
|
<th class="el-table__cell !w-[250px] !h-[48px] border-b-[1px] !border-[var(--el-color-info-light-8)] border-solid"><div class="cell">{{ t('siteDomain') }}</div></th>
|
||||||
</el-table-column>
|
<th class="el-table__cell !h-[48px] border-b-[1px] !border-[var(--el-color-info-light-8)] border-solid"><div class="cell">{{ t('createTime') }}</div></th>
|
||||||
|
<th class="el-table__cell !h-[48px] border-b-[1px] !border-[var(--el-color-info-light-8)] border-solid"><div class="cell">{{ t('expireTime') }}</div></th>
|
||||||
|
<th class="el-table__cell !h-[48px] border-b-[1px] !border-[var(--el-color-info-light-8)] border-solid"><div class="cell">{{ t('status') }}</div></th>
|
||||||
|
<th class="el-table__cell !h-[48px] border-b-[1px] !border-[var(--el-color-info-light-8)] border-solid "><div class="cell !text-right">{{ t('operation') }}</div></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="el-table__body-wrapper text-[14px]">
|
||||||
|
<div class="el-scrollbar" v-if="siteTableData.data&&siteTableData.data.length>0" >
|
||||||
|
<div class="el-scrollbar__wrap el-scrollbar__wrap--hidden-default">
|
||||||
|
<div class="el-scrollbar__view" style="display: inline-block; vertical-align: middle;">
|
||||||
|
<table class="el-table__body" cellspacing="0" cellpadding="0" border="0" style="table-layout: fixed; width: 100%;" >
|
||||||
|
<tbody tabindex="-1">
|
||||||
|
<tr v-for="row in siteTableData.data" :key="row.site_id" class="hover-row relative el-table__row " >
|
||||||
|
<td class="w-[100px]"><div class="cell">{{ row.site_id }}</div></td>
|
||||||
|
<td class="w-[300px]">
|
||||||
|
<div class="flex items-center cell">
|
||||||
|
<img class="w-[54px] h-[54px] mr-[10px] rounded-[4px]" v-if="row.logo" :src="img(row.logo)" alt="">
|
||||||
|
<img class="w-[54px] h-[54px] mr-[10px] rounded-[4px]" v-else src="@/app/assets/images/site_default.png" alt="">
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<span>{{ row.site_name || '' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="flex items-center cell">
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<span>{{ row.admin.username || '' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td><div class="cell">{{ row.group_name }}</div></td>
|
||||||
|
<td class="w-[250px]"><div class="cell">{{ row.site_domain}}</div></td>
|
||||||
|
<td><div class="cell">{{ row.create_time }}</div></td>
|
||||||
|
<td>
|
||||||
|
<div class="cell" v-if="row.expire_time == 0">永久</div>
|
||||||
|
<div class="cell" v-else>{{ row.expire_time }}</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="cell">
|
||||||
|
<el-tag class="ml-2" type="success" v-if="row.status == 1">{{ row.status_name }}</el-tag>
|
||||||
|
<el-tag class="ml-2" type="error" v-else-if="row.status == 3">
|
||||||
|
{{ row.status_name }}
|
||||||
|
</el-tag>
|
||||||
|
<el-tag class="ml-2" type="error" v-else>
|
||||||
|
{{ row.status_name }}
|
||||||
|
</el-tag>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="text-right pr-[20px] relative">
|
||||||
|
<el-button type="primary" link @click="openClose(row.status, row.site_id)" v-if="row.status == 1 || row.status == 3">{{ row.status == 1 ? t('closeTxt') : t('openTxt') }}</el-button>
|
||||||
|
<el-button type="primary" link @click="toSiteLink(row.site_id)">{{ t('toSite') }}</el-button>
|
||||||
|
|
||||||
<el-table-column :label="t('manager')" width="150" align="left">
|
<div class="manage-option text-right">
|
||||||
<template #default="{ row }">
|
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
|
||||||
<div class="flex items-center">
|
<el-button type="primary" link @click="deleteEvent(row)">{{ t('delete') }}</el-button>
|
||||||
<div class="flex flex-col">
|
<el-button type="primary" link @click="infoEvent(row)">{{ t('info') }}</el-button>
|
||||||
<span>{{ row.admin.username || '' }}</span>
|
<el-button type="primary" link @click="initSiteEvent(row)">{{ t('站点初始化') }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</td>
|
||||||
</template>
|
</tr>
|
||||||
</el-table-column>
|
</tbody>
|
||||||
|
</table>
|
||||||
<el-table-column prop="group_name" :label="t('groupId')" width="150" :show-overflow-tooltip="true" />
|
|
||||||
<el-table-column prop="site_domain" :label="t('siteDomain')" width="250" :show-overflow-tooltip="true" />
|
|
||||||
<el-table-column prop="create_time" :label="t('createTime')" width="200" :show-overflow-tooltip="true" />
|
|
||||||
<el-table-column prop="expire_time" :label="t('expireTime')" width="200" :show-overflow-tooltip="true">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<div v-if="row.expire_time == 0">永久</div>
|
|
||||||
<div v-else>{{ row.expire_time }}</div>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column :label="t('status')" width="100" align="center">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<el-tag class="ml-2" type="success" v-if="row.status == 1">{{ row.status_name }}</el-tag>
|
|
||||||
<el-tag class="ml-2" type="error" v-else-if="row.status == 3">
|
|
||||||
{{ row.status_name }}
|
|
||||||
</el-tag>
|
|
||||||
<el-tag class="ml-2" type="error" v-else>
|
|
||||||
{{ row.status_name }}
|
|
||||||
</el-tag>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<el-table-column :label="t('operation')" min-width="150" align="right" fixed="right">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<el-button type="primary" link @click="openClose(row.status, row.site_id)" v-if="row.status == 1 || row.status == 3">{{ row.status == 1 ? t('closeTxt') : t('openTxt') }}</el-button>
|
|
||||||
<el-button type="primary" link @click="toSiteLink(row.site_id)">{{ t('toSite') }}</el-button>
|
|
||||||
<!-- <el-dropdown>
|
|
||||||
<span class="el-dropdown-link ml-[12px] h-[20px] leading-[24px] text-[var(--el-color-primary)]">
|
|
||||||
更多
|
|
||||||
</span>
|
|
||||||
<template #dropdown>
|
|
||||||
<div class="flex flex-col py-[5px] px-[10px]">
|
|
||||||
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
|
|
||||||
<el-button type="primary" class="mt-[5px] !ml-[0]" link @click="deleteEvent(row)">{{ t('delete') }}</el-button>
|
|
||||||
<el-button type="primary" class="mt-[5px] !ml-[0]" link @click="infoEvent(row)">{{ t('info') }}</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</div>
|
||||||
</el-dropdown> -->
|
|
||||||
<div class="manage-option text-right">
|
|
||||||
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
|
|
||||||
<el-button type="primary" link @click="deleteEvent(row)">{{ t('delete') }}</el-button>
|
|
||||||
<el-button type="primary" link @click="infoEvent(row)">{{ t('info') }}</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
<div v-if="siteTableData.data.length == 0" class="flex justify-center items-center ">
|
||||||
</el-table-column>
|
<span class="text-center !h-[60px] leading-[60px] !text-[var(--el-text-color-secondary)] ">{{ !siteTableData.loading ? t('emptyData') : '' }}</span>
|
||||||
</el-table>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="mt-[16px] flex justify-end">
|
<div class="mt-[16px] flex justify-end">
|
||||||
<el-pagination v-model:current-page="siteTableData.page" v-model:page-size="siteTableData.limit"
|
<el-pagination v-model:current-page="siteTableData.page" v-model:page-size="siteTableData.limit"
|
||||||
layout="total, sizes, prev, pager, next, jumper" :total="siteTableData.total"
|
layout="total, sizes, prev, pager, next, jumper" :total="siteTableData.total"
|
||||||
@ -156,13 +168,12 @@
|
|||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { getToken, img } from '@/utils/common'
|
import { getToken, img } from '@/utils/common'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getSiteList, getSiteGroupAll, getStatusList, closeSite, openSite, deleteSite } from '@/app/api/site'
|
import { getSiteList, getSiteGroupAll, getStatusList, closeSite, openSite, deleteSite ,initSite} from '@/app/api/site'
|
||||||
import { ElMessage, ElMessageBox, FormInstance } from 'element-plus'
|
import { ElMessage, ElMessageBox, FormInstance } from 'element-plus'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import EditSite from '@/app/views/site/components/edit-site.vue'
|
import EditSite from '@/app/views/site/components/edit-site.vue'
|
||||||
import { getInstalledAddonList } from '@/app/api/addon'
|
import { getInstalledAddonList } from '@/app/api/addon'
|
||||||
import useUserStore from '@/stores/modules/user'
|
import useUserStore from '@/stores/modules/user'
|
||||||
import {deleteUser} from "@/app/api/user";
|
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
status: {
|
status: {
|
||||||
@ -280,6 +291,22 @@ const infoEvent = (data: any) => {
|
|||||||
router.push({ path: '/admin/site/info', query: { id: data.site_id } })
|
router.push({ path: '/admin/site/info', query: { id: data.site_id } })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 站点初始化
|
||||||
|
const initSiteEvent = (data: any) => {
|
||||||
|
ElMessageBox.confirm(t('siteInitTips'), t('warning'),
|
||||||
|
{
|
||||||
|
confirmButtonText: t('confirm'),
|
||||||
|
cancelButtonText: t('cancel'),
|
||||||
|
type: 'warning'
|
||||||
|
}
|
||||||
|
).then(() => {
|
||||||
|
initSite({ site_id: data.site_id }).then(res => {
|
||||||
|
loadSiteList()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 编辑站点详情
|
* 编辑站点详情
|
||||||
* @param data
|
* @param data
|
||||||
@ -410,52 +437,42 @@ const deleteEvent = (data: any) => {
|
|||||||
color: #4F516D;
|
color: #4F516D;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
/* 样式原样保留或略微调整即可适配原生 table */
|
||||||
.manage-option {
|
.manage-option {
|
||||||
line-height: 50px;
|
line-height: 50px;
|
||||||
padding: 0 30px;
|
padding: 0 30px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
background-color: #f4f6f9;
|
background-color: #f4f6f9;
|
||||||
transition: all .3s;
|
transition: all 0.3s;
|
||||||
box-shadow: 0 4px 4px rgba(220, 220, 220, .3);
|
box-shadow: 0 4px 4px rgba(220, 220, 220, 0.3);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
z-index: 999;
|
z-index: 999;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 当行被 hover 时 */
|
/* 悬浮整行显示 manage-option */
|
||||||
:deep(.el-table__row:hover) {
|
.hover-row:hover {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
.hover-row:hover>td {
|
||||||
/* 当行被 hover 时,其下的单元格允许溢出 */
|
background-color: var(--el-table-row-hover-bg-color) !important;
|
||||||
:deep(.el-table__row:hover .el-table__cell) {
|
|
||||||
overflow: visible;
|
|
||||||
}
|
}
|
||||||
|
.hover-row>td {
|
||||||
/* 当行被 hover 时,显示 manage-option 并调整其位置 */
|
border-bottom: 1px solid var(--el-color-info-light-8) !important;
|
||||||
:deep(.el-table__row:hover .manage-option) {
|
|
||||||
opacity: 1;
|
|
||||||
bottom: -51px;
|
|
||||||
}
|
}
|
||||||
|
.hover-row:hover .manage-option {
|
||||||
:deep(.el-table__fixed-body-wrapper:hover),
|
opacity: 1;
|
||||||
:deep(.el-table__fixed-body-wrapper .el-table__row:hover) {
|
bottom: -51px;
|
||||||
z-index: 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-table__fixed-body-wrapper .el-table__row:hover .el-table__cell) {
|
|
||||||
overflow: visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.setting-card .el-card__body){
|
:deep(.setting-card .el-card__body){
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
}
|
}
|
||||||
:deep(.el-scrollbar__view){
|
:deep(.el-scrollbar__view){
|
||||||
margin-bottom: 50px !important;
|
margin-bottom: 53px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -54,7 +54,7 @@
|
|||||||
</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">
|
||||||
<el-tabs v-model="currTab" @tab-click="handleClick">
|
<el-tabs v-model="currTab">
|
||||||
<el-tab-pane :label="t('siteInfo')" name="siteInfo">
|
<el-tab-pane :label="t('siteInfo')" name="siteInfo">
|
||||||
<el-table :data="detail.roles" size="large">
|
<el-table :data="detail.roles" size="large">
|
||||||
<el-table-column prop="site_id" :label="t('siteId')" width="100px" />
|
<el-table-column prop="site_id" :label="t('siteId')" width="100px" />
|
||||||
|
|||||||
@ -69,7 +69,7 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { getToken, img } from '@/utils/common'
|
import { img } from '@/utils/common'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { getAddonDevelop, deleteAddonDevelop, addonDevelopBuild, addonDevelopDownload } from '@/app/api/tools'
|
import { getAddonDevelop, deleteAddonDevelop, addonDevelopBuild, addonDevelopDownload } from '@/app/api/tools'
|
||||||
import { ElMessageBox, FormInstance } from 'element-plus'
|
import { ElMessageBox, FormInstance } from 'element-plus'
|
||||||
|
|||||||
@ -23,8 +23,6 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<el-table :data="tableData.data" size="large" v-loading="tableData.loading" ref="tableRef" @selection-change="handleSelectionChange">
|
<el-table :data="tableData.data" size="large" v-loading="tableData.loading" ref="tableRef" @selection-change="handleSelectionChange">
|
||||||
|
|
||||||
<template #empty>
|
<template #empty>
|
||||||
@ -176,7 +174,6 @@
|
|||||||
<el-button @click="showDialog=false" type="primary" class="!w-[90px]">完成</el-button>
|
<el-button @click="showDialog=false" type="primary" class="!w-[90px]">完成</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-result>
|
</el-result>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<!-- 失败 -->
|
<!-- 失败 -->
|
||||||
<div class="mt-[50px]" v-show="active == 'error'">
|
<div class="mt-[50px]" v-show="active == 'error'">
|
||||||
@ -189,9 +186,7 @@
|
|||||||
<el-button @click="showDialog=false" type="primary" class="!w-[90px]">完成</el-button>
|
<el-button @click="showDialog=false" type="primary" class="!w-[90px]">完成</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-result>
|
</el-result>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@ -261,8 +256,8 @@ const isPass: any = ref(false)
|
|||||||
const uploading: any = ref(false)
|
const uploading: any = ref(false)
|
||||||
const numberOfSteps = ref(0)
|
const numberOfSteps = ref(0)
|
||||||
const currentId: any = ref(0)
|
const currentId: any = ref(0)
|
||||||
let backupContents = []
|
let backupContents: any = []
|
||||||
let restoreContents = []
|
let restoreContents: any = []
|
||||||
|
|
||||||
const resetForm = (formEl: FormInstance | undefined) => {
|
const resetForm = (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
|
|||||||
@ -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="codeTableData.searchParam" ref="searchFormRef">
|
<el-form :inline="true" :model="codeTableData.searchParam" ref="searchFormRef">
|
||||||
<el-form-item :label="t('addonName')" prop="addon_name">
|
<el-form-item :label="t('addonName')" prop="addon_name">
|
||||||
<el-select v-model="codeTableData.searchParam.addon_name" placeholder="全部" filterable remote clearable :remote-method="getAddonDevelopFn">
|
<el-select v-model="codeTableData.searchParam.addon_name" placeholder="全部" filterable remote clearable :remote-method="loadGenerateTableList">
|
||||||
<el-option label="全部" value="" />
|
<el-option label="全部" value="" />
|
||||||
<el-option label="系统" value="2" />
|
<el-option label="系统" value="2" />
|
||||||
<el-option :label="item.title" :value="item.key" v-for="item in addonList" :key="item.key" />
|
<el-option :label="item.title" :value="item.key" v-for="item in addonList" :key="item.key" />
|
||||||
@ -127,7 +127,7 @@ loadGenerateTableList()
|
|||||||
/**
|
/**
|
||||||
* 删除代码生成
|
* 删除代码生成
|
||||||
*/
|
*/
|
||||||
const deleteEvent = (id: number) => {
|
const deleteEvent = (id: number) => {
|
||||||
ElMessageBox.confirm(t('codeDeleteTips'), t('warning'),
|
ElMessageBox.confirm(t('codeDeleteTips'), t('warning'),
|
||||||
{
|
{
|
||||||
confirmButtonText: t('confirm'),
|
confirmButtonText: t('confirm'),
|
||||||
@ -157,12 +157,12 @@ const generatorCheckFileFn = ((id: any) => {
|
|||||||
generatorCheckFile({ id }).then((res: any) => {
|
generatorCheckFile({ id }).then((res: any) => {
|
||||||
codeTableData.loading = false
|
codeTableData.loading = false
|
||||||
ElMessageBox.confirm(
|
ElMessageBox.confirm(
|
||||||
res.msg != '2' ? t('saveAndSyncText') : t('saveAndSyncText1'),
|
res.msg != '2' ? t('saveAndSyncText') : t('saveAndSyncText1'),
|
||||||
t('warning'),
|
t('warning'),
|
||||||
{
|
{
|
||||||
confirmButtonText: t('confirm'),
|
confirmButtonText: t('confirm'),
|
||||||
cancelButtonText: t('cancel')
|
cancelButtonText: t('cancel')
|
||||||
}
|
}
|
||||||
).then(() => {
|
).then(() => {
|
||||||
generateCreateFn(id, 3)
|
generateCreateFn(id, 3)
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
|
|||||||
@ -11,12 +11,8 @@
|
|||||||
<template #default>
|
<template #default>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>{{ t('cronTipsOne') }}</p>
|
||||||
{{ t('cronTipsOne') }}
|
<p class="mt-2">{{ t('cronTipsTwo') }}</p>
|
||||||
</p>
|
|
||||||
<p class="mt-2">
|
|
||||||
{{ t('cronTipsTwo') }}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -26,13 +22,13 @@
|
|||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<el-form :inline="true" :model="cronTableData.searchParam" ref="searchFormRef">
|
<el-form :inline="true" :model="cronTableData.searchParam" ref="searchFormRef">
|
||||||
<el-form-item :label="t('title')" prop="key">
|
<el-form-item :label="t('title')" prop="key">
|
||||||
<el-select v-model="cronTableData.searchParam.key" placeholder="全部" filterable remote clearable :remote-method="getAddonDevelopFn">
|
<el-select v-model="cronTableData.searchParam.key" placeholder="全部" filterable remote clearable :remote-method="loadCronList">
|
||||||
<el-option label="全部" value="all" />
|
<el-option label="全部" value="all" />
|
||||||
<el-option v-for="item in templateList" :key="item.key" :label="item.name" :value="item.key" />
|
<el-option v-for="item in templateList" :key="item.key" :label="item.name" :value="item.key" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('status')" prop="status">
|
<el-form-item :label="t('status')" prop="status">
|
||||||
<el-select v-model="cronTableData.searchParam.status" placeholder="全部" filterable remote clearable :remote-method="getAddonDevelopFn">
|
<el-select v-model="cronTableData.searchParam.status" placeholder="全部" filterable remote clearable :remote-method="loadCronList">
|
||||||
<el-option label="全部" value="all" />
|
<el-option label="全部" value="all" />
|
||||||
<el-option label="启用" value="1" />
|
<el-option label="启用" value="1" />
|
||||||
<el-option label="关闭" value="0" />
|
<el-option label="关闭" value="0" />
|
||||||
@ -51,7 +47,7 @@
|
|||||||
<template #empty>
|
<template #empty>
|
||||||
<span>{{ !cronTableData.loading ? t('emptyData') : '' }}</span>
|
<span>{{ !cronTableData.loading ? t('emptyData') : '' }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-table-column prop="key" :label="t('key')" min-width="150" />
|
<el-table-column prop="key" :label="t('key')" min-width="150" />
|
||||||
<el-table-column prop="name" :label="t('title')" min-width="150" />
|
<el-table-column prop="name" :label="t('title')" min-width="150" />
|
||||||
<el-table-column :label="t('crondType')" min-width="150">
|
<el-table-column :label="t('crondType')" min-width="150">
|
||||||
@ -248,22 +244,26 @@ const formRules = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const validatePass = (rule: any, value: any, callback: any) => {
|
const validatePass = (rule: any, value: any, callback: any) => {
|
||||||
if (formData.time.type == 'min' && formData.time.min != '') {
|
const time = formData.time;
|
||||||
return callback()
|
|
||||||
|
const isPositiveInt = (v: any) => /^[1-9]\d*$/.test(v);
|
||||||
|
|
||||||
|
const error = () => callback(new Error(t('cronTimeTips')));
|
||||||
|
|
||||||
|
switch (time.type) {
|
||||||
|
case 'min':
|
||||||
|
return isPositiveInt(time.min) ? callback() : error();
|
||||||
|
case 'hour':
|
||||||
|
return isPositiveInt(time.hour) && isPositiveInt(time.min) ? callback() : error();
|
||||||
|
case 'day':
|
||||||
|
return isPositiveInt(time.day) && isPositiveInt(time.hour) && isPositiveInt(time.min) ? callback() : error();
|
||||||
|
case 'week':
|
||||||
|
return time.week !== '' && isPositiveInt(time.hour) && isPositiveInt(time.min) ? callback() : error();
|
||||||
|
case 'month':
|
||||||
|
return isPositiveInt(time.day) && isPositiveInt(time.hour) && isPositiveInt(time.min) ? callback() : error();
|
||||||
|
default:
|
||||||
|
return error();
|
||||||
}
|
}
|
||||||
if (formData.time.type == 'week' && formData.time.week != '' && formData.time.hour != '' && formData.time.min != '') {
|
|
||||||
return callback()
|
|
||||||
}
|
|
||||||
if (formData.time.type == 'month' && formData.time.day != '' && formData.time.hour != '' && formData.time.min != '') {
|
|
||||||
return callback()
|
|
||||||
}
|
|
||||||
if (formData.time.type == 'day' && formData.time.day != '' && formData.time.hour != '' && formData.time.min != '') {
|
|
||||||
return callback()
|
|
||||||
}
|
|
||||||
if (formData.time.type == 'hour' && formData.time.hour != '' && formData.time.min != '') {
|
|
||||||
return callback()
|
|
||||||
}
|
|
||||||
return callback(new Error(t('cronTimeTips')))
|
|
||||||
}
|
}
|
||||||
const save_type = ref(false)
|
const save_type = ref(false)
|
||||||
const addEvent = async (formEl: FormInstance | undefined) => {
|
const addEvent = async (formEl: FormInstance | undefined) => {
|
||||||
|
|||||||
@ -33,6 +33,7 @@
|
|||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="loadCronLogList()">{{ t('search') }}</el-button>
|
<el-button type="primary" @click="loadCronLogList()">{{ t('search') }}</el-button>
|
||||||
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
|
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
|
||||||
|
<el-button @click="clearAll" :loading="clearLoading">{{ t('clearAll') }}</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
@ -42,7 +43,6 @@
|
|||||||
<div class="mb-[10px] flex items-center">
|
<div class="mb-[10px] flex items-center">
|
||||||
<el-checkbox v-model="toggleCheckbox" size="large" class="px-[14px]" @change="toggleChange" :indeterminate="isIndeterminate" />
|
<el-checkbox v-model="toggleCheckbox" size="large" class="px-[14px]" @change="toggleChange" :indeterminate="isIndeterminate" />
|
||||||
<el-button @click="batchDelete" size="small" :loading="deleteLoading">{{ t('batchDelete') }}</el-button>
|
<el-button @click="batchDelete" size="small" :loading="deleteLoading">{{ t('batchDelete') }}</el-button>
|
||||||
<el-button @click="clearAll" size="small" :loading="clearLoading">{{ t('clearAll') }}</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-table :data="cronTableData.data" size="large" v-loading="cronTableData.loading" ref="cronLogListTableRef" @selection-change="handleSelectionChange">
|
<el-table :data="cronTableData.data" size="large" v-loading="cronTableData.loading" ref="cronLogListTableRef" @selection-change="handleSelectionChange">
|
||||||
@ -115,8 +115,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref, computed } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
|
import { ArrowLeft } from "@element-plus/icons-vue"
|
||||||
import { getCronLogList, getCronTemplate, deleteCronLog, clearCronLog } from '@/app/api/sys'
|
import { getCronLogList, getCronTemplate, deleteCronLog, clearCronLog } from '@/app/api/sys'
|
||||||
import { ElMessageBox, ElMessage, FormInstance } from 'element-plus'
|
import { ElMessageBox, ElMessage, FormInstance } from 'element-plus'
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
@ -185,7 +186,7 @@ const clearLoading = ref(false)
|
|||||||
/**
|
/**
|
||||||
* 表单数据
|
* 表单数据
|
||||||
*/
|
*/
|
||||||
const initialFormData = {
|
const initialFormData = {
|
||||||
id: '',
|
id: '',
|
||||||
name: '',
|
name: '',
|
||||||
key: '',
|
key: '',
|
||||||
@ -300,7 +301,7 @@ const batchDelete = () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
deleteCronLog({
|
deleteCronLog({
|
||||||
ids: ids
|
ids
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
loadCronLogList()
|
loadCronLogList()
|
||||||
toggleCheckbox.value = false
|
toggleCheckbox.value = false
|
||||||
@ -315,7 +316,6 @@ const batchDelete = () => {
|
|||||||
|
|
||||||
// 清空日志
|
// 清空日志
|
||||||
const clearAll = () => {
|
const clearAll = () => {
|
||||||
|
|
||||||
ElMessageBox.confirm(t('clearAllTips'), t('warning'),
|
ElMessageBox.confirm(t('clearAllTips'), t('warning'),
|
||||||
{
|
{
|
||||||
confirmButtonText: t('confirm'),
|
confirmButtonText: t('confirm'),
|
||||||
@ -327,10 +327,10 @@ const clearAll = () => {
|
|||||||
repeat.value = true
|
repeat.value = true
|
||||||
clearLoading.value = true
|
clearLoading.value = true
|
||||||
|
|
||||||
const schedule_id = route.query.id ?? ''
|
let schedule_id: any = route.query.id ?? ''
|
||||||
|
|
||||||
clearCronLog({
|
clearCronLog({
|
||||||
schedule_id: schedule_id
|
schedule_id
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
loadCronLogList()
|
loadCronLogList()
|
||||||
toggleCheckbox.value = false
|
toggleCheckbox.value = false
|
||||||
|
|||||||
@ -22,7 +22,8 @@ import { ref } from 'vue'
|
|||||||
import { t } from '@/lang'
|
import { t } from '@/lang'
|
||||||
import { clearCache } from '@/app/api/sys'
|
import { clearCache } from '@/app/api/sys'
|
||||||
import { ElMessageBox } from 'element-plus'
|
import { ElMessageBox } from 'element-plus'
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
const loading = ref<Boolean>(false)
|
const loading = ref<Boolean>(false)
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const pageName = route.meta.title
|
const pageName = route.meta.title
|
||||||
|
|||||||
@ -72,7 +72,6 @@ import { t } from '@/lang'
|
|||||||
import {ElMessage, ElMessageBox, FormInstance} from 'element-plus'
|
import {ElMessage, ElMessageBox, FormInstance} from 'element-plus'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { getUpgradeRecords, delUpgradeRecords } from '@/app/api/upgrade'
|
import { getUpgradeRecords, delUpgradeRecords } from '@/app/api/upgrade'
|
||||||
import 'vue-web-terminal/lib/theme/dark.css'
|
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const pageName = route.meta.title
|
const pageName = route.meta.title
|
||||||
@ -146,7 +145,7 @@ const deleteEvent = (ids: any) => {
|
|||||||
}
|
}
|
||||||
).then(() => {
|
).then(() => {
|
||||||
delUpgradeRecords({
|
delUpgradeRecords({
|
||||||
ids: ids
|
ids
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
loadList()
|
loadList()
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
|
|||||||
@ -17,16 +17,14 @@
|
|||||||
<el-form-item :label="t('empowerReceiveUrl')">
|
<el-form-item :label="t('empowerReceiveUrl')">
|
||||||
<el-input v-model.trim="staticInfo.auth_serve_url" placeholder="Please input" class="!w-[500px]" :readonly="true">
|
<el-input v-model.trim="staticInfo.auth_serve_url" placeholder="Please input" class="!w-[500px]" :readonly="true">
|
||||||
<template #append>
|
<template #append>
|
||||||
<div class="cursor-pointer" @click="copyEvent(staticInfo.auth_serve_url)">{{ t('copy') }}
|
<div class="cursor-pointer" @click="copyEvent(staticInfo.auth_serve_url)">{{ t('copy') }}</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('messageReceiveUrl')">
|
<el-form-item :label="t('messageReceiveUrl')">
|
||||||
<el-input v-model.trim="staticInfo.message_serve_url" placeholder="Please input" class="!w-[500px]" :readonly="true">
|
<el-input v-model.trim="staticInfo.message_serve_url" placeholder="Please input" class="!w-[500px]" :readonly="true">
|
||||||
<template #append>
|
<template #append>
|
||||||
<div class="cursor-pointer" @click="copyEvent(staticInfo.message_serve_url)">{{ t('copy') }}
|
<div class="cursor-pointer" @click="copyEvent(staticInfo.message_serve_url)">{{ t('copy') }}</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -75,9 +73,7 @@
|
|||||||
<div class="form-tip">{{ t('uploadIpTips') }}{{ staticInfo.upload_ip }}</div>
|
<div class="form-tip">{{ t('uploadIpTips') }}{{ staticInfo.upload_ip }}</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<div class="fixed-footer-wrap">
|
<div class="fixed-footer-wrap">
|
||||||
|
|||||||
@ -92,7 +92,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<div v-else class="flex flex-wrap">
|
<div v-else class="flex flex-wrap">
|
||||||
<div v-for="(item, index) in childList" :key="index"
|
<div v-for="(item, index) in childList" :key="index"
|
||||||
class="border border-br rounded-[3px] mr-[10px] mb-[10px] px-4 h-[32px] leading-[32px] cursor-pointer hover:bg-primary-light-9 px-[10px] hover:text-primary"
|
class="border border-br rounded-[3px] mr-[10px] mb-[10px] h-[32px] leading-[32px] cursor-pointer hover:bg-primary-light-9 px-[10px] hover:text-primary"
|
||||||
:class="{ 'border-primary text-primary': (parentLinkName != 'DIY_PAGE' && item.name == selectLink.name) || (parentLinkName == 'DIY_PAGE' && item.url == selectLink.url) }"
|
:class="{ 'border-primary text-primary': (parentLinkName != 'DIY_PAGE' && item.name == selectLink.name) || (parentLinkName == 'DIY_PAGE' && item.url == selectLink.url) }"
|
||||||
@click="changeChildLink(item)">{{ item.title }}
|
@click="changeChildLink(item)">{{ item.title }}
|
||||||
</div>
|
</div>
|
||||||
@ -194,12 +194,25 @@ const show = () => {
|
|||||||
const getLinkFn = (callback: any = null) => {
|
const getLinkFn = (callback: any = null) => {
|
||||||
getLink({}).then((res: any) => {
|
getLink({}).then((res: any) => {
|
||||||
link.value = res.data
|
link.value = res.data
|
||||||
|
if(link.value && link.value.length == 0) return;
|
||||||
|
|
||||||
if (prop.ignore && prop.ignore.length) {
|
if (prop.ignore && prop.ignore.length) {
|
||||||
for (let key in link.value) {
|
for (let key in link.value) {
|
||||||
for (let i = 0; i < prop.ignore.length; i++) {
|
for (let i = 0; i < prop.ignore.length; i++) {
|
||||||
if (key == prop.ignore[i]) {
|
if (key == prop.ignore[i]) {
|
||||||
delete link.value[key];
|
delete link.value[key]
|
||||||
break;
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (link.value[key] && link.value[key].child_list) {
|
||||||
|
for (let i = 0; i < link.value[key].child_list.length; i++) {
|
||||||
|
for (let j = 0; j < prop.ignore.length; j++) {
|
||||||
|
if (link.value[key].child_list[i].name == prop.ignore[j]) {
|
||||||
|
console.log(link.value[key].child_list[i])
|
||||||
|
link.value[key].child_list.splice(i, 1)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -94,11 +94,11 @@ const handleEditorReady = (editor) => {
|
|||||||
// 方案二:原型链扩展(如果编辑器版本支持)
|
// 方案二:原型链扩展(如果编辑器版本支持)
|
||||||
const originalCount = editor.getContentLength; // 原生统计方法
|
const originalCount = editor.getContentLength; // 原生统计方法
|
||||||
|
|
||||||
// 覆盖方法:去除空格后统计
|
// 覆盖方法:去除空格后统计
|
||||||
editor.getContentLength = function () {
|
editor.getContentLength = function () {
|
||||||
const rawContent = editor.getContent();
|
const rawContent = editor.getContent();
|
||||||
return rawContent.replace(/[\s\u3000]+/g, '').length;
|
return rawContent.replace(/[\s\u3000]+/g, '').length;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const imageSelect = (data: Record<string, any>) => {
|
const imageSelect = (data: Record<string, any>) => {
|
||||||
|
|||||||
@ -80,7 +80,6 @@ const value: any = computed({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 公式:
|
* 公式:
|
||||||
* 宽度:400
|
* 宽度:400
|
||||||
|
|||||||
@ -48,7 +48,7 @@
|
|||||||
<el-col :span="10">
|
<el-col :span="10">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<el-upload v-bind="upload" ref="uploadRef" v-if="prop.type != 'icon'">
|
<el-upload v-bind="upload" ref="uploadRef" v-if="prop.type != 'icon'">
|
||||||
<el-button type="primary">{{ t('upload.upload' + type) }} {{ isOpen }}</el-button>
|
<el-button type="primary">{{ t('upload.upload' + type) }}</el-button>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
<div v-if="scene == 'attachment' && prop.type != 'icon'">
|
<div v-if="scene == 'attachment' && prop.type != 'icon'">
|
||||||
<el-button v-if="operate === false" class="ml-[10px]" type="primary" @click="operate = true">{{ t('edit') }}</el-button>
|
<el-button v-if="operate === false" class="ml-[10px]" type="primary" @click="operate = true">{{ t('edit') }}</el-button>
|
||||||
@ -192,9 +192,7 @@ import {
|
|||||||
editAttachmentCategory as updateCategory,
|
editAttachmentCategory as updateCategory,
|
||||||
deleteAttachmentCategory as deleteCategory,
|
deleteAttachmentCategory as deleteCategory,
|
||||||
deleteAttachment,
|
deleteAttachment,
|
||||||
moveAttachment,
|
moveAttachment
|
||||||
getIconCategoryList,
|
|
||||||
getIconList
|
|
||||||
} from '@/app/api/sys'
|
} from '@/app/api/sys'
|
||||||
import { debounce, img, getToken } from '@/utils/common'
|
import { debounce, img, getToken } from '@/utils/common'
|
||||||
import { ElMessage, UploadFile, UploadFiles, ElMessageBox, MessageParams } from 'element-plus'
|
import { ElMessage, UploadFile, UploadFiles, ElMessageBox, MessageParams } from 'element-plus'
|
||||||
@ -202,7 +200,6 @@ import storage from '@/utils/storage'
|
|||||||
|
|
||||||
const attachmentCategoryName = ref('')
|
const attachmentCategoryName = ref('')
|
||||||
const operate = ref(false)
|
const operate = ref(false)
|
||||||
|
|
||||||
const repeat = ref(false)
|
const repeat = ref(false)
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
@ -260,6 +257,72 @@ const attachmentParam = reactive({
|
|||||||
cate_id: 0
|
cate_id: 0
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const iconJsonFile = import.meta.glob('../../styles/icon/**/*.json', { eager: true })
|
||||||
|
const iconList = {
|
||||||
|
0: []
|
||||||
|
}
|
||||||
|
|
||||||
|
const getIconCategoryList = (search) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
const result = {
|
||||||
|
code: 1,
|
||||||
|
data: []
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(iconJsonFile).reverse().forEach(key => {
|
||||||
|
let item = iconJsonFile[key].default
|
||||||
|
if (search.name && item.name.indexOf(search.name) != -1) {
|
||||||
|
result.data.push(item)
|
||||||
|
} else if (!search.name) {
|
||||||
|
result.data.push(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!iconList[item.id]) {
|
||||||
|
item.glyphs = item.glyphs.map(iconItem => {
|
||||||
|
iconItem.url = `${ item.font_family } ${ item.css_prefix_text }${ iconItem.font_class }`
|
||||||
|
iconItem.real_name = iconItem.name
|
||||||
|
iconItem.att_id = iconItem.icon_id
|
||||||
|
return iconItem
|
||||||
|
})
|
||||||
|
iconList[0].push(...item.glyphs)
|
||||||
|
iconList[item.id] = item.glyphs
|
||||||
|
}
|
||||||
|
})
|
||||||
|
resolve(result)
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
reject(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getIconList = (search) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
const result = {
|
||||||
|
code: 1,
|
||||||
|
data: {
|
||||||
|
current_page: search.page,
|
||||||
|
per_page: 1,
|
||||||
|
total: 0,
|
||||||
|
data: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let icons = JSON.parse(JSON.stringify(iconList[search.cate_id]))
|
||||||
|
if (search.real_name) icons = icons.filter(item => item.real_name.indexOf(search.real_name) != -1)
|
||||||
|
|
||||||
|
result.data.total = icons.length
|
||||||
|
result.data.data = icons.splice((search.page - 1) * search.limit, search.limit)
|
||||||
|
result.data.per_page = Math.ceil(icons.length / search.limit)
|
||||||
|
resolve(result)
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
reject(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询分组
|
* 查询分组
|
||||||
*/
|
*/
|
||||||
@ -380,10 +443,10 @@ const upload = computed(() => {
|
|||||||
const headers: Record<string, any> = {}
|
const headers: Record<string, any> = {}
|
||||||
headers[import.meta.env.VITE_REQUEST_HEADER_TOKEN_KEY] = getToken()
|
headers[import.meta.env.VITE_REQUEST_HEADER_TOKEN_KEY] = getToken()
|
||||||
headers[import.meta.env.VITE_REQUEST_HEADER_SITEID_KEY] = storage.get('siteId') || 0
|
headers[import.meta.env.VITE_REQUEST_HEADER_SITEID_KEY] = storage.get('siteId') || 0
|
||||||
const baseURL = import.meta.env.VITE_APP_BASE_URL.substr(-1) == '/' ? import.meta.env.VITE_APP_BASE_URL : `${import.meta.env.VITE_APP_BASE_URL}/`;
|
const baseURL = import.meta.env.VITE_APP_BASE_URL.substr(-1) == '/' ? import.meta.env.VITE_APP_BASE_URL : `${ import.meta.env.VITE_APP_BASE_URL }/`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
action: `${baseURL}sys/${prop.type}`,
|
action: `${ baseURL }sys/${ prop.type }`,
|
||||||
multiple: true,
|
multiple: true,
|
||||||
data: {
|
data: {
|
||||||
cate_id: attachmentParam.cate_id
|
cate_id: attachmentParam.cate_id
|
||||||
@ -394,17 +457,16 @@ const upload = computed(() => {
|
|||||||
getAttachmentList()
|
getAttachmentList()
|
||||||
uploadRef.value?.handleRemove(uploadFile)
|
uploadRef.value?.handleRemove(uploadFile)
|
||||||
} else {
|
} else {
|
||||||
if(time.value==null) {
|
if (time.value == null) {
|
||||||
time.value = setTimeout(() => {
|
time.value = setTimeout(() => {
|
||||||
uploadFile.status = 'fail'
|
uploadFile.status = 'fail'
|
||||||
showElMessage({ message: response.msg, type: 'error' })
|
showElMessage({ message: response.msg, type: 'error' })
|
||||||
clearTimeout(time.value)
|
clearTimeout(time.value)
|
||||||
time.value=null
|
time.value = null
|
||||||
},500)
|
}, 500)
|
||||||
|
} else {
|
||||||
}else{
|
|
||||||
clearTimeout(time.value)
|
clearTimeout(time.value)
|
||||||
time.value=null
|
time.value = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,19 +47,17 @@ const emit = defineEmits(['confirm'])
|
|||||||
*/
|
*/
|
||||||
const confirm = () => {
|
const confirm = () => {
|
||||||
showDialog.value = false
|
showDialog.value = false
|
||||||
|
|
||||||
let filesObj = attachmentRef?.value.selectedFile || {};
|
let filesObj = attachmentRef?.value.selectedFile || {};
|
||||||
let filesIndexObj = attachmentRef?.value.selectedFileIndex || {};
|
let filesIndexObj = attachmentRef?.value.selectedFileIndex || {};
|
||||||
// 整理图片顺序
|
// 整理图片顺序
|
||||||
let arr = [];
|
let arr = [];
|
||||||
Object.values(filesIndexObj).forEach((item,index)=>{
|
Object.values(filesIndexObj).forEach((item, index) => {
|
||||||
for(let key in filesObj){
|
for (let key in filesObj) {
|
||||||
if(item == key){
|
if (item == key) {
|
||||||
arr.push(deepClone(filesObj[key]))
|
arr.push(deepClone(filesObj[key]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
emit('confirm', prop.limit == 1 ? arr[0] ?? null : arr)
|
emit('confirm', prop.limit == 1 ? arr[0] ?? null : arr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -58,7 +58,7 @@ const prop = defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
default: 'image'
|
default: 'image'
|
||||||
},
|
},
|
||||||
imageFit : {
|
imageFit: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'contain'
|
default: 'contain'
|
||||||
},
|
},
|
||||||
@ -106,9 +106,9 @@ const setValue = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
watch(() => value.value, () => {
|
watch(() => value.value, () => {
|
||||||
if(value.value.indexOf('data:image') != -1){
|
if (value.value.indexOf('data:image') != -1) {
|
||||||
images.data = [value.value]
|
images.data = [value.value]
|
||||||
}else {
|
} else {
|
||||||
images.data = [
|
images.data = [
|
||||||
...value.value.split(',').filter((item: string) => {
|
...value.value.split(',').filter((item: string) => {
|
||||||
return item
|
return item
|
||||||
@ -141,7 +141,7 @@ const confirmSelect = (data: Record<string, any>) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
setValue()
|
setValue()
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
emit('change', value.value)
|
emit('change', value.value)
|
||||||
})
|
})
|
||||||
@ -172,14 +172,12 @@ const previewImage = (index: number = 0) => {
|
|||||||
* 拖拽
|
* 拖拽
|
||||||
*/
|
*/
|
||||||
const imgListRef:any = ref(null)
|
const imgListRef:any = ref(null)
|
||||||
onMounted(()=>{
|
onMounted(()=> {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
rowDrop()
|
rowDrop()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const activeRows = ref<any[]>([])
|
|
||||||
|
|
||||||
// 拖拽排序
|
// 拖拽排序
|
||||||
const rowDrop = () => {
|
const rowDrop = () => {
|
||||||
if (prop.limit == 1) return;
|
if (prop.limit == 1) return;
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
import request from "./../utils/axios" //组件内部封装的axios
|
import request from "./../utils/axios" //组件内部封装的axios
|
||||||
// import request from "@/app/api/axios.js" //调用项目封装的axios
|
// import request from "@/app/api/axios.js" //调用项目封装的axios
|
||||||
|
|
||||||
//获取验证图片 以及token
|
// 获取验证图片 以及token
|
||||||
export function reqGet(data) {
|
export function reqGet(data) {
|
||||||
return request.get('/captcha/create', { params: { ...data } });
|
return request.get('/captcha/create', { params: { ...data } });
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ export function reqGet(data) {
|
|||||||
// })
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
//滑动或者点选验证
|
// 滑动或者点选验证
|
||||||
export function reqCheck(data) {
|
export function reqCheck(data) {
|
||||||
return request.get('/captcha/check', { params: { ...data } });
|
return request.get('/captcha/check', { params: { ...data } });
|
||||||
|
|
||||||
@ -26,5 +26,3 @@ export function reqCheck(data) {
|
|||||||
// data
|
// data
|
||||||
// })
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,20 +6,20 @@
|
|||||||
<!-- <div class="flex items-center justify-center bg-primary text-white h-[40px] text-[16px] rounded-[4px] mb-[10px]"><span class="text-[20px]">+</span><span v-if="systemStore.menuIsCollapse" class="ml-[10px]">应用市场</span></div> -->
|
<!-- <div class="flex items-center justify-center bg-primary text-white h-[40px] text-[16px] rounded-[4px] mb-[10px]"><span class="text-[20px]">+</span><span v-if="systemStore.menuIsCollapse" class="ml-[10px]">应用市场</span></div> -->
|
||||||
<div class="flex flex-col items-center">
|
<div class="flex flex-col items-center">
|
||||||
<template v-for="(item, index) in oneMenuData">
|
<template v-for="(item, index) in oneMenuData">
|
||||||
<div v-if="item.meta.show" class="menu-item my-[2px] p-2 flex w-full box-border cursor-pointer relative" :class="{'is-active':oneMenuActive===item.original_name,'hover-left': systemStore.menuIsCollapse, 'vertical': !systemStore.menuIsCollapse , 'horizontal': systemStore.menuIsCollapse }" :style="{ height: (systemStore.menuIsCollapse ) ? '40px' : '55px' }" @click="router.push({ name: item.name })">
|
<div v-if="item.meta.show" :title="systemStore.menuIsCollapse ? item.meta.title : item.meta.short_title" class="menu-item my-[2px] p-2 flex w-full box-border cursor-pointer relative" :class="{'is-active':oneMenuActive===item.original_name,'hover-left': systemStore.menuIsCollapse, 'vertical': !systemStore.menuIsCollapse , 'horizontal': systemStore.menuIsCollapse }" :style="{ height: (systemStore.menuIsCollapse ) ? '40px' : '55px' }" @click="router.push({ name: item.name })">
|
||||||
<div class="w-[20px] h-[20px] flex items-center justify-center menu-icon" :class="{'is-active':oneMenuActive===item.original_name}">
|
<div class="w-[20px] h-[20px] flex items-center justify-center menu-icon" :class="{'is-active':oneMenuActive===item.original_name}">
|
||||||
<template v-if="item.meta.icon">
|
<template v-if="item.meta.icon">
|
||||||
<el-image class="w-[20px] h-[20px] overflow-hidden" :src="item.meta.icon" fit="fill" v-if="isUrl(item.meta.icon)"/>
|
<el-image class="w-[20px] h-[20px] overflow-hidden" :src="item.meta.icon" fit="fill" v-if="isUrl(item.meta.icon)"/>
|
||||||
<icon :name="item.meta.icon" size="20px" color="#1D1F3A" v-else />
|
<icon :name="item.meta.icon" size="20px" color="#1D1F3A" v-else />
|
||||||
</template>
|
</template>
|
||||||
<icon v-else :name="'iconfont iconshezhi1'" color="#1D1F3A" />
|
<icon v-else :name="'iconfont iconshezhi1'" color="#1D1F3A" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="systemStore.menuIsCollapse" class="text-center text-[14px] mt-[3px] ml-[10px]">{{ item.meta.title || item.meta.short_title }}</div>
|
<div v-if="systemStore.menuIsCollapse" class="text-left text-[14px] mt-[3px] w-[75px] using-hidden ml-[10px]">{{ item.meta.title || item.meta.short_title }}</div>
|
||||||
<div v-else class="text-center text-[12px] mt-1">{{ item.meta.short_title || item.meta.title }}</div>
|
<div v-else class="text-center text-[12px] using-hidden mt-1">{{ item.meta.short_title || item.meta.title }}</div>
|
||||||
<div v-if="systemStore.menuIsCollapse && item.name=='app_store' && recentlyUpdated.length>0" class="text-[11px] bg-[#DA203E] px-[10px] rounded-[12px] text-[#fff] ml-auto">更新</div>
|
<div v-if="systemStore.menuIsCollapse && item.name=='app_store' && recentlyUpdated.length>0" class="text-[11px] bg-[#DA203E] px-[10px] rounded-[12px] text-[#fff] absolute right-[6px]">更新</div>
|
||||||
<div v-if="!systemStore.menuIsCollapse && item.name=='app_store' && recentlyUpdated.length>0" class="w-[7px] h-[7px] bg-[#DA203E] absolute flex items-center justify-center rounded-full top-[4px] right-[14px]"></div>
|
<div v-if="!systemStore.menuIsCollapse && item.name=='app_store' && recentlyUpdated.length>0" class="w-[7px] h-[7px] bg-[#DA203E] absolute flex items-center justify-center rounded-full top-[4px] right-[14px]"></div>
|
||||||
<div v-if="systemStore.menuIsCollapse && item.original_name=='tool' && isNewVersion" class="text-[11px] bg-[#DA203E] px-[10px] rounded-[12px] text-[#fff] ml-auto">更新</div>
|
<div v-if="systemStore.menuIsCollapse && item.original_name=='tool' && isNewVersion" class="text-[11px] bg-[#DA203E] px-[10px] rounded-[12px] text-[#fff] absolute right-[6px]">更新</div>
|
||||||
<div v-if="!systemStore.menuIsCollapse && item.original_name=='tool' && isNewVersion" class="w-[7px] h-[7px] bg-[#DA203E] absolute flex items-center justify-center rounded-full top-[4px] right-[14px]"></div>
|
<div v-if="!systemStore.menuIsCollapse && item.original_name=='tool' && isNewVersion" class="w-[7px] h-[7px] bg-[#DA203E] absolute flex items-center justify-center rounded-full top-[4px] right-[14px]"></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -47,11 +47,11 @@ import { useRoute, useRouter } from 'vue-router'
|
|||||||
import useSystemStore from '@/stores/modules/system'
|
import useSystemStore from '@/stores/modules/system'
|
||||||
import useUserStore from '@/stores/modules/user'
|
import useUserStore from '@/stores/modules/user'
|
||||||
import { ADMIN_ROUTE,findFirstValidRoute } from "@/router/routers"
|
import { ADMIN_ROUTE,findFirstValidRoute } from "@/router/routers"
|
||||||
import { img, isUrl } from '@/utils/common'
|
import { isUrl } from '@/utils/common'
|
||||||
import menuItem from './menu-item.vue'
|
import menuItem from './menu-item.vue'
|
||||||
import { getAddonLocal} from '@/app/api/addon'
|
import { getAddonLocal} from '@/app/api/addon'
|
||||||
import { getVersions } from "@/app/api/auth"
|
import { getVersions } from "@/app/api/auth"
|
||||||
import { getAuthInfo, getFrameworkVersionList } from "@/app/api/module"
|
import { getFrameworkVersionList } from "@/app/api/module"
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
@ -75,7 +75,6 @@ routers.forEach(item => {
|
|||||||
item.name = findFirstValidRoute(item.children)
|
item.name = findFirstValidRoute(item.children)
|
||||||
}
|
}
|
||||||
oneMenuData.value.push(item)
|
oneMenuData.value.push(item)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const oneMenuActive = ref(oneMenuData.value[0].name)
|
const oneMenuActive = ref(oneMenuData.value[0].name)
|
||||||
@ -83,7 +82,6 @@ watch(route, () => {
|
|||||||
twoMenuData.value = route.matched[1].children ?? []
|
twoMenuData.value = route.matched[1].children ?? []
|
||||||
oneMenuActive.value = route.matched[1].name == ADMIN_ROUTE.children[0].name ? route.matched[2].name : route.matched[1].name
|
oneMenuActive.value = route.matched[1].name == ADMIN_ROUTE.children[0].name ? route.matched[2].name : route.matched[1].name
|
||||||
defaultOpeneds.value = twoMenuData.value.map(item => item.name)
|
defaultOpeneds.value = twoMenuData.value.map(item => item.name)
|
||||||
|
|
||||||
}, { immediate: true })
|
}, { immediate: true })
|
||||||
|
|
||||||
const recentlyUpdated = ref([])
|
const recentlyUpdated = ref([])
|
||||||
@ -107,7 +105,7 @@ const isNewVersion = computed(() => {
|
|||||||
if (!newVersion.value || newVersion.value.version_no === version.value) {
|
if (!newVersion.value || newVersion.value.version_no === version.value) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将版本号转为字符串再处理
|
// 将版本号转为字符串再处理
|
||||||
const currentVersionStr = String(version.value);
|
const currentVersionStr = String(version.value);
|
||||||
const latestVersionStr = String(newVersion.value.version_no);
|
const latestVersionStr = String(newVersion.value.version_no);
|
||||||
@ -115,7 +113,8 @@ const isNewVersion = computed(() => {
|
|||||||
const currentVersionNum = parseInt(currentVersionStr.replace(/\./g, ''), 10);
|
const currentVersionNum = parseInt(currentVersionStr.replace(/\./g, ''), 10);
|
||||||
const latestVersionNum = parseInt(latestVersionStr.replace(/\./g, ''), 10);
|
const latestVersionNum = parseInt(latestVersionStr.replace(/\./g, ''), 10);
|
||||||
return latestVersionNum > currentVersionNum;
|
return latestVersionNum > currentVersionNum;
|
||||||
});
|
})
|
||||||
|
|
||||||
const getFrameworkVersionListFn = () => {
|
const getFrameworkVersionListFn = () => {
|
||||||
getFrameworkVersionList().then(({ data }) => {
|
getFrameworkVersionList().then(({ data }) => {
|
||||||
frameworkVersionList.value = data
|
frameworkVersionList.value = data
|
||||||
@ -194,7 +193,7 @@ getVersionsInfo()
|
|||||||
}
|
}
|
||||||
.menu-item.hover-left {
|
.menu-item.hover-left {
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
padding-left: 5px;
|
padding-left: 5px;
|
||||||
}
|
}
|
||||||
&.expanded .menu-item .text-center {
|
&.expanded .menu-item .text-center {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
@ -205,7 +204,6 @@ getVersionsInfo()
|
|||||||
.el-scrollbar{
|
.el-scrollbar{
|
||||||
height: calc(100vh - 65px);
|
height: calc(100vh - 65px);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
.two-menu{
|
.two-menu{
|
||||||
.aside-menu:not(.el-menu--collapse) {
|
.aside-menu:not(.el-menu--collapse) {
|
||||||
@ -224,7 +222,7 @@ getVersionsInfo()
|
|||||||
&.is-active{
|
&.is-active{
|
||||||
background-color: #EAEBF0 !important;
|
background-color: #EAEBF0 !important;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
// background-color: var(--el-color-primary-light-9) !important;
|
// background-color: var(--el-color-primary-light-9) !important;
|
||||||
}
|
}
|
||||||
&:hover{
|
&:hover{
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
<div v-if="meta.icon && props.level != 2" class="w-[13px] h-[13px] mr-[10rpx] relative flex justify-center items-center">
|
<div v-if="meta.icon && props.level != 2" class="w-[13px] h-[13px] mr-[10rpx] relative flex justify-center items-center">
|
||||||
<icon v-if="meta.icon && props.level != 2" :name="meta.icon" color="#1D1F3A" class="absolute !w-auto" />
|
<icon v-if="meta.icon && props.level != 2" :name="meta.icon" color="#1D1F3A" class="absolute !w-auto" />
|
||||||
</div>
|
</div>
|
||||||
<span :class="['ml-[10px]', {'text-[15px]': routes.meta.class == 1}, {'text-[14px]': routes.meta.class != 1}]">{{ meta.title }}</span>
|
<span class="using-hidden" :class="['ml-[10px]', {'text-[15px]': routes.meta.class == 1}, {'text-[14px]': routes.meta.class != 1}]">{{ meta.title }}</span>
|
||||||
</template>
|
</template>
|
||||||
<menu-item v-for="(route, index) in routes.children" :routes="route" :level="props.level + 1" :key="index" :isNewVersion="props.isNewVersion" />
|
<menu-item v-for="(route, index) in routes.children" :routes="route" :level="props.level + 1" :key="index" :isNewVersion="props.isNewVersion" />
|
||||||
</el-sub-menu>
|
</el-sub-menu>
|
||||||
@ -14,7 +14,7 @@
|
|||||||
<div v-if="meta.icon && props.level != 2" class="w-[13px] h-[13px] mr-[10rpx] relative flex justify-center items-center">
|
<div v-if="meta.icon && props.level != 2" class="w-[13px] h-[13px] mr-[10rpx] relative flex justify-center items-center">
|
||||||
<icon v-if="meta.icon && props.level != 2" color="#1D1F3A" :name="meta.icon" class="absolute !w-auto" />
|
<icon v-if="meta.icon && props.level != 2" color="#1D1F3A" :name="meta.icon" class="absolute !w-auto" />
|
||||||
</div>
|
</div>
|
||||||
<span :class="[{'text-[15px]': routes.meta.class == 1}, {'text-[14px]': routes.meta.class != 1}, {'ml-[10px]': routes.meta.class == 2, 'ml-[15px]': routes.meta.class == 3}]">{{ meta.title }}
|
<span class="using-hidden" :class="[{'text-[15px]': routes.meta.class == 1}, {'text-[14px]': routes.meta.class != 1}, {'ml-[10px]': routes.meta.class == 2, 'ml-[15px]': routes.meta.class == 3}]">{{ meta.title }}
|
||||||
<div v-if="meta.view=='app/upgrade'&& props.isNewVersion" class="w-[7px] h-[7px] bg-[#DA203E] absolute flex items-center justify-center rounded-full top-[10px] right-[65px]"></div>
|
<div v-if="meta.view=='app/upgrade'&& props.isNewVersion" class="w-[7px] h-[7px] bg-[#DA203E] absolute flex items-center justify-center rounded-full top-[10px] right-[65px]"></div>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
@ -65,4 +65,16 @@ const meta = computed(() => props.routes.meta)
|
|||||||
background-color: var(--el-color-primary);
|
background-color: var(--el-color-primary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<style scoped>
|
||||||
|
.using-hidden {
|
||||||
|
word-break: break-all;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 1;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -107,6 +107,7 @@ import userInfo from './user-info.vue'
|
|||||||
import layoutSetting from './layout-setting.vue'
|
import layoutSetting from './layout-setting.vue'
|
||||||
import message from './message.vue'
|
import message from './message.vue'
|
||||||
|
|
||||||
|
const showDialog = ref<boolean>(false)
|
||||||
const systemStore = useSystemStore()
|
const systemStore = useSystemStore()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@ -165,7 +166,7 @@ const toHome = () => {
|
|||||||
window.localStorage.setItem('site.comparisonTokenStorage', getToken())
|
window.localStorage.setItem('site.comparisonTokenStorage', getToken())
|
||||||
}
|
}
|
||||||
if (!window.localStorage.getItem('site.userinfo')) {
|
if (!window.localStorage.getItem('site.userinfo')) {
|
||||||
window.localStorage.setItem('site.userinfo', JSON.stringify(useUserStore().userInfo))
|
window.localStorage.setItem('site.userinfo', JSON.stringify(useUserStore().userInfo))
|
||||||
}
|
}
|
||||||
router.push({ path: '/home/index'})
|
router.push({ path: '/home/index'})
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user