mirror of
https://gitee.com/niucloud-team/niucloud.git
synced 2026-01-26 04:28:10 +00:00
update admin
This commit is contained in:
parent
e4872ef902
commit
71defadfff
@ -60,7 +60,7 @@ export function editDiyPage(params: Record<string, any>) {
|
||||
* @param params
|
||||
*/
|
||||
export function setUseDiyPage(params: Record<string, any>) {
|
||||
return request.put(`diy/use`, params, {showSuccessMessage: true})
|
||||
return request.put(`diy/use/${params.id}`, params, {showSuccessMessage: true})
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -433,15 +433,6 @@ export function getMemberLevelPageList(params: Record<string, any>) {
|
||||
return request.get(`member/level`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会员等级列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getMemberLevelList(params: Record<string, any>) {
|
||||
return request.get(`member/level/list`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会员等级详情
|
||||
* @param level_id 会员等级level_id
|
||||
@ -521,4 +512,4 @@ export function setSignConfig(params: Record<string, any>) {
|
||||
*/
|
||||
export function getMemberSignList(params: Record<string, any>) {
|
||||
return request.get(`member/sign`, { params });
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,26 +3,24 @@ import request from '@/utils/request'
|
||||
/**
|
||||
* 获取授权信息
|
||||
*/
|
||||
export function getAuthinfo() {
|
||||
export function getAuthInfo() {
|
||||
return request.get('niucloud/authinfo', { showErrorMessage: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 授权配置
|
||||
*/
|
||||
export function setAuthinfo(params: Record<string, any>) {
|
||||
export function setAuthInfo(params: Record<string, any>) {
|
||||
return request.post('niucloud/authinfo', params, {showSuccessMessage: true})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 授权配置
|
||||
*/
|
||||
export function getAdminAuthinfo() {
|
||||
export function getAdminAuthInfo() {
|
||||
return request.get('niucloud/admin/authinfo')
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取授权插件列表
|
||||
* @returns
|
||||
|
||||
@ -28,7 +28,6 @@ export function getNoticeLog(params: any) {
|
||||
return request.get(`notice/log`, {params})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 消息启动与关闭
|
||||
* @param params
|
||||
|
||||
184
admin/src/app/api/printer.ts
Normal file
184
admin/src/app/api/printer.ts
Normal file
@ -0,0 +1,184 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 获取小票打印机分页列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getPrinterPageList(params: Record<string, any>) {
|
||||
return request.get(`sys/printer`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取小票打印机列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getPrinterList(params: Record<string, any>) {
|
||||
return request.get(`sys/printer/list`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取小票打印机详情
|
||||
* @param printer_id 小票打印机printer_id
|
||||
* @returns
|
||||
*/
|
||||
export function getPrinterInfo(printer_id: number) {
|
||||
return request.get(`sys/printer/${ printer_id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加小票打印机
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addPrinter(params: Record<string, any>) {
|
||||
return request.post('sys/printer', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑小票打印机
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editPrinter(params: Record<string, any>) {
|
||||
return request.put(`sys/printer/${ params.printer_id }`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改小票打印机状态
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function modifyPrinterStatus(params: Record<string, any>) {
|
||||
return request.put(`sys/printer/status`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除小票打印机
|
||||
* @param printer_id
|
||||
* @returns
|
||||
*/
|
||||
export function deletePrinter(printer_id: number) {
|
||||
return request.delete(`sys/printer/${ printer_id }`, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取小票打印模板分页列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getPrinterTemplatePageList(params: Record<string, any>) {
|
||||
return request.get(`sys/printer/template`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取小票打印模板列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getPrinterTemplateList(params: Record<string, any>) {
|
||||
return request.get(`sys/printer/template/list`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取小票打印模板详情
|
||||
* @param template_id 小票打印模板template_id
|
||||
* @returns
|
||||
*/
|
||||
export function getPrinterTemplateInfo(template_id: number) {
|
||||
return request.get(`sys/printer/template/${ template_id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加小票打印模板
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addPrinterTemplate(params: Record<string, any>) {
|
||||
return request.post('sys/printer/template', params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑小票打印模板
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editPrinterTemplate(params: Record<string, any>) {
|
||||
return request.put(`sys/printer/template/${ params.template_id }`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除小票打印模板
|
||||
* @param template_id
|
||||
* @returns
|
||||
*/
|
||||
export function deletePrinterTemplate(template_id: number) {
|
||||
return request.delete(`sys/printer/template/${ template_id }`, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取小票打印模板类型
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getPrinterType(params: Record<string, any>) {
|
||||
return request.get(`sys/printer/type`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取小票打印机设备品牌
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getPrinterBrand(params: Record<string, any>) {
|
||||
return request.get(`sys/printer/brand`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新打印机token
|
||||
* @param printer_id 小票打印机printer_id
|
||||
* @returns
|
||||
*/
|
||||
export function refreshPrinterToken(printer_id: number) {
|
||||
return request.put(`sys/printer/refreshtoken/${ printer_id }`,{},{
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试打印
|
||||
* @param printer_id 小票打印机printer_id
|
||||
* @returns
|
||||
*/
|
||||
export function testPrint(printer_id: number) {
|
||||
return request.put(`sys/printer/testprint/${ printer_id }`, {},{ showErrorMessage: true, showSuccessMessage: true });
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印小票内容
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function printTicket(params: Record<string, any>) {
|
||||
return request.post('sys/printer/printticket', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
//包含站点管理,站点用户管理,站点操作日志
|
||||
// 包含站点管理,站点用户管理,站点操作日志
|
||||
|
||||
/***************************************************** 站点管理 ****************************************************/
|
||||
|
||||
@ -69,7 +69,6 @@ export function getStatusList() {
|
||||
return request.get(`site/statuslist`)
|
||||
}
|
||||
|
||||
|
||||
/***************************************************** 站点分组管理 ****************************************************/
|
||||
|
||||
/**
|
||||
@ -167,7 +166,6 @@ export function editUser(params: Record<string, any>) {
|
||||
return request.put(`site/user/${params.uid}`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 锁定用户
|
||||
* @param uid
|
||||
@ -177,7 +175,6 @@ export function lockUser(uid: number) {
|
||||
return request.put(`site/user/lock/${uid}`)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 解锁用户
|
||||
* @param uid
|
||||
@ -187,7 +184,6 @@ export function unlockUser(uid: number) {
|
||||
return request.put(`site/user/unlock/${uid}`)
|
||||
}
|
||||
|
||||
|
||||
/***************************************************** 操作日志 **************************************************/
|
||||
|
||||
/**
|
||||
|
||||
@ -13,5 +13,4 @@ export function getStatInfo() {
|
||||
*/
|
||||
export function getSiteStatInfo() {
|
||||
return request.get(`stat/siteindex`)
|
||||
}
|
||||
|
||||
}
|
||||
@ -138,7 +138,6 @@ export function getMenuByTypeDir(key: any = 'system') {
|
||||
return request.get(`sys/menu/dir/${key}`)
|
||||
}
|
||||
|
||||
|
||||
/***************************************************** 站点菜单 ****************************************************/
|
||||
|
||||
/**
|
||||
@ -149,7 +148,6 @@ export function getSiteMenus() {
|
||||
return request.get(`site/site/menu`)
|
||||
}
|
||||
|
||||
|
||||
/***************************************************** 设置 ****************************************************/
|
||||
|
||||
/**
|
||||
@ -279,20 +277,6 @@ export function getAuthMenu() {
|
||||
return request.get(`auth/site/showmenu`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取快捷菜单
|
||||
*/
|
||||
export function getShortcutMenu() {
|
||||
return request.get(`sys/config/shortcut_menu`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加快捷菜单
|
||||
*/
|
||||
export function setShortcutMenu(params: Record<string, any>) {
|
||||
return request.put(`sys/config/shortcut_menu`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取图标库分类列表
|
||||
* @param params
|
||||
@ -336,7 +320,6 @@ export function getAreatree(level: number = 1) {
|
||||
return request.get(`sys/area/tree/${level}`)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取地址信息
|
||||
*/
|
||||
@ -528,7 +511,6 @@ export function getChannelType() {
|
||||
return request.get(`sys/channel`);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取渠道域名
|
||||
* @returns
|
||||
@ -569,13 +551,12 @@ export function setPatConfig(params: Record<string, any>) {
|
||||
return request.post(`pay/channel/set/all`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
|
||||
/***************************************************** 刷新菜单 ****************************************************/
|
||||
/**
|
||||
* 刷新菜单
|
||||
*/
|
||||
export function menuRefresh(params: Record<string, any>) {
|
||||
return request.post(`sys/menu/refresh`, {}, { showSuccessMessage: true })
|
||||
return request.post(`sys/menu/refresh`, {})
|
||||
}
|
||||
|
||||
/**
|
||||
@ -585,7 +566,6 @@ export function clearSchemaCache(params: Record<string, any>) {
|
||||
return request.post(`sys/schema/clear`, {}, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
|
||||
/***************************************************** 获取应用 ****************************************************/
|
||||
/**
|
||||
* 获取应用
|
||||
@ -610,21 +590,6 @@ export function getMap() {
|
||||
return request.get(`sys/config/map`)
|
||||
}
|
||||
|
||||
/***************************************************** 首页 ****************************************************/
|
||||
/**
|
||||
* 获取首页列表
|
||||
*/
|
||||
export function getIndexList() {
|
||||
return request.get(`sys/config/site_index`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置首页模版
|
||||
*/
|
||||
export function setIndexList(params: Record<string, any>) {
|
||||
return request.put(`sys/config/site_index`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取支付待审核记录
|
||||
*/
|
||||
@ -662,13 +627,6 @@ export function getAddonList() {
|
||||
return request.get(`app/getAddonList`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取手机端首页列表
|
||||
*/
|
||||
export function getWapIndexList(params: Record<string, any>) {
|
||||
return request.get('sys/config/wap_index', { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取开发者key
|
||||
* @returns
|
||||
@ -686,7 +644,6 @@ export function setDeveloperToken(params: Record<string, any>) {
|
||||
return request.put(`sys/config/developer_token`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取布局设置
|
||||
* @returns
|
||||
@ -729,7 +686,6 @@ export function setThemecolor(params: Record<string, any>) {
|
||||
return request.put(`sys/config/themecolor`, params)
|
||||
}
|
||||
|
||||
|
||||
/***************************************************** 报表导出 ****************************************************/
|
||||
|
||||
/**
|
||||
|
||||
@ -40,6 +40,15 @@ export function getAllUserList(params: Record<string, any>) {
|
||||
return request.get(`user/user_all`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取添加站点可选用户列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getUserListSelect(params: Record<string, any>) {
|
||||
return request.get(`user/user_select`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户名是否存在
|
||||
* @param username
|
||||
@ -51,7 +60,7 @@ export function checkUsernameIsExist(username: string) {
|
||||
|
||||
/**
|
||||
* 获取用户站点创建限制
|
||||
* @param params
|
||||
* @param uid
|
||||
*/
|
||||
export function getUserCreateSiteLimit(uid: number) {
|
||||
return request.get(`user/user/create_site_limit/${uid}`)
|
||||
@ -83,7 +92,7 @@ export function editUserCreateSiteLimit(params: Record<string, any>) {
|
||||
|
||||
/**
|
||||
* 编辑用户站点创建限制
|
||||
* @param params
|
||||
* @param id
|
||||
*/
|
||||
export function delUserCreateSiteLimit(id: number) {
|
||||
return request.delete(`user/user/create_site_limit/${id}`, { showSuccessMessage: true })
|
||||
|
||||
@ -34,7 +34,6 @@ export function getVerifierList(params: Record<string, any>) {
|
||||
|
||||
/**
|
||||
* 获取核销员列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getVerifierSelect() {
|
||||
|
||||
@ -49,7 +49,6 @@ export function getTemplateList() {
|
||||
return request.get('wechat/template')
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取同步
|
||||
* @param params
|
||||
@ -131,7 +130,6 @@ export function getMediaList(params: Record<string, any>) {
|
||||
return request.get('wechat/media', { params })
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 同步素材库
|
||||
*/
|
||||
|
||||
BIN
admin/src/app/assets/images/default_headimg_square.jpg
Normal file
BIN
admin/src/app/assets/images/default_headimg_square.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 14 KiB |
@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<el-dialog v-model="showDialog" :title="t('upgrade.title')" width="850px" :close-on-click-modal="false"
|
||||
:close-on-press-escape="false" :before-close="dialogClose">
|
||||
<el-dialog v-model="showDialog" :title="t('upgrade.title')" width="850px" :close-on-click-modal="false" :close-on-press-escape="false" :before-close="dialogClose">
|
||||
|
||||
<div v-show="active == 'content'">
|
||||
|
||||
@ -117,6 +116,8 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref, h, watch } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getVersions } from '@/app/api/auth'
|
||||
import { getFrameworkVersionList } from '@/app/api/module'
|
||||
import { getUpgradeContent, getUpgradeTask, upgradeAddon, executeUpgrade, preUpgradeCheck, clearUpgradeTask } from '@/app/api/upgrade'
|
||||
import { Terminal, TerminalFlash } from 'vue-web-terminal'
|
||||
import 'vue-web-terminal/lib/theme/dark.css'
|
||||
@ -209,6 +210,14 @@ const elNotificationClick = () => {
|
||||
notificationEl && notificationEl.close()
|
||||
}
|
||||
|
||||
const versions = ref('')
|
||||
const getVersionsInfo = () => {
|
||||
getVersions().then(res => {
|
||||
versions.value = res.data.version.version
|
||||
})
|
||||
}
|
||||
getVersionsInfo()
|
||||
|
||||
/**
|
||||
* 执行升级
|
||||
*/
|
||||
@ -218,19 +227,17 @@ const handleUpgrade = async () => {
|
||||
|
||||
const appKey = upgradeContent.value?.app.app_key != 'niucloud-admin' ? upgradeContent.value?.app.app_key : ''
|
||||
|
||||
await preUpgradeCheck(appKey)
|
||||
.then(async ({ data }) => {
|
||||
if (data.is_pass) {
|
||||
await upgradeAddon(appKey).then(() => {
|
||||
getUpgradeTaskFn()
|
||||
}).catch(() => {
|
||||
uploading.value = false
|
||||
})
|
||||
} else {
|
||||
upgradeCheck.value = data
|
||||
}
|
||||
})
|
||||
.catch()
|
||||
await preUpgradeCheck(appKey).then(async({ data }) => {
|
||||
if (data.is_pass) {
|
||||
await upgradeAddon(appKey).then(() => {
|
||||
getUpgradeTaskFn()
|
||||
}).catch(() => {
|
||||
uploading.value = false
|
||||
})
|
||||
} else {
|
||||
upgradeCheck.value = data
|
||||
}
|
||||
}).catch()
|
||||
|
||||
if (uploading.value) active.value = 'upgrade'
|
||||
}
|
||||
@ -240,18 +247,26 @@ const open = (addonKey: string = '') => {
|
||||
ElMessage({ message: '已有正在执行中的升级任务', type: 'error' })
|
||||
showDialog.value = true
|
||||
} else {
|
||||
getUpgradeContent(addonKey).then(({ data }) => {
|
||||
upgradeContent.value = data
|
||||
if (!data.version_list.length) {
|
||||
ElMessage({ message: '已经是最新版本了', type: 'error' })
|
||||
getFrameworkVersionList().then(({ data }) => {
|
||||
const newVersion = data.length ? data[0] : null
|
||||
if (addonKey && newVersion && newVersion.version_no !== versions.value) {
|
||||
ElMessage({ message: '存在新版本框架,请先升级框架', type: 'error' })
|
||||
return
|
||||
}
|
||||
if (Storage.get('upgradeTipsLock')) {
|
||||
showDialog.value = true
|
||||
} else {
|
||||
upgradeTipsShowDialog.value = true
|
||||
getUpgradeContent(addonKey).then(({ data }) => {
|
||||
upgradeContent.value = data
|
||||
if (!data.version_list.length) {
|
||||
ElMessage({ message: '已经是最新版本了', type: 'error' })
|
||||
return
|
||||
}
|
||||
if (Storage.get('upgradeTipsLock')) {
|
||||
showDialog.value = true
|
||||
} else {
|
||||
upgradeTipsShowDialog.value = true
|
||||
}
|
||||
}).catch()
|
||||
}
|
||||
}).catch()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<el-dialog v-model="dialogVisible" :title="t('accountSettings')" width="500">
|
||||
<el-form :model="saveInfo" label-width="90px" ref="formRef" class="page-form">
|
||||
<el-form-item :label="t('headImg')">
|
||||
<upload-image v-model="saveInfo.head_img" :limit="1" :type="'avatar'" />
|
||||
<upload-image v-model="saveInfo.head_img" :limit="1" :type="'avatar'" imageFit="cover" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('userName')">
|
||||
<span>{{saveInfo.username}}</span>
|
||||
@ -77,5 +77,4 @@ defineExpose({
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
|
||||
@ -14,5 +14,6 @@
|
||||
"updateCode": "重新绑定",
|
||||
"notHaveAuth": "还没有授权?去购买",
|
||||
"authInfoTips": "授权码和授权秘钥可在Niucloud官网我的授权 授权详情中查看",
|
||||
"cloudBuildTips": "是否要进行云编译该操作可能会影响到正在访问的客户是否要继续操作?"
|
||||
"cloudBuildTips": "是否要进行云编译该操作可能会影响到正在访问的客户是否要继续操作?",
|
||||
"versionTips":"已经升级到最新版本"
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"pageContent": "页面内容",
|
||||
"statusBarContent": "导航栏内容",
|
||||
"statusBarStyle": "导航栏样式",
|
||||
"statusBarSwitchTips": "此处控制当前页面导航栏是否显示",
|
||||
"bottomNavContent": "底部导航内容",
|
||||
"diyPageTitle": "页面名称",
|
||||
"diyPageTitlePlaceholder": "请输入页面名称",
|
||||
@ -104,8 +105,7 @@
|
||||
"titleStyle": "标题样式",
|
||||
"selectStyle": "风格选择",
|
||||
"styleLabel": "风格",
|
||||
"styleShowTips": "风格 1 2 3 5 6,仅在小程序中展示",
|
||||
"topStatusBarBgColorTips": "当导航栏样式为风格5且页面滚动时,背景颜色会跟随顶部颜色的设置而改变",
|
||||
"styleShowTips": "风格 1 2 3,仅在小程序中展示",
|
||||
"titleContent": "标题内容",
|
||||
"title": "标题名称",
|
||||
"titlePlaceholder": "请输入标题",
|
||||
@ -206,6 +206,7 @@
|
||||
"carouselSearchHotWordTextPlaceholder": "请输入热词",
|
||||
"carouselSearchAddHotWordItem": "添加一个热词",
|
||||
"carouselSearchLogoTips": "建议尺寸,70px * 30px",
|
||||
"carouselSearchTextTips": "搜索内容是默认展示数据,当添加搜索热词时,搜索内容隐藏; 当没有搜索热词时,搜索内容展示",
|
||||
"carouselSearchPlaceholder": "请输入搜索内容",
|
||||
"carouselSearchTabSet": "选项卡设置",
|
||||
"carouselSearchTabControl": "展示开关",
|
||||
@ -249,9 +250,10 @@
|
||||
"topStatusBarNav": "导航栏",
|
||||
"topStatusBarNavTips": "此处控制当前页面导航栏是否显示",
|
||||
"topStatusBarImgTips": "宽度自适应(最大150px),高度28px",
|
||||
"topStatusBarIsTransparent": "顶部透明",
|
||||
"topStatusBarTextColor": "标题颜色",
|
||||
"topStatusBarBgColor": "顶部颜色",
|
||||
"topStatusBarBgColor": "头部颜色",
|
||||
"rollTopStatusBarBgColor": "滚动后头部颜色",
|
||||
"rollTopStatusBarTextColor": "滚动后标题颜色",
|
||||
"topStatusBarSearchName": "搜索内容",
|
||||
"topStatusBarSearchNamePlaceholder": "请输入搜索关键词",
|
||||
"settingTips": "点击查看如何配置"
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
"title": "页面名称",
|
||||
"typeName": "页面类型",
|
||||
"forAddon": "所属应用",
|
||||
"forAddonPlaceholder": "请选择所属应用",
|
||||
"addPageTips": "创建新页面",
|
||||
"pageTypePlaceholder": "请选择页面类型",
|
||||
"nameMax": "名称不能超过12个字符",
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
{
|
||||
"title": "页面名称",
|
||||
"forAddon": "所属插件",
|
||||
"forAddon": "所属应用",
|
||||
"forAddonPlaceholder": "请选择所属应用",
|
||||
"all": "全部",
|
||||
"wapUrl": "wap链接",
|
||||
"weappUrl": "小程序链接",
|
||||
|
||||
@ -1,67 +0,0 @@
|
||||
{
|
||||
"todayData": "实时概况",
|
||||
"memberNumb": "新增会员数(人)",
|
||||
"orderMoney": "订单金额(元)",
|
||||
"numberOfSites": "站点数量",
|
||||
"numberOfVisitors": "今日访客数(人)",
|
||||
"commonlyUsedFunction": "常用功能",
|
||||
"articleList": "文章列表",
|
||||
"memberManagement": "会员管理",
|
||||
"balanceAccount": "余额账户",
|
||||
"administrator": "管理员",
|
||||
"WebDecoration": "网站装修",
|
||||
"accessMessage": "访问消息",
|
||||
"memberDistribution": "会员分布",
|
||||
"systemInfo": "系统环境",
|
||||
"os": "操作系统",
|
||||
"phpVersions": "PHP版本号",
|
||||
"productionEnvironment": "生产环境",
|
||||
"versionsInfo": "版本信息",
|
||||
"versions": "当前版本",
|
||||
"frame": "基于框架",
|
||||
"channel": "获取渠道",
|
||||
"serviceSupport": "服务支持",
|
||||
"officialWbsite": "官网",
|
||||
"pageView": "访客数(人)",
|
||||
"siteInfo":"站点信息",
|
||||
"siteName":"站点名称",
|
||||
"groupName":"站点套餐",
|
||||
"expireTime":"过期时间",
|
||||
"permanent":"永久",
|
||||
"statusName":"站点状态",
|
||||
"orderNumber": "订单数(笔)",
|
||||
"wechatCode": "公众号二维码",
|
||||
"wechatCodeDesc": "微信扫码关注",
|
||||
"enterpriseWechatCode": "客服二维码",
|
||||
"enterpriseWechatCodeDesc": "扫码联系客服",
|
||||
"tel": "服务热线:",
|
||||
"message": "请联系客服",
|
||||
"messageTitle": "提示",
|
||||
"accumulative":"累计",
|
||||
"officialAccount": "Niucloud官方公众号",
|
||||
"officialAccountDesc": "微信扫码关注",
|
||||
"WeCom": "添加企业微信群",
|
||||
"path": "地址",
|
||||
"menuName": "名称",
|
||||
"menuNamePlaceholder": "模版名称",
|
||||
"menuBgColor": "背景颜色",
|
||||
"menuImg": "选择图标",
|
||||
"menuDesc": "描述",
|
||||
"addShortcutMenu": "添加快捷模版",
|
||||
"appTemplate": "应用模块",
|
||||
"siteType": "站点类型",
|
||||
"periodTime": "有效期",
|
||||
"renew": "续费",
|
||||
"selectModel": "选择模块",
|
||||
"addMenu": "添加模块",
|
||||
"shortcutLink": "模版",
|
||||
"emptyMenu": "暂无快捷模块",
|
||||
"select": "选择",
|
||||
"custom": "自定义",
|
||||
"accessSite": "访问站点",
|
||||
"pathSelect": "选择模块",
|
||||
"bgColorPlaceholder": "请选择背景色",
|
||||
"iconPlaceholder": "请选择图标",
|
||||
"pathPlaceholder": "请选择链接",
|
||||
"descPlaceholder": "输入描述语…"
|
||||
}
|
||||
@ -72,5 +72,5 @@
|
||||
"newVersion": "最新版本",
|
||||
"cloudBuild": "云编译",
|
||||
"cloudBuildTips": "是否要进行云编译该操作可能会影响到正在访问的客户是否要继续操作?",
|
||||
"deleteAddonTips": "确定要删除该插件吗?"
|
||||
"deleteAddonTips": "删除插件会把插件目录连同文件全部删除,确定要删除吗?"
|
||||
}
|
||||
|
||||
@ -42,8 +42,8 @@
|
||||
"doubleCipherHint": "输入的两次密码不一致",
|
||||
"memberNoHint":"会员编号只能输入字母和数字",
|
||||
"mobileHint": "请输入正确的手机号!",
|
||||
"lable": "标签",
|
||||
"setLable": "标签",
|
||||
"memberLabelTag": "标签",
|
||||
"setLabel": "标签",
|
||||
"notAvailable": "暂无",
|
||||
"memberLabelPlaceholder": "请选择会员标签",
|
||||
"memberInfo":"会员信息",
|
||||
|
||||
@ -47,5 +47,15 @@
|
||||
"polygon": "多边形",
|
||||
"angle": "旋转角度",
|
||||
"nickName": "昵称",
|
||||
"needLoginTips": "前台需要登录才会展示"
|
||||
"needLoginTips": "前台需要登录才会展示",
|
||||
"horizontalAlignment": "水平对齐方式",
|
||||
"verticalAlignment": "垂直对齐方式",
|
||||
"AlignTips": "当设置文本水平对齐方式时,其内容也会随之改变",
|
||||
"lineHeight": "行高",
|
||||
"textAlign": "文字居中方式",
|
||||
"space": "字间距",
|
||||
"weight": "文字加粗",
|
||||
"imgShape": "图片形状"
|
||||
|
||||
|
||||
}
|
||||
26
admin/src/app/lang/zh-cn/printer.edit.json
Normal file
26
admin/src/app/lang/zh-cn/printer.edit.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"printerSet": "打印机设置",
|
||||
"printerName": "打印机名称",
|
||||
"printerNamePlaceholder": "请输入打印机名称",
|
||||
"brand": "设备品牌",
|
||||
"brandPlaceholder": "请选择设备品牌",
|
||||
"printerCode": "打印机编号",
|
||||
"printerCodePlaceholder": "请输入打印机编号",
|
||||
"printerCodeTips": "易联云打印机背面的终端号",
|
||||
"printerKey": "打印机秘钥",
|
||||
"printerKeyPlaceholder": "请输入打印机秘钥",
|
||||
"printerKeyTips": "易联云打印机背面的密钥",
|
||||
"openId": "开发者id",
|
||||
"openIdPlaceholder": "请输入开发者id",
|
||||
"openIdTips": "应用ID(易联云-开发者中心后台应用中心里获取)",
|
||||
"apikey": "开发者密钥",
|
||||
"apikeyPlaceholder": "请输入开发者密钥",
|
||||
"apikeyTips": "应用密钥(易联云-开发者中心后台应用中心里获取)",
|
||||
"printWidth": "纸张宽度",
|
||||
"printWidthPlaceholder": "请输入纸张宽度",
|
||||
"status": "状态",
|
||||
"printTrigger": "打印时机",
|
||||
"usePrintTemplate": "选择模板",
|
||||
"printNum": "打印联数",
|
||||
"printTypeEmpty": "缺少打印模板类型"
|
||||
}
|
||||
19
admin/src/app/lang/zh-cn/printer.list.json
Normal file
19
admin/src/app/lang/zh-cn/printer.list.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"tabPrinterManager": "打印机管理",
|
||||
"tabPrinterTemplate": "打印模板",
|
||||
"printerName": "打印机名称",
|
||||
"printerNamePlaceholder": "请输入打印机名称",
|
||||
"brand": "设备品牌",
|
||||
"printWidth": "纸张宽度",
|
||||
"status": "状态",
|
||||
"statusOn": "启用",
|
||||
"statusOff": "禁用",
|
||||
"createTime": "创建时间",
|
||||
"addPrinter": "添加打印机",
|
||||
"updatePrinter": "编辑打印机",
|
||||
"printerDeleteTips": "确定要删除该数据吗?",
|
||||
"testPrint": "测试打印",
|
||||
"testPrintTips": "确定测试打印吗",
|
||||
"refreshToken": "授权",
|
||||
"refreshTokenTips": "若易联云打印机在 [测试打印] 时提示 access_token过期或错误,请重新授权,是否重新授权"
|
||||
}
|
||||
11
admin/src/app/lang/zh-cn/printer.template_edit.json
Normal file
11
admin/src/app/lang/zh-cn/printer.template_edit.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"templateInfoLabel": "模板信息",
|
||||
"templateName": "模板名称",
|
||||
"templateNamePlaceholder": "请输入模板名称",
|
||||
"templateType": "模板类型",
|
||||
"printTypeEmpty": "缺少打印模板类型",
|
||||
"templateTypePlaceholder": "请选择模板类型",
|
||||
"templateEditLabel": "模板编辑",
|
||||
"preview": "预览图",
|
||||
"printTemplateEmpty": "打印模板不存在"
|
||||
}
|
||||
11
admin/src/app/lang/zh-cn/printer.template_list.json
Normal file
11
admin/src/app/lang/zh-cn/printer.template_list.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"tabPrinterManager": "打印机管理",
|
||||
"tabPrinterTemplate": "打印模板",
|
||||
"templateName": "模板名称",
|
||||
"templateNamePlaceholder": "请输入模板名称",
|
||||
"templateType": "模板类型",
|
||||
"templateTypePlaceholder": "请选择模板类型",
|
||||
"createTime": "创建时间",
|
||||
"addPrinterTemplate": "添加小票打印模板",
|
||||
"printerTemplateDeleteTips": "确定要删除该数据吗?"
|
||||
}
|
||||
@ -6,8 +6,8 @@
|
||||
"isBindMobile": "强制绑定手机",
|
||||
"isUsernameTip": "开启之后可以使用账号+密码进行注册和登录",
|
||||
"isMobileTip": "开启之后可以使用手机+验证码进行注册和登录",
|
||||
"isAuthRegisterTip": "开启之后,微信公众号、小程序等等第三方平台可以自动注册会员。方便会员自动登录",
|
||||
"isBindMobileTip": "开启之后,会员通过账号或者第三方注册账户会强制绑定手机号,方便商家进行管理,同时方便会员在不同端口统一账号",
|
||||
"isAuthRegisterTip": "开启之后,微信公众号、小程序等第三方平台可以自动注册会员。方便会员自动登录",
|
||||
"isBindMobileTip": "开启之后,会员通过普通注册方式会强制绑定手机号,同时在相关页面也会引导会员强制绑定手机账号,否则影响功能正常使用,也方便商家进行管理,同时方便会员在不同端口统一账号",
|
||||
"agreement": "政策协议",
|
||||
"agreementTips": "注册时服务协议和隐私协议是否进行展示",
|
||||
"mobileOrUsernameNoEmpty":"普通注册方式至少需启用一种",
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
{
|
||||
"siteId":"站点id",
|
||||
"noticeKey":"消息模板",
|
||||
"noticeKeyPlaceholder":"请选择消息模板",
|
||||
"noticeType":"消息类型",
|
||||
"noticeInfo":"消息详情",
|
||||
"uid":"通知的用户id",
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
{
|
||||
"siteId":"站点id",
|
||||
"noticeKey":"消息模板",
|
||||
"noticeKeyPlaceholder":"请选择消息模板",
|
||||
"noticeType":"消息类型",
|
||||
"noticeInfo":"消息详情",
|
||||
"uid":"通知的用户id",
|
||||
|
||||
@ -33,5 +33,6 @@
|
||||
"siteDomain": "站点域名",
|
||||
"siteDomainPlaceholder": "请输入站点域名",
|
||||
"siteDomainTips": "站点域名的配置是针对站点的wap和web端",
|
||||
"siteDomainTipsTwo": "需要将域名配置到您的服务器,同时域名需要解析您的服务器才可生效"
|
||||
"siteDomainTipsTwo": "需要将域名配置到您的服务器,同时域名需要解析您的服务器才可生效",
|
||||
"siteDomainTipsThree": "站点域名不需要加http或者https,末尾不需要加/"
|
||||
}
|
||||
|
||||
@ -108,8 +108,8 @@
|
||||
import { reactive, ref, computed } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getVersions } from '@/app/api/auth'
|
||||
import { getAuthinfo, setAuthinfo, getFrameworkVersionList } from '@/app/api/module'
|
||||
import { ElMessageBox, FormInstance, FormRules } from 'element-plus'
|
||||
import { getAuthInfo, setAuthInfo, getFrameworkVersionList } from '@/app/api/module'
|
||||
import { ElMessageBox, FormInstance, FormRules,ElMessage } from 'element-plus'
|
||||
import Upgrade from '@/app/components/upgrade/index.vue'
|
||||
import CloudBuild from '@/app/components/cloud-build/index.vue'
|
||||
|
||||
@ -121,9 +121,20 @@ const authCodeApproveDialog = ref(false)
|
||||
const isCheck = ref(false)
|
||||
const frameworkVersionList = ref([])
|
||||
|
||||
const checkVersion = ref(false)
|
||||
const getFrameworkVersionListFn = () => {
|
||||
getFrameworkVersionList().then(({ data }) => {
|
||||
frameworkVersionList.value = data
|
||||
if (checkVersion.value) {
|
||||
if (!newVersion.value || (newVersion.value && newVersion.value.version_no == versions.value)) {
|
||||
ElMessage({
|
||||
message: t('versionTips'),
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
} else {
|
||||
checkVersion.value = true
|
||||
}
|
||||
})
|
||||
}
|
||||
getFrameworkVersionListFn()
|
||||
@ -156,7 +167,7 @@ const authinfo = ref<AuthInfo>({
|
||||
const loading = ref(true)
|
||||
const saveLoading = ref(false)
|
||||
const checkAppMange = () => {
|
||||
getAuthinfo().then((res) => {
|
||||
getAuthInfo().then((res) => {
|
||||
loading.value = false
|
||||
if (res.data.data && res.data.data.length != 0) {
|
||||
authinfo.value = res.data.data
|
||||
@ -193,7 +204,7 @@ const save = async (formEl: FormInstance | undefined) => {
|
||||
if (valid) {
|
||||
saveLoading.value = true
|
||||
|
||||
setAuthinfo(formData).then(() => {
|
||||
setAuthInfo(formData).then(() => {
|
||||
saveLoading.value = false
|
||||
checkAppMange()
|
||||
}).catch(() => {
|
||||
@ -220,7 +231,7 @@ getVersionsInfo()
|
||||
* 升级
|
||||
*/
|
||||
const handleUpgrade = () => {
|
||||
if (!authinfo.value) {
|
||||
if (!authinfo.value.auth_code) {
|
||||
authCodeApproveFn()
|
||||
return
|
||||
}
|
||||
@ -228,7 +239,7 @@ const handleUpgrade = () => {
|
||||
}
|
||||
|
||||
const handleCloudBuild = () => {
|
||||
if (!authinfo.value) {
|
||||
if (!authinfo.value.auth_code) {
|
||||
authCodeApproveFn()
|
||||
return
|
||||
}
|
||||
|
||||
@ -8,22 +8,20 @@
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap plug-list pb-10 plug-large" v-if="appList.length">
|
||||
<div v-for="(item, index) in appList" :key="index + 'b'">
|
||||
<div class="relative cursor-pointer mt-[20px] mr-4 px-4 border-br-light border-[1px] bg-[var(--el-color-info-light-9)] hover:border-primary">
|
||||
<div @click="toLink(item.key)" class="flex py-5 items-center">
|
||||
<div class="flex justify-center items-center">
|
||||
<el-image class="w-[40px] h-[40px]" :src="img(item.icon)" fit="contain">
|
||||
<template #error>
|
||||
<div class="image-slot">
|
||||
<img class="w-[50px] h-[50px]" src="@/app/assets/images/index/app_default.png" />
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
</div>
|
||||
<div class="flex flex-col justify-between text-left w-[190px]">
|
||||
<p class="app-text w-[190px] text-[17px] pl-3">{{ item.title }}</p>
|
||||
<div v-for="(item, index) in appList" :key="index + 'b'" class="app-item relative cursor-pointer mt-[20px] mr-4 bg-[#f7f7f7] w-[264px] flex py-[20px] px-[17px]" @click="toLink(item.key)">
|
||||
<el-image class="w-[40px] h-[40px] mr-[10px]" :src="img(item.icon)" fit="contain">
|
||||
<template #error>
|
||||
<div class="image-slot">
|
||||
<img class="w-[50px] h-[50px]" 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]">{{ item.title }}</span>
|
||||
<span class="iconfont iconxiaochengxu2 text-[#00b240] ml-[4px] !text-[14px]"></span>
|
||||
</div>
|
||||
<p class="app-text text-[12px] text-[#999]">{{item.desc}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -69,4 +67,8 @@ const toLink = (addon: string) => {
|
||||
text-overflow: ellipsis;
|
||||
/* 显示省略号 */
|
||||
}
|
||||
.app-item:hover{
|
||||
transition: 0.5s;
|
||||
box-shadow: 0px 2px 8px 0px rgba(0,0,0,0.1);
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -2,10 +2,10 @@
|
||||
<el-dialog v-model="showDialog" :title="popTitle" width="500px" :destroy-on-close="true">
|
||||
<el-form :model="formData" label-width="90px" class="page-form" ref="formRef" :rules="formRules" v-loading="loading">
|
||||
<el-form-item :label="t('menuName')" prop="menu_name">
|
||||
<el-input v-model="formData.menu_name" :placeholder="t('menuNamePlaceholder')" class="input-width" />
|
||||
<el-input v-model.trim="formData.menu_name" maxlength="10" show-word-limit :placeholder="t('menuNamePlaceholder')" class="input-width" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('menuKey')" prop="menu_key" v-if="!formData.id">
|
||||
<el-input v-model="formData.menu_key" :placeholder="t('menuKeyPlaceholder')" class="input-width" />
|
||||
<el-input v-model.trim="formData.menu_key" maxlength="50" show-word-limit :placeholder="t('menuKeyPlaceholder')" class="input-width" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('menuType')">
|
||||
@ -17,8 +17,8 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('addon')" prop="addon" v-show="formData.app_type == 'site'">
|
||||
<el-select v-model="formData.addon" placeholder="Select" class="input-width" @change="addonChange">
|
||||
<el-option v-for="(item, index) in addonLst" :label="item.title" :value="item.key" :key="index" />
|
||||
<el-select v-model="formData.addon" :placeholder="t('addon')" class="input-width" @change="addonChange">
|
||||
<el-option v-for="(item, index) in addonList" :label="item.title" :value="item.key" :key="index" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
@ -77,7 +77,7 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('sort')">
|
||||
<el-input-number v-model="formData.sort" :min="0" />
|
||||
<el-input-number v-model="formData.sort" :min="0" max="99999999" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
@ -124,7 +124,7 @@ const initialFormData = {
|
||||
}
|
||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||
|
||||
const addonLst = ref<Array<any>>([])
|
||||
const addonList = ref<Array<any>>([])
|
||||
const sysMenuList = ref<Array<any>>([])
|
||||
const addonMenuList = ref<Array<any>>([])
|
||||
const formRef = ref<FormInstance>()
|
||||
@ -167,8 +167,8 @@ const formRules = computed(() => {
|
||||
// 获取插件列表
|
||||
const getAddonDevelopFn = async () => {
|
||||
const { data } = await getAddonDevelop({})
|
||||
addonLst.value = [{ title: '系统', key: '' }]
|
||||
addonLst.value.push(...data)
|
||||
addonList.value = [{ title: '系统', key: '' }]
|
||||
addonList.value.push(...data)
|
||||
}
|
||||
|
||||
// 获取系统菜单列表
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<el-dialog v-model="showDialog" :title="popTitle" width="500px" :destroy-on-close="true">
|
||||
<el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
|
||||
<el-form-item :label="t('roleName')" prop="role_name">
|
||||
<el-input v-model="formData.role_name" :placeholder="t('roleNamePlaceholder')" clearable :disabled="formData.uid" class="input-width" maxlength="10" :show-word-limit="true" />
|
||||
<el-input v-model.trim="formData.role_name" :placeholder="t('roleNamePlaceholder')" clearable :disabled="formData.uid" class="input-width" maxlength="10" :show-word-limit="true" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('status')">
|
||||
@ -95,6 +95,7 @@ const collapseAll = (data:any) => {
|
||||
if (data[key].children && data[key].children.length > 0) collapseAll(data[key].children)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单数据
|
||||
*/
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<el-dialog v-model="showDialog" :title="popTitle" width="500px" :destroy-on-close="true">
|
||||
<el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
|
||||
|
||||
<el-form-item :label="t('accountNumber')" v-if="!formData.uid" prop="uid">
|
||||
<!-- <el-form-item :label="t('accountNumber')" v-if="!formData.uid" prop="uid">
|
||||
<el-select :model-value="uid" :placeholder="t('accountNumberPlaceholder')" class="input-width" filterable clearable :allow-create="true" @change="selectUser" :default-first-option="true">
|
||||
<el-option v-for="item in userList" :key="item.uid" :label="item.username" :value="item.uid">
|
||||
<div class="flex items-center">
|
||||
@ -12,10 +12,10 @@
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form-item> -->
|
||||
|
||||
<el-form-item :label="t('accountNumber')" prop="username" v-else>
|
||||
<el-input v-model="formData.username" :placeholder="t('accountNumberPlaceholder')" clearable :disabled="formData.uid" class="input-width" maxlength="10" show-word-limit />
|
||||
<el-form-item :label="t('accountNumber')" prop="username" >
|
||||
<el-input v-model.trim="formData.username" :placeholder="t('accountNumberPlaceholder')" clearable :disabled="formData.uid" class="input-width" maxlength="10" show-word-limit />
|
||||
</el-form-item>
|
||||
|
||||
<div v-if="needAddUserInfo">
|
||||
@ -24,22 +24,22 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('userRealName')" prop="real_name">
|
||||
<el-input v-model="formData.real_name" :placeholder="t('userRealNamePlaceholder')" :readonly="real_name_input" @click="real_name_input = false" @blur="real_name_input = true" clearable class="input-width" maxlength="10" show-word-limit />
|
||||
<el-input v-model.trim="formData.real_name" :placeholder="t('userRealNamePlaceholder')" :readonly="real_name_input" @click="real_name_input = false" @blur="real_name_input = true" clearable class="input-width" maxlength="10" show-word-limit />
|
||||
</el-form-item>
|
||||
<div v-if="!formData.uid">
|
||||
<el-form-item :label="t('password')" prop="password">
|
||||
<el-input v-model="formData.password" :placeholder="t('passwordPlaceholder')" :readonly="password_input" @click="password_input = false" @blur="password_input = true" type="password" :show-password="true" clearable class="input-width" />
|
||||
<el-input v-model.trim="formData.password" :placeholder="t('passwordPlaceholder')" :readonly="password_input" @click="password_input = false" @blur="password_input = true" type="password" :show-password="true" clearable class="input-width" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('confirmPassword')" prop="confirm_password">
|
||||
<el-input v-model="formData.confirm_password" :placeholder="t('confirmPasswordPlaceholder')" :readonly="confirm_password_input" @click="confirm_password_input = false" @blur="confirm_password_input = true" type="password" :show-password="true" clearable class="input-width" />
|
||||
<el-input v-model.trim="formData.confirm_password" :placeholder="t('confirmPasswordPlaceholder')" :readonly="confirm_password_input" @click="confirm_password_input = false" @blur="confirm_password_input = true" type="password" :show-password="true" clearable class="input-width" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-form-item :label="t('userRoleName')" prop="role_ids" v-if="!formData.userrole.is_admin">
|
||||
<el-select v-model="formData.role_ids" :placeholder="t('userRolePlaceholder')" class="input-width" multiple collapse-tags collapse-tags-tooltip>
|
||||
<el-option :label="item.role_name" :value="item.role_id" v-for="(item, index) in roles" :key="index" />
|
||||
<el-option :label="item.role_name" :value="item.role_id" v-for="(item, index) in roles" :key="index" :disabled="item.disabled" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
@ -179,7 +179,6 @@ const confirm = async (formEl: FormInstance | undefined) => {
|
||||
|
||||
const data = deepClone(toRaw(formData))
|
||||
if (!formData.uid && typeof uid.value == 'number') data.uid = uid.value
|
||||
|
||||
save(data).then(res => {
|
||||
loading.value = false
|
||||
showDialog.value = false
|
||||
|
||||
@ -30,5 +30,4 @@ const menuLevel = computed(() => {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
|
||||
@ -78,7 +78,6 @@ const getMenuList = () => {
|
||||
menusTableData.loading = false
|
||||
menusTableData.data = res.data
|
||||
}).catch(() => {
|
||||
|
||||
})
|
||||
}
|
||||
getMenuList()
|
||||
|
||||
@ -9,8 +9,8 @@
|
||||
|
||||
<div class="flex justify-between items-center mt-[20px]">
|
||||
<el-form :inline="true" :model="userTableData.searchParam" ref="searchFormRef">
|
||||
<el-form-item :label="t('accountNumber')" prop="seach">
|
||||
<el-input v-model="userTableData.searchParam.seach" class="input-width" :placeholder="t('accountNumberPlaceholder')" />
|
||||
<el-form-item :label="t('accountNumber')" prop="search">
|
||||
<el-input v-model="userTableData.searchParam.search" class="input-width" :placeholder="t('accountNumberPlaceholder')" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="loadUserList()">{{ t('search') }}</el-button>
|
||||
@ -107,7 +107,7 @@ const userTableData = reactive({
|
||||
loading: true,
|
||||
data: [],
|
||||
searchParam: {
|
||||
seach: '',
|
||||
search: '',
|
||||
user_type: ''
|
||||
}
|
||||
})
|
||||
@ -131,7 +131,7 @@ const loadUserList = (page: number = 1) => {
|
||||
getUserList({
|
||||
page: userTableData.page,
|
||||
limit: userTableData.limit,
|
||||
username: userTableData.searchParam.seach,
|
||||
username: userTableData.searchParam.search,
|
||||
user_type: userTableData.searchParam.user_type
|
||||
}).then(res => {
|
||||
userTableData.loading = false
|
||||
|
||||
@ -76,7 +76,7 @@
|
||||
|
||||
<el-dialog v-model="failReasonDialogVisible" :title="t('failReason')" width="60%">
|
||||
<el-scrollbar class="h-[60vh] w-full whitespace-pre p-[20px]">
|
||||
{{ failReason }}
|
||||
<div v-html="failReason"></div>
|
||||
</el-scrollbar>
|
||||
</el-dialog>
|
||||
|
||||
@ -97,7 +97,7 @@ import { reactive, ref } from 'vue'
|
||||
import { setWeappVersion, getWeappPreview, getWeappVersionList, getWeappUploadLog, getWeappConfig } from '@/app/api/weapp'
|
||||
import { t } from '@/lang'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { getAuthinfo } from '@/app/api/module'
|
||||
import { getAuthInfo } from '@/app/api/module'
|
||||
import { getAppType } from '@/utils/common'
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
import { AnyObject } from '@/types/global'
|
||||
@ -131,7 +131,7 @@ const form = ref({
|
||||
const uploadSuccessShowDialog = ref(false)
|
||||
const authCode = ref('')
|
||||
|
||||
getAuthinfo().then(res => {
|
||||
getAuthInfo().then(res => {
|
||||
if (res.data.data && res.data.data.auth_code) {
|
||||
authCode.value = res.data.data.auth_code
|
||||
getWeappPreviewImage()
|
||||
@ -279,7 +279,6 @@ const configElMessageBox = () => {
|
||||
}
|
||||
).then(() => {
|
||||
router.push({ path: '/channel/weapp/config' })
|
||||
}).catch((action: string) => {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -132,7 +132,7 @@ import { reactive, ref, watch, computed } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getWeappConfig, setWeappConfig } from '@/app/api/weapp'
|
||||
import { useClipboard } from '@vueuse/core'
|
||||
import { ElMessage, FormInstance, FormRules } from 'element-plus'
|
||||
import { ElMessage, FormInstance } from 'element-plus'
|
||||
import { ArrowLeft } from '@element-plus/icons-vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
|
||||
@ -24,8 +24,7 @@
|
||||
<div v-if="attachment.data.length">
|
||||
<div class="flex flex-wrap" v-if="prop.type != 'news'">
|
||||
<div class="attachment-item mr-[10px] mb-[10px] w-[120px]" v-for="(item, index) in attachment.data" :key="index" @click="selectedFile = item">
|
||||
<div
|
||||
class="attachment-wrap w-full rounded cursor-pointer overflow-hidden relative flex items-center justify-center h-[120px]">
|
||||
<div class="attachment-wrap w-full rounded cursor-pointer overflow-hidden relative flex items-center justify-center h-[120px]">
|
||||
<el-image :src="img(item.value)" fit="contain" v-if="type == 'image'" :preview-src-list="item.image_list" />
|
||||
<video :src="img(item.value)" v-else-if="type == 'video'"></video>
|
||||
<div class="absolute z-[1] flex items-center justify-center w-full h-full inset-0 bg-black bg-opacity-60" v-show="selectedFile.id == item.id">
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
<el-form-item :label="t('keyword')" prop="keyword">
|
||||
<el-input v-model.trim="formData.keyword" :placeholder="t('keywordPlaceholder')" class="input-width" clearable >
|
||||
<template #prepend>
|
||||
<el-select v-model="formData.matching_type" placeholder="Select" style="width: 115px">
|
||||
<el-select v-model="formData.matching_type" style="width: 115px">
|
||||
<el-option :label="t('allMatching')" value="full" />
|
||||
<el-option :label="t('fuzzyMatching')" value="like" />
|
||||
</el-select>
|
||||
|
||||
@ -2,10 +2,10 @@
|
||||
<el-dialog v-model="showDialog" :title="formData.id ? t('updateDict') : t('addDict')" width="480" class="diy-dialog-wrap" :destroy-on-close="true">
|
||||
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
|
||||
<el-form-item :label="t('name')" prop="name">
|
||||
<el-input v-model="formData.name" clearable :placeholder="t('namePlaceholder')" class="input-width" />
|
||||
<el-input v-model.trim="formData.name" clearable maxlength="40" show-word-limit :placeholder="t('namePlaceholder')" class="input-width" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('key')" prop="key">
|
||||
<el-input v-model="formData.key" clearable :placeholder="t('keyPlaceholder')" class="input-width" />
|
||||
<el-input v-model.trim="formData.key" clearable maxlength="40" show-word-limit :placeholder="t('keyPlaceholder')" class="input-width" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('memo')">
|
||||
<el-input v-model="formData.memo" type="textarea" clearable :placeholder="t('memoPlaceholder')" class="input-width" />
|
||||
|
||||
@ -242,6 +242,8 @@ diyStore.editComponent.list.forEach((item: any) => {
|
||||
const showTitleDialog = ref(false)
|
||||
|
||||
const showTitleStyle = () => {
|
||||
selectTitleStyle.title = diyStore.editComponent.titleStyle.title;
|
||||
selectTitleStyle.value = diyStore.editComponent.titleStyle.value;
|
||||
showTitleDialog.value = true
|
||||
}
|
||||
|
||||
|
||||
@ -31,7 +31,10 @@
|
||||
<upload-image v-model="diyStore.editComponent.search.logo" :limit="1" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('carouselSearchText')">
|
||||
<el-input v-model.trim="diyStore.editComponent.search.text" :placeholder="t('carouselSearchPlaceholder')" clearable maxlength="20" show-word-limit />
|
||||
<div>
|
||||
<el-input v-model.trim="diyStore.editComponent.search.text" :placeholder="t('carouselSearchPlaceholder')" clearable maxlength="20" show-word-limit />
|
||||
<p class="text-sm text-gray-400 mt-[10px] leading-[1.5]">{{t('carouselSearchTextTips')}}</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('link')">
|
||||
<diy-link v-model="diyStore.editComponent.search.link"/>
|
||||
|
||||
@ -3,14 +3,41 @@
|
||||
<div class="content-wrap float-btn" v-show="diyStore.editTab == 'content'">
|
||||
|
||||
<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('floatBtnBtton') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('floatBtnBtton')">
|
||||
<span>{{ selectTemplate.name }}</span>
|
||||
<ul class="ml-[10px] flex items-center">
|
||||
<li v-for="(item,i) in templateList" :key="i" :class="['w-[50px] h-[32px] flex items-center justify-center border-solid border-[1px] border-[#eee] cursor-pointer', {'border-r-transparent': templateList.length != (i+1)}, (item.className == diyStore.editComponent.bottomPosition) ? '!border-[var(--el-color-primary)]' : '' ]" @click="changeTemplateList(item)">
|
||||
<span :class="['iconfont', item.src]"></span>
|
||||
</li>
|
||||
<template v-for="(item,i) in templateList" :key="i">
|
||||
<li v-if="diyStore.editComponent.style==='style-1'||(diyStore.editComponent.style==='style-2'&&i>1)" :class="['w-[50px] h-[32px] flex items-center justify-center border-solid border-[1px] border-[#eee] cursor-pointer', {'border-r-transparent': templateList.length != (i+1)}, (item.className == diyStore.editComponent.bottomPosition) ? '!border-[var(--el-color-primary)]' : '' ]" @click="changeTemplateList(item)">
|
||||
<span :class="['iconfont !text-[20px]', item.src]"></span>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('floatBtnOffset')">
|
||||
@ -22,7 +49,7 @@
|
||||
<h3 class="mb-[10px]">{{ t('floatBtnImageSet') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('floatBtnImageSize')">
|
||||
<el-slider v-model="diyStore.editComponent.imageSize" show-input size="small" class="ml-[10px] horz-blank-slider" :min="40" :max="100"/>
|
||||
<el-slider v-model="diyStore.editComponent.imageSize" show-input size="small" class="ml-[10px] horz-blank-slider" :min="30" :max="100"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('floatBtnAroundRadius')">
|
||||
<el-slider v-model="diyStore.editComponent.aroundRadius" show-input size="small" class="ml-[10px] graphic-nav-slider" :max="50"/>
|
||||
@ -59,7 +86,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, onMounted, nextTick } from 'vue'
|
||||
import { ref, reactive, onMounted, nextTick } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import Sortable from 'sortablejs'
|
||||
import useDiyStore from '@/stores/modules/diy'
|
||||
@ -67,7 +94,7 @@ import { img } from '@/utils/common'
|
||||
import { range } from 'lodash-es'
|
||||
|
||||
const diyStore = useDiyStore()
|
||||
diyStore.editComponent.ignore = [] // 忽略公共属性
|
||||
diyStore.editComponent.ignore = ['pageBgColor','marginTop','marginBottom','marginBoth'] // 忽略公共属性
|
||||
|
||||
// 组件验证
|
||||
diyStore.editComponent.verify = (index: number) => {
|
||||
@ -82,30 +109,72 @@ diyStore.editComponent.verify = (index: number) => {
|
||||
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([
|
||||
{
|
||||
name: '左上',
|
||||
src: 'iconzuoshangjiao',
|
||||
src: 'iconzuoshangpc',
|
||||
className: 'upperLeft'
|
||||
},
|
||||
{
|
||||
name: '右上',
|
||||
src: 'iconyoushangjiao',
|
||||
src: 'iconyoushangpc',
|
||||
className: 'upperRight'
|
||||
},
|
||||
{
|
||||
name: '左下',
|
||||
src: 'iconzuoxiajiao',
|
||||
src: 'iconzuoxiapc',
|
||||
className: 'lowerLeft'
|
||||
},
|
||||
{
|
||||
name: '右下',
|
||||
src: 'iconyouxiajiao',
|
||||
src: 'iconyouxiapc',
|
||||
className: 'lowerRight'
|
||||
}
|
||||
])
|
||||
|
||||
let selectTemplate = ref({})
|
||||
const selectTemplate = ref({})
|
||||
templateList.value.forEach((item) => {
|
||||
if (item.className == diyStore.editComponent.bottomPosition) {
|
||||
selectTemplate.value = item
|
||||
|
||||
@ -124,7 +124,7 @@ const handleHeight = (isCalcHeight:boolean = false)=> {
|
||||
}
|
||||
|
||||
const blurImageHeight = () => {
|
||||
diyStore.editComponent.imageHeight = parseInt(diyStore.editComponent.imageHeight)
|
||||
diyStore.editComponent.imageHeight = diyStore.editComponent.imageHeight ? parseInt(diyStore.editComponent.imageHeight) : 0
|
||||
}
|
||||
|
||||
const imageBoxRef = ref()
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
<div :class="['mr-[10px] rounded cursor-pointer w-[100px]', {'border-[1px] border-solid border-[var(--el-color-primary)]': diyStore.editComponent.systemUrl == 'style_2' && diyStore.editComponent.imgType == 'system'}]">
|
||||
<img src="@/app/assets/images/diy/notice/style_2.png" class="px-[10px] py-[5px]" @click="changeStyle('style_2')"/>
|
||||
</div>
|
||||
<div @click="diyStore.editComponent.imgType = 'diy'" :class="['mr-[10px] rounded cursor-pointer diy-upload-img', {'border-[1px] border-solid border-[var(--el-color-primary)]': (diyStore.editComponent.imageUrl && diyStore.editComponent.imgType == 'diy') }]">
|
||||
<div @click.stop="diyStore.editComponent.imgType = 'diy'" :class="['mr-[10px] rounded cursor-pointer diy-upload-img', {'border-[1px] border-solid border-[var(--el-color-primary)]': (diyStore.editComponent.imageUrl && diyStore.editComponent.imgType == 'diy') }]">
|
||||
<upload-image v-model="diyStore.editComponent.imageUrl" :limit="1"/>
|
||||
</div>
|
||||
</div>
|
||||
@ -105,7 +105,6 @@ import useDiyStore from '@/stores/modules/diy'
|
||||
import { ref, watch, onMounted, nextTick } from 'vue'
|
||||
import { range } from 'lodash-es'
|
||||
import Sortable from 'sortablejs'
|
||||
|
||||
const diyStore = useDiyStore()
|
||||
diyStore.editComponent.ignore = [] // 忽略公共属性
|
||||
|
||||
@ -148,7 +147,7 @@ watch(
|
||||
if(newValue){
|
||||
diyStore.editComponent.imgType = 'diy';
|
||||
}else{
|
||||
diyStore.editComponent.imgType = 'system';
|
||||
changeStyle('style_1');
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -204,9 +203,7 @@ defineExpose({})
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.operation{
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -13,35 +13,41 @@
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('statusBarContent') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('diyTitle')">
|
||||
<el-input v-model.trim="diyStore.global.title" :placeholder="t('diyTitlePlaceholder')" clearable maxlength="12" show-word-limit/>
|
||||
<div class="text-sm text-gray-400">{{ t('titleTips') }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('selectStyle')" class="display-block">
|
||||
<div class="flex">
|
||||
<span class="text-primary flex-1 cursor-pointer" @click="showStyle">{{diyStore.global.topStatusBar.styleName}}</span>
|
||||
<el-icon>
|
||||
<ArrowRight />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="text-sm text-gray-400 leading-[1.5]">{{ t('styleShowTips') }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('topStatusBarImg')" v-if="['style-2','style-3'].indexOf(diyStore.global.topStatusBar.style) > -1">
|
||||
<upload-image v-model="diyStore.global.topStatusBar.imgUrl" :limit="1" />
|
||||
<div class="text-sm text-gray-400 mt-[10px]">{{ t('topStatusBarImgTips') }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('topStatusBarSearchName')" v-if="'style-3' == diyStore.global.topStatusBar.style">
|
||||
<el-input v-model.trim="diyStore.global.topStatusBar.inputPlaceholder" :placeholder="t('topStatusBarSearchNamePlaceholder')" clearable maxlength="12" show-word-limit/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('textAlign')" v-show="diyStore.global.topStatusBar.style == 'style-1'">
|
||||
<el-radio-group v-model="diyStore.global.topStatusBar.textAlign">
|
||||
<el-radio :label="'left'">{{ t('textAlignLeft') }}</el-radio>
|
||||
<el-radio :label="'center'">{{ t('textAlignCenter') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('link')" v-if="['style-2','style-3'].indexOf(diyStore.global.topStatusBar.style) > -1">
|
||||
<diy-link v-model="diyStore.global.topStatusBar.link" />
|
||||
<el-form-item :label="t('topStatusBarNav')" class="display-block">
|
||||
<el-switch v-model="diyStore.global.topStatusBar.isShow"/>
|
||||
<div class="text-sm text-gray-400">{{ t('statusBarSwitchTips') }}</div>
|
||||
</el-form-item>
|
||||
<template v-if="diyStore.global.topStatusBar.isShow">
|
||||
<el-form-item :label="t('diyTitle')">
|
||||
<el-input v-model.trim="diyStore.global.title" :placeholder="t('diyTitlePlaceholder')" clearable maxlength="12" show-word-limit/>
|
||||
<div class="text-sm text-gray-400">{{ t('titleTips') }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('selectStyle')" class="display-block">
|
||||
<div class="flex">
|
||||
<span class="text-primary flex-1 cursor-pointer" @click="showStyle">{{diyStore.global.topStatusBar.styleName}}</span>
|
||||
<el-icon>
|
||||
<ArrowRight />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="text-sm text-gray-400 leading-[1.5]">{{ t('styleShowTips') }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('topStatusBarImg')" v-if="['style-2','style-3'].indexOf(diyStore.global.topStatusBar.style) > -1">
|
||||
<upload-image v-model="diyStore.global.topStatusBar.imgUrl" :limit="1" />
|
||||
<div class="text-sm text-gray-400 mt-[10px]">{{ t('topStatusBarImgTips') }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('topStatusBarSearchName')" v-if="'style-3' == diyStore.global.topStatusBar.style">
|
||||
<el-input v-model.trim="diyStore.global.topStatusBar.inputPlaceholder" :placeholder="t('topStatusBarSearchNamePlaceholder')" clearable maxlength="12" show-word-limit/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('textAlign')" v-show="diyStore.global.topStatusBar.style == 'style-1'">
|
||||
<el-radio-group v-model="diyStore.global.topStatusBar.textAlign">
|
||||
<el-radio :label="'left'">{{ t('textAlignLeft') }}</el-radio>
|
||||
<el-radio :label="'center'">{{ t('textAlignCenter') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('link')" v-if="['style-2','style-3'].indexOf(diyStore.global.topStatusBar.style) > -1">
|
||||
<diy-link v-model="diyStore.global.topStatusBar.link" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="edit-attr-item-wrap">
|
||||
@ -69,12 +75,6 @@
|
||||
<div class="flex items-center justify-center overflow-hidden w-[32%] h-[100px] mr-[2%] cursor-pointer border bg-gray-50" :class="{ 'border-primary': selectStyle == 'style-4' }" @click="selectStyle = 'style-4'">
|
||||
<img class="max-w-[100%] max-h-[100%]" src="@/app/assets/images/diy/head/nav_style4.jpg" />
|
||||
</div>
|
||||
<div class="flex items-center justify-center overflow-hidden w-[32%] h-[100px] mr-[2%] cursor-pointer border bg-gray-50" :class="{ 'border-primary': selectStyle == 'style-5' }" @click="selectStyle = 'style-5'">
|
||||
<img class="max-w-[100%] max-h-[100%]" src="@/app/assets/images/diy/head/nav_style5.png" />
|
||||
</div>
|
||||
<div class="flex items-center justify-center overflow-hidden w-[32%] h-[100px] cursor-pointer border bg-gray-50" :class="{ 'border-primary': selectStyle == 'style-6' }" @click="selectStyle = 'style-6'">
|
||||
<img class="max-w-[100%] max-h-[100%]" src="@/app/assets/images/diy/head/nav_style6.jpg" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
@ -91,7 +91,7 @@
|
||||
<div class="style-wrap" v-show="diyStore.editTab == 'style'">
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('pageStyle') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form label-width="115px" class="px-[10px]">
|
||||
<el-form-item :label="t('pageBgColor')">
|
||||
<el-color-picker v-model="diyStore.editComponent.pageStartBgColor" show-alpha :predefine="diyStore.predefineColors" />
|
||||
<icon name="iconfont iconmap-connect" size="20px" class="block !text-gray-400 mx-[5px]"/>
|
||||
@ -114,19 +114,24 @@
|
||||
</div>
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('statusBarStyle') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('topStatusBarBgColor')" class="display-block" v-if="selectStyle == 'style-5'">
|
||||
<el-form label-width="115px" class="px-[10px]">
|
||||
<el-form-item :label="t('topStatusBarBgColor')" class="display-block">
|
||||
<el-color-picker v-model="diyStore.global.topStatusBar.bgColor" show-alpha />
|
||||
<div class="text-sm text-gray-400 leading-[1.5]">{{ t('topStatusBarBgColorTips') }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('rollTopStatusBarBgColor')" class="display-block">
|
||||
<el-color-picker v-model="diyStore.global.topStatusBar.rollBgColor" show-alpha />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('topStatusBarTextColor')" class="display-block">
|
||||
<el-color-picker v-model="diyStore.global.topStatusBar.textColor" show-alpha />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('rollTopStatusBarTextColor')" class="display-block">
|
||||
<el-color-picker v-model="diyStore.global.topStatusBar.rollTextColor" show-alpha />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('marginSet') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form label-width="115px" class="px-[10px]">
|
||||
<el-form-item :label="t('marginBoth')">
|
||||
<el-slider v-model="diyStore.global.template.margin.both" show-input size="small" @input="inputBoth" class="ml-[10px] horz-blank-slider"/>
|
||||
</el-form-item>
|
||||
@ -182,8 +187,6 @@ const showStyle = () => {
|
||||
|
||||
const selectStyle = ref("style-1")
|
||||
const changeStyle = () => {
|
||||
diyStore.global.topStatusBar.isShow = true;
|
||||
diyStore.global.topStatusBar.isTransparent = false;
|
||||
switch (selectStyle.value) {
|
||||
case 'style-1':
|
||||
diyStore.global.topStatusBar.styleName = '风格1'
|
||||
@ -197,14 +200,6 @@ const changeStyle = () => {
|
||||
case 'style-4':
|
||||
diyStore.global.topStatusBar.styleName = '风格4'
|
||||
break
|
||||
case 'style-5':
|
||||
diyStore.global.topStatusBar.isTransparent = true;
|
||||
diyStore.global.topStatusBar.styleName = '风格5'
|
||||
break
|
||||
case 'style-6':
|
||||
diyStore.global.topStatusBar.isShow = false;
|
||||
diyStore.global.topStatusBar.styleName = '风格6'
|
||||
break
|
||||
}
|
||||
diyStore.global.topStatusBar.style = selectStyle.value
|
||||
showDialog.value = false
|
||||
|
||||
@ -96,7 +96,7 @@ diyStore.editComponent.verify = (index: number) => {
|
||||
const templateList = ref([
|
||||
{
|
||||
name: '1行2个',
|
||||
src: 'iconyihangliangge',
|
||||
src: 'iconyihang2gepc1',
|
||||
className: 'row1-of2',
|
||||
dimensionScale: [
|
||||
{
|
||||
@ -114,7 +114,7 @@ const templateList = ref([
|
||||
},
|
||||
{
|
||||
name: '1行3个',
|
||||
src: 'iconyihangsange',
|
||||
src: 'iconyihang3gepc',
|
||||
className: 'row1-of3',
|
||||
dimensionScale: [
|
||||
{
|
||||
@ -137,7 +137,7 @@ const templateList = ref([
|
||||
},
|
||||
{
|
||||
name: '1行4个',
|
||||
src: 'iconyihangsige',
|
||||
src: 'iconyihang4gepc',
|
||||
className: 'row1-of4',
|
||||
dimensionScale: [
|
||||
{
|
||||
@ -165,7 +165,7 @@ const templateList = ref([
|
||||
},
|
||||
{
|
||||
name: '2左2右',
|
||||
src: 'iconmofang-liangzuoliangyou',
|
||||
src: 'iconliangzuoliangyoupc',
|
||||
className: 'row2-lt-of2-rt',
|
||||
dimensionScale: [
|
||||
{
|
||||
@ -193,7 +193,7 @@ const templateList = ref([
|
||||
},
|
||||
{
|
||||
name: '1左2右',
|
||||
src: 'iconmofang-yizuoliangyou',
|
||||
src: 'iconyizuoliangyoupc',
|
||||
className: 'row1-lt-of2-rt',
|
||||
dimensionScale: [
|
||||
{
|
||||
@ -216,7 +216,7 @@ const templateList = ref([
|
||||
},
|
||||
{
|
||||
name: '1上2下',
|
||||
src: 'iconmofang-yishangliangxia',
|
||||
src: 'iconyishangliangxiapc',
|
||||
className: 'row1-tp-of2-bm',
|
||||
dimensionScale: [
|
||||
{
|
||||
@ -239,7 +239,7 @@ const templateList = ref([
|
||||
},
|
||||
{
|
||||
name: '1左3右',
|
||||
src: 'iconxuanzemoban-yizuosanyou',
|
||||
src: 'iconyizuosanyoupc',
|
||||
className: 'row1-lt-of1-tp-of2-bm',
|
||||
dimensionScale: [
|
||||
{
|
||||
|
||||
@ -191,10 +191,10 @@
|
||||
<el-slider v-model="diyStore.editComponent.margin.both" show-input size="small" class="ml-[10px] horz-blank-slider" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('topRounded')" v-if="diyStore.editComponent.ignore.indexOf('topRounded') == -1">
|
||||
<el-slider v-model="diyStore.editComponent.topRounded" show-input size="small" class="ml-[10px] horz-blank-slider" :max="50" />
|
||||
<el-slider v-model="diyStore.editComponent.topRounded" show-input size="small" class="ml-[10px] horz-blank-slider" :max="100" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('bottomRounded')" v-if="diyStore.editComponent.ignore.indexOf('bottomRounded') == -1">
|
||||
<el-slider v-model="diyStore.editComponent.bottomRounded" show-input size="small" class="ml-[10px] horz-blank-slider" :max="50" />
|
||||
<el-slider v-model="diyStore.editComponent.bottomRounded" show-input size="small" class="ml-[10px] horz-blank-slider" :max="100" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
|
||||
<div class="w-[700px]">
|
||||
<div class="flex flex-wrap">
|
||||
<diy-link v-model="link" :ignore="['DIY_LINK']" @success="changePage">
|
||||
<diy-link v-model="link" :ignore="['DIY_LINK','DIY_JUMP_OTHER_APPLET','DIY_MAKE_PHONE_CALL']" @success="changePage">
|
||||
<el-button type="primary">{{ t('changePage') }}</el-button>
|
||||
</diy-link>
|
||||
<el-button type="primary" @click="toDecorate()" v-show="page.use_template.action == 'decorate'" class="ml-[12px]">{{ t('decorate') }}</el-button>
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
<el-input v-model="diyPageTableData.searchParam.title" :placeholder="t('titlePlaceholder')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('forAddon')" prop="addon_name">
|
||||
<el-select v-model="diyPageTableData.searchParam.addon_name" :placeholder="t('pageTypePlaceholder')" @change="handleSelectAddonChange">
|
||||
<el-select v-model="diyPageTableData.searchParam.addon_name" :placeholder="t('forAddonPlaceholder')" @change="handleSelectAddonChange">
|
||||
<el-option :label="t('all')" value="" />
|
||||
<el-option v-for="(item, key) in apps" :label="item.title" :value="key" :key="key"/>
|
||||
</el-select>
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
<el-input v-model="diyRouteTableData.searchParam.title" :placeholder="t('titlePlaceholder')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('forAddon')" prop="addon_name">
|
||||
<el-select v-model="diyRouteTableData.searchParam.addon_name" :placeholder="t('pageTypePlaceholder')">
|
||||
<el-select v-model="diyRouteTableData.searchParam.addon_name" :placeholder="t('forAddonPlaceholder')">
|
||||
<el-option :label="t('all')" value="" />
|
||||
<el-option v-for="(item, key) in apps" :label="item.title" :value="key" :key="key"/>
|
||||
</el-select>
|
||||
@ -54,7 +54,7 @@
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="mt-[16px] flex justify-end">
|
||||
<el-pagination v-model:current-page="diyRouteTableData.page" v-model:page-size="diyRouteTableData.limit" layout="total, sizes, prev, pager, next, jumper" :total="diyRouteTableData.total" @size-change="loadDiyRouteList()" @current-change="loadDiyRouteList" />
|
||||
<el-pagination v-model:current-page="diyRouteTableData.page" v-model:page-size="diyRouteTableData.limit" layout="total, sizes, prev, pager, next, jumper" :total="diyRouteTableData.total" @size-change="getDiyRouteListFn" @current-change="loadDiyRouteList" />
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
@ -99,6 +99,7 @@ import { ElMessage, FormInstance } from 'element-plus'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { useClipboard } from '@vueuse/core'
|
||||
import { getUrl } from '@/app/api/sys'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
@ -121,6 +122,8 @@ const diyRouteTableData = reactive({
|
||||
}
|
||||
})
|
||||
|
||||
const diyRouteList: any = ref([])
|
||||
|
||||
const wapDomain = ref('')
|
||||
const getDomain = async () => {
|
||||
wapDomain.value = (await getUrl()).data.wap_url
|
||||
@ -130,42 +133,60 @@ getDomain()
|
||||
|
||||
const apps: any = reactive({}) // 应用插件列表
|
||||
|
||||
getDiyRouteAppList().then(res=>{
|
||||
if(res.data){
|
||||
getDiyRouteAppList().then(res=> {
|
||||
if (res.data) {
|
||||
for (const key in res.data) {
|
||||
apps[key] = res.data[key];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const getDiyRouteListFn = () => {
|
||||
getDiyRouteList({}).then(res => {
|
||||
diyRouteTableData.loading = false
|
||||
diyRouteList.value = cloneDeep(res.data)
|
||||
loadDiyRouteList(diyRouteTableData.page)
|
||||
}).catch(() => {
|
||||
diyRouteTableData.loading = false
|
||||
});
|
||||
}
|
||||
|
||||
getDiyRouteListFn();
|
||||
|
||||
/**
|
||||
* 获取自定义路由列表
|
||||
*/
|
||||
const loadDiyRouteList = (page: number = 1) => {
|
||||
diyRouteTableData.loading = true
|
||||
diyRouteTableData.page = page
|
||||
|
||||
getDiyRouteList({
|
||||
page: diyRouteTableData.page,
|
||||
limit: diyRouteTableData.limit,
|
||||
...diyRouteTableData.searchParam
|
||||
}).then(res => {
|
||||
diyRouteTableData.loading = false
|
||||
const tempData = cloneDeep(diyRouteList.value)
|
||||
const data: any = [];
|
||||
|
||||
const len = Math.ceil(res.data.length / diyRouteTableData.limit)
|
||||
const data = JSON.parse(JSON.stringify(res.data))
|
||||
const dataGather = []
|
||||
for (let i = 0; i < len; i++) {
|
||||
dataGather[i] = data.splice(0, diyRouteTableData.limit)
|
||||
// 筛选条件
|
||||
for (let i = 0; i < tempData.length; i++) {
|
||||
let isAdd = true;
|
||||
if (diyRouteTableData.searchParam.title && tempData[i].title.indexOf(diyRouteTableData.searchParam.title) == -1) {
|
||||
isAdd = false;
|
||||
}
|
||||
diyRouteTableData.data = dataGather[diyRouteTableData.page - 1]
|
||||
|
||||
diyRouteTableData.total = res.data.length
|
||||
}).catch(() => {
|
||||
diyRouteTableData.loading = false
|
||||
})
|
||||
if (diyRouteTableData.searchParam.addon_name && tempData[i].addon_info && tempData[i].addon_info.key != diyRouteTableData.searchParam.addon_name) {
|
||||
isAdd = false;
|
||||
}
|
||||
|
||||
if (isAdd) {
|
||||
data.push(tempData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
diyRouteTableData.total = data.length
|
||||
const len = Math.ceil(data.length / diyRouteTableData.limit)
|
||||
const dataGather = []
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
dataGather[i] = data.splice(0, diyRouteTableData.limit)
|
||||
}
|
||||
diyRouteTableData.data = dataGather[diyRouteTableData.page - 1]
|
||||
}
|
||||
loadDiyRouteList()
|
||||
|
||||
// 获取自定义页面模板
|
||||
getDiyTemplate({}).then(res => {
|
||||
@ -273,7 +294,7 @@ const shareEvent = async (formEl: FormInstance | undefined) => {
|
||||
share: JSON.stringify(shareFormData),
|
||||
...diyRouteData
|
||||
}).then(() => {
|
||||
loadDiyRouteList()
|
||||
getDiyRouteListFn()
|
||||
shareDialogVisible.value = false
|
||||
}).catch(() => {
|
||||
})
|
||||
@ -284,7 +305,7 @@ const shareEvent = async (formEl: FormInstance | undefined) => {
|
||||
const resetForm = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
formEl.resetFields()
|
||||
loadDiyRouteList()
|
||||
getDiyRouteListFn()
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
<el-tabs v-model="activeName" class="demo-tabs mt-[15px]">
|
||||
<el-tab-pane :label="t('navImage')" name="navPicture">
|
||||
<div ref="navItemRef">
|
||||
<div v-for="(item,index) in diyBottomData.value.list" :key="'a'+index" :data-id="index" class="item-wrap border-2 border-dashed pt-[18px] m-[10px] mb-[15px] relative list-item">
|
||||
<div v-for="(item,index) in diyBottomData.value.list" :key="'a'+index" :data-id="index" class="item-wrap border-2 border-dashed pt-[18px] m-[10px] mb-[15px] relative list-item" :class="{ 'not-sort': useDrag }">
|
||||
<el-form-item :label="t('navIconOne')">
|
||||
<div class="flex align-center">
|
||||
<div class="flex flex-col justify-center items-center">
|
||||
@ -48,7 +48,7 @@
|
||||
<el-input class="!w-[215px]" v-model="item.text" :placeholder="t('titleContent')" maxlength="5" show-word-limit />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('navLinkOne')">
|
||||
<diy-link v-model="item.link"/>
|
||||
<diy-link v-model="item.link" @confirm="diyLinkFn" />
|
||||
</el-form-item>
|
||||
<el-icon class="close-icon cursor-pointer -top-[11px] -right-[8px]" @click="deleteNav(index)">
|
||||
<CircleCloseFilled />
|
||||
@ -238,6 +238,7 @@ onMounted(() => {
|
||||
const sortable = Sortable.create(navItemRef.value, {
|
||||
group: 'item-wrap',
|
||||
animation: 200,
|
||||
filter: '.not-sort', // 过滤.not-sort的元素
|
||||
onEnd: event => {
|
||||
const temp = diyBottomData.value.list[event.oldIndex!]
|
||||
diyBottomData.value.list.splice(event.oldIndex!, 1)
|
||||
@ -253,6 +254,10 @@ onMounted(() => {
|
||||
})
|
||||
})
|
||||
|
||||
const useDrag = ref(false)
|
||||
const diyLinkFn = (val) => {
|
||||
useDrag.value = val
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.close-icon {
|
||||
|
||||
@ -89,7 +89,7 @@
|
||||
<template #default="{ row }">
|
||||
<div class="flex items-center cursor-pointer " @click="toMember(row.member.member_id)">
|
||||
<img class="w-[50px] h-[50px] mr-[10px]" v-if="row.member.headimg" :src="img(row.member.headimg)" alt="">
|
||||
<img class="w-[50px] h-[50px] mr-[10px]" v-else src="@/app/assets/images/default_headimg.png" alt="">
|
||||
<img class="w-[50px] h-[50px] mr-[10px] rounded-full" v-else src="@/app/assets/images/member_head.png" alt="">
|
||||
<div class="flex flex flex-col">
|
||||
<span>{{ row.member.nickname || '' }}</span>
|
||||
<span>{{ row.member.mobile || '' }}</span>
|
||||
@ -99,7 +99,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('cashOutMethod')" align="center" min-width="140">
|
||||
<template #default="{ row }">
|
||||
{{ Transfertype[row.transfer_type].name }}
|
||||
{{ row.transfer_type_name }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
@ -183,7 +183,7 @@
|
||||
<el-dialog v-model="auditShowDialog" :title="t('rejectionAudit')" width="500px" :destroy-on-close="true">
|
||||
<el-form :model="auditFailure" label-width="90px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
|
||||
<el-form-item :label="t('reasonsRefusal')" prop="label_name">
|
||||
<el-input v-model="auditFailure.refuse_reason" clearable :placeholder="t('reasonsRefusalPlaceholder')" class="input-width" type="textarea" />
|
||||
<el-input v-model="auditFailure.refuse_reason" clearable maxlength="200" :show-word-limit="true" :placeholder="t('reasonsRefusalPlaceholder')" :rows="4" class="input-width" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
@ -334,10 +334,9 @@ const fnProcessing = (type: string, data: any) => {
|
||||
}
|
||||
} else if (type == 'transferFn') {
|
||||
obj.id = data.id
|
||||
ElMessageBox.confirm(`${t('isTransfer')}`, `${t('transfer')}`)
|
||||
.then(() => {
|
||||
transferFn(obj)
|
||||
})
|
||||
ElMessageBox.confirm(`${ t('isTransfer') }`, `${ t('transfer') }`).then(() => {
|
||||
transferFn(obj)
|
||||
})
|
||||
} else {
|
||||
detailFn(data.id)
|
||||
}
|
||||
@ -349,7 +348,9 @@ const fnProcessing = (type: string, data: any) => {
|
||||
*/
|
||||
const transferFn = (data:any) => {
|
||||
memberTransfer({ ...data }).then(res => {
|
||||
auditFailure.value = { refuse_reason: '', id: 0, action: 0 }
|
||||
loadOrderList()
|
||||
|
||||
}).catch(() => {
|
||||
loadOrderList()
|
||||
})
|
||||
@ -389,6 +390,7 @@ const cashOutAuditFn = (data:any) => {
|
||||
...data
|
||||
}).then(res => {
|
||||
loadOrderList()
|
||||
|
||||
}).catch(() => {
|
||||
loadOrderList()
|
||||
})
|
||||
|
||||
@ -9,8 +9,7 @@
|
||||
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
|
||||
<el-form :inline="true" :model="payListTable.searchParam" ref="searchFormRef">
|
||||
<el-form-item :label="t('outTradeNo')" prop="trade_no">
|
||||
<el-input v-model="payListTable.searchParam.out_trade_no"
|
||||
:placeholder="t('outTradeNoPlaceholder')" />
|
||||
<el-input v-model="payListTable.searchParam.out_trade_no" :placeholder="t('outTradeNoPlaceholder')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('createTime')" prop="create_time">
|
||||
<el-date-picker v-model="payListTable.searchParam.create_time" type="datetimerange"
|
||||
@ -18,7 +17,7 @@
|
||||
:end-placeholder="t('endDate')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('status')" prop="status">
|
||||
<el-select v-model="payListTable.searchParam.status" placeholder="Select">
|
||||
<el-select v-model="payListTable.searchParam.status" :placeholder="t('status')">
|
||||
<el-option :label="t('all')" value="" />
|
||||
<el-option :label="t('waitAudit')" value="3" />
|
||||
<el-option :label="t('passed')" value="2" />
|
||||
@ -137,21 +136,17 @@ loadPayList()
|
||||
|
||||
const passEvent = (row: AnyObject) => {
|
||||
ElMessageBox.confirm(
|
||||
t('passTips'),
|
||||
t('warning'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning'
|
||||
}
|
||||
t('passTips'),
|
||||
t('warning'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning'
|
||||
}
|
||||
).then(({ value }) => {
|
||||
payAuditPass(row.out_trade_no)
|
||||
.then(() => {
|
||||
loadPayList()
|
||||
})
|
||||
.catch()
|
||||
}).catch(() => {
|
||||
|
||||
payAuditPass(row.out_trade_no).then(() => {
|
||||
loadPayList()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -163,13 +158,9 @@ const refuseEvent = (row: AnyObject) => {
|
||||
inputPattern: /\S/,
|
||||
inputType: 'textarea'
|
||||
}).then(({ value }) => {
|
||||
payAuditRefuse({ out_trade_no: row.out_trade_no, reason: value })
|
||||
.then(() => {
|
||||
loadPayList()
|
||||
})
|
||||
.catch()
|
||||
}).catch(() => {
|
||||
|
||||
payAuditRefuse({ out_trade_no: row.out_trade_no, reason: value }).then(() => {
|
||||
loadPayList()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -72,34 +72,26 @@ const formData: Record<string, any> | null = ref(null)
|
||||
const setFormData = async () => {
|
||||
loading.value = true
|
||||
formData.value = null
|
||||
await getPayDetail(id)
|
||||
.then(({ data }) => {
|
||||
formData.value = data
|
||||
})
|
||||
.catch(() => {
|
||||
|
||||
})
|
||||
await getPayDetail(id).then(({ data }) => {
|
||||
formData.value = data
|
||||
})
|
||||
loading.value = false
|
||||
}
|
||||
setFormData()
|
||||
|
||||
const passEvent = () => {
|
||||
ElMessageBox.confirm(
|
||||
t('passTips'),
|
||||
t('warning'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning'
|
||||
}
|
||||
t('passTips'),
|
||||
t('warning'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning'
|
||||
}
|
||||
).then(({ value }) => {
|
||||
payAuditPass(formData.value.out_trade_no)
|
||||
.then(() => {
|
||||
setFormData()
|
||||
})
|
||||
.catch()
|
||||
}).catch(() => {
|
||||
|
||||
payAuditPass(formData.value.out_trade_no).then(() => {
|
||||
setFormData()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -113,9 +105,7 @@ const refuseEvent = () => {
|
||||
}).then(({ value }) => {
|
||||
payAuditRefuse({ out_trade_no: formData.value.out_trade_no, reason: value }).then(() => {
|
||||
setFormData()
|
||||
}).catch()
|
||||
}).catch(() => {
|
||||
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -67,7 +67,7 @@ const route = useRoute()
|
||||
const router = useRouter()
|
||||
const pageName = route.meta.title
|
||||
|
||||
const refundNo: string = route.query.refund_no
|
||||
const refundNo: any = route.query.refund_no
|
||||
const loading = ref(true)
|
||||
|
||||
const refundList = ref([])
|
||||
@ -76,15 +76,10 @@ const formData: Record<string, any> | null = ref(null)
|
||||
const setFormData = async (refundNo: string = '') => {
|
||||
loading.value = true
|
||||
formData.value = null
|
||||
await getPayRefundInfo(refundNo)
|
||||
.then(({ data }) => {
|
||||
formData.value = data
|
||||
refundList.value.push(data)
|
||||
})
|
||||
|
||||
.catch(() => {
|
||||
|
||||
})
|
||||
await getPayRefundInfo(refundNo).then(({ data }) => {
|
||||
formData.value = data
|
||||
refundList.value.push(data)
|
||||
})
|
||||
loading.value = false
|
||||
}
|
||||
if (refundNo) setFormData(refundNo)
|
||||
|
||||
@ -105,4 +105,5 @@ const returnFn = () => {
|
||||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
}</style>
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -20,8 +20,8 @@
|
||||
<div class="flex justify-between items-center mt-[18px]">
|
||||
<div class="w-[800px] text-[14px] whitespace-nowrap">
|
||||
<el-scrollbar :always="true">
|
||||
<span :class="['mr-[12px] cursor-pointer', {'text-[var(--el-color-primary)]': params.app == ''}]" @click="cutAppFn('')">所有应用</span>
|
||||
<span :class="['mr-[12px] cursor-pointer', {'text-[var(--el-color-primary)]': params.app == item.key}]" @click="cutAppFn(item.key)" v-for="(item,index) in addonList" :key="index">{{item.title}}</span>
|
||||
<span :class="['px-[10px] cursor-pointer h-[35px] leading-[35px] inline-block', {'text-[var(--el-color-primary)]': params.app == ''}]" @click="cutAppFn('')">所有应用</span>
|
||||
<span :class="['px-[10px] cursor-pointer h-[35px] leading-[35px] inline-block', {'text-[var(--el-color-primary)]': params.app == item.key}]" @click="cutAppFn(item.key)" v-for="(item,index) in addonList" :key="index">{{item.title}}</span>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
<el-input v-model="params.keywords" class="!w-[300px] !h-[34px]" placeholder="请输入要搜索的站点名称" @keyup.enter.native="getHomeSiteFn()">
|
||||
@ -73,9 +73,9 @@
|
||||
|
||||
<el-dialog v-model="createSiteDialog" width="54vw" :destroy-on-close="true" style="border-radius: 25px;">
|
||||
<template #title>
|
||||
<div class="text-[#333333] text-[22px] ml-[10px] leading-[1]">创建站点</div>
|
||||
<div class="text-[#333333] text-[22px] ml-[15px] leading-[1] mt-[10px]">创建站点</div>
|
||||
</template>
|
||||
<div class="flex flex-col mx-[20px] h-[430px]">
|
||||
<div class="flex flex-col mx-[25px] h-[430px] mt-[15px]">
|
||||
<div class="flex items-center">
|
||||
<div class="text-[18px] text-[#333333]">站点名称</div>
|
||||
<div class="w-[420px] h-[34px] ml-[10px]">
|
||||
@ -89,7 +89,7 @@
|
||||
|
||||
<div class="flex-1 mt-[20px] h-[160px]" v-show="createSiteData.step == 1">
|
||||
<div class="text-[18px] text-[#333333]">店铺套餐</div>
|
||||
<el-scrollbar class="w-full mt-[10px] -ml-[10px]" height="350px">
|
||||
<el-scrollbar class="w-full mt-[10px] meal-site -ml-[10px]" height="350px">
|
||||
<div class="w-full whitespace-nowrap" v-show="createSiteData.step == 1">
|
||||
<div v-for="(item, index) in siteGroup" :key="index"
|
||||
class="inline-flex flex-col w-[300px] h-[330px] box-border rounded-[17px] border-transparent border-[2px] border-solid create-site-item my-[10px]"
|
||||
@ -116,7 +116,7 @@
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button type="primary" @click="createSiteFn" class="w-[118px] h-[44px] text-[16px]">创建站点</el-button>
|
||||
<el-button type="primary" @click="createSiteFn" class="w-[118px] h-[44px] mt-[10px] text-[16px]">创建站点</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
@ -327,4 +327,7 @@ watch(() => createSiteDialog.value, () => {
|
||||
.create-site-name .el-input__wrapper{
|
||||
border-radius: 6px !important;
|
||||
}
|
||||
.meal-site{
|
||||
height: calc(100% - 30px) !important;
|
||||
}
|
||||
</style>
|
||||
@ -127,10 +127,8 @@ import { AnyObject } from '@/types/global'
|
||||
import useStyleStore from '@/stores/modules/style'
|
||||
|
||||
const loading = ref(true)
|
||||
|
||||
const newSiteStat = ref<any>(null)
|
||||
const addUser = ref<any>(null)
|
||||
|
||||
const styleStore = useStyleStore()
|
||||
|
||||
interface NewVersion{
|
||||
@ -153,7 +151,7 @@ const newVersion = ref<NewVersion>({
|
||||
|
||||
getFrameworkNewVersion().then(({ data }) => {
|
||||
newVersion.value = data
|
||||
}).catch()
|
||||
})
|
||||
|
||||
const statInfo = ref<StatInfo>({
|
||||
today_data: {},
|
||||
@ -165,6 +163,7 @@ const statInfo = ref<StatInfo>({
|
||||
site_group_stat: {},
|
||||
app: {}
|
||||
})
|
||||
|
||||
const getStatInfoFn = async (id: number = 0) => {
|
||||
statInfo.value = await (await getStatInfo()).data
|
||||
loading.value = false
|
||||
@ -255,6 +254,7 @@ const toHref = (url:any, id:any) => {
|
||||
const toApplication = () => {
|
||||
window.open('https://www.niucloud.com/app')
|
||||
}
|
||||
|
||||
// 更新时间
|
||||
const time = ref('')
|
||||
const nowTime = () => {
|
||||
|
||||
@ -22,8 +22,7 @@
|
||||
<el-form-item :label="t('link')" v-show="wapPreview">
|
||||
<el-input readonly :value="wapPreview">
|
||||
<template #append>
|
||||
<el-button @click="copyEvent(wapPreview)" class="bg-primary copy">{{ t('copy') }}
|
||||
</el-button>
|
||||
<el-button @click="copyEvent(wapPreview)" class="bg-primary copy">{{ t('copy') }}</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -87,7 +87,7 @@
|
||||
<template #default="{ row }">
|
||||
<el-button class="!text-[13px]" v-if="row.install_info && Object.keys(row.install_info)?.length && row.install_info.version != row.version" type="primary" link @click="upgradeAddonFn(row.key)">{{ t('upgrade') }}</el-button>
|
||||
<el-button class="!text-[13px]" v-if="row.install_info && Object.keys(row.install_info)?.length" type="primary" link @click="uninstallAddonFn(row.key)">{{ t('unload') }}</el-button>
|
||||
<template v-if="row.is_download && Object.keys(row.install_info) <= 0">
|
||||
<template v-if="row.is_download && (!row.install_info || !Object.keys(row.install_info).length)">
|
||||
<el-button class="!text-[13px]" type="primary" link @click="installAddonFn(row.key)">{{ t('install') }}</el-button>
|
||||
<el-button class="!text-[13px]" type="primary" link @click="deleteAddonFn(row.key)">{{ t('delete') }}</el-button>
|
||||
</template>
|
||||
@ -145,8 +145,7 @@
|
||||
您在官方应用市场购买任意一款应用,即可获得授权码。输入正确授权码认证通过后,即可支持在线升级和其它相关服务</p>
|
||||
<div class="flex justify-end mt-[36px]">
|
||||
<el-button class="w-[182px] !h-[48px]" plain @click="market">去应用市场逛逛</el-button>
|
||||
<el-button class="w-[100px] !h-[48px]" plain
|
||||
@click="getAuthCodeDialog.hide()">关闭</el-button>
|
||||
<el-button class="w-[100px] !h-[48px]" plain @click="getAuthCodeDialog.hide()">关闭</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<template #reference>
|
||||
@ -376,7 +375,7 @@ import { ref, reactive, watch, h } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getAddonLocal, uninstallAddon, installAddon, preInstallCheck, cloudInstallAddon, getAddonInstalltask, getAddonCloudInstallLog, preUninstallCheck, cancelInstall } from '@/app/api/addon'
|
||||
import { deleteAddonDevelop } from '@/app/api/tools'
|
||||
import { downloadVersion, getAuthinfo, setAuthinfo } from '@/app/api/module'
|
||||
import { downloadVersion, getAuthInfo, setAuthInfo } from '@/app/api/module'
|
||||
import { ElMessage, ElMessageBox, ElNotification, FormInstance, FormRules } from 'element-plus'
|
||||
import 'vue-web-terminal/lib/theme/dark.css'
|
||||
import { Terminal, TerminalFlash } from 'vue-web-terminal'
|
||||
@ -432,7 +431,7 @@ const downEvent = (param: Record<string, any>, isDown = false) => {
|
||||
}
|
||||
|
||||
const authCode = ref('')
|
||||
getAuthinfo().then(res => {
|
||||
getAuthInfo().then(res => {
|
||||
if (res.data.data && res.data.data.auth_code) {
|
||||
authCode.value = res.data.data.auth_code
|
||||
}
|
||||
@ -831,7 +830,7 @@ const saveLoading = ref(false)
|
||||
const authLoading = ref(true)
|
||||
const checkAppMange = () => {
|
||||
authLoading.value = true
|
||||
getAuthinfo()
|
||||
getAuthInfo()
|
||||
.then((res) => {
|
||||
authLoading.value = false
|
||||
if (res.data.data && res.data.data.length != 0) {
|
||||
@ -871,7 +870,7 @@ const save = async (formEl: FormInstance | undefined) => {
|
||||
if (valid) {
|
||||
saveLoading.value = true
|
||||
|
||||
setAuthinfo(formData)
|
||||
setAuthInfo(formData)
|
||||
.then(() => {
|
||||
saveLoading.value = false
|
||||
setTimeout(() => {
|
||||
|
||||
@ -65,8 +65,7 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="password">
|
||||
<el-input type="password" v-model="form.password" @keyup.enter="handleLogin(formRef)"
|
||||
autocomplete="new-password" :show-password="true" class="w-50 m-1 h-[40px]" :placeholder="t('passwordPlaceholder')">
|
||||
<el-input type="password" v-model="form.password" @keyup.enter="handleLogin(formRef)" autocomplete="new-password" :show-password="true" class="w-50 m-1 h-[40px]" :placeholder="t('passwordPlaceholder')">
|
||||
<template #prefix>
|
||||
<icon name="element Lock" />
|
||||
</template>
|
||||
@ -74,8 +73,7 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="mt-[30px] h-[40px] w-full" @click="handleLogin(formRef)" :loading="loading">{{ loading ? t('logging') :
|
||||
t('login') }}</el-button>
|
||||
<el-button type="primary" class="mt-[30px] h-[40px] w-full" @click="handleLogin(formRef)" :loading="loading">{{ loading ? t('logging') : t('login') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
@ -350,7 +350,6 @@ const setContinueSignAward = async () => {
|
||||
|
||||
setMemberBenefitsContents(contentData, continue_award.value, 0, 1)
|
||||
|
||||
|
||||
if (!isEdit) {
|
||||
formData.continue_award.push(JSON.parse(JSON.stringify(continue_award.value)))
|
||||
} else {
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
<template #default="{ row }">
|
||||
<div class="flex items-center cursor-pointer" @click="toMember(row.member_id)">
|
||||
<img class="w-[50px] h-[50px] mr-[10px]" v-if="row.member.headimg" :src="img(row.member.headimg)" alt="">
|
||||
<img class="w-[50px] h-[50px] mr-[10px]" v-else src="@/app/assets/images/default_headimg.png" alt="">
|
||||
<img class="w-[50px] h-[50px] mr-[10px] rounded-full" v-else src="@/app/assets/images/member_head.png" alt="">
|
||||
<div class="flex flex flex-col">
|
||||
<span>{{ row.member.nickname || '' }}</span>
|
||||
</div>
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
<template #default="{ row }">
|
||||
<div class="flex items-center cursor-pointer " @click="toMember(row.member.member_id)" v-if="row.member">
|
||||
<img class="w-[50px] h-[50px] mr-[10px]" v-if="row.member.headimg" :src="img(row.member.headimg)" alt="">
|
||||
<img class="w-[50px] h-[50px] mr-[10px]" v-else src="@/app/assets/images/default_headimg.png" alt="">
|
||||
<img class="w-[50px] h-[50px] mr-[10px] rounded-full" v-else src="@/app/assets/images/member_head.png" alt="">
|
||||
<div class="flex flex flex-col">
|
||||
<span>{{ row.member.nickname || '' }}</span>
|
||||
<span>{{ row.member.mobile || '' }}</span>
|
||||
@ -157,7 +157,6 @@ const deleteEvent = (id: number) => {
|
||||
).then(() => {
|
||||
deleteVerifier(id).then(() => {
|
||||
loadVerifierList()
|
||||
}).catch(() => {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@
|
||||
<template #default="{ row }">
|
||||
<div class="flex items-center cursor-pointer" @click="toMember(row.member_id)">
|
||||
<img class="w-[50px] h-[50px] mr-[10px]" v-if="row.member.headimg" :src="img(row.member.headimg)" alt="">
|
||||
<img class="w-[50px] h-[50px] mr-[10px]" v-else src="@/app/assets/images/default_headimg.png" alt="">
|
||||
<img class="w-[50px] h-[50px] mr-[10px] rounded-full" v-else src="@/app/assets/images/member_head.png" alt="">
|
||||
<div class="flex flex flex-col">
|
||||
<span>{{ row.member.nickname || '' }}</span>
|
||||
</div>
|
||||
|
||||
@ -92,7 +92,7 @@
|
||||
<template #default="{ row }">
|
||||
<div class="flex items-center cursor-pointer" @click="toMember(row.member_id)">
|
||||
<img class="w-[50px] h-[50px] mr-[10px]" v-if="row.member.headimg" :src="img(row.member.headimg)" alt="">
|
||||
<img class="w-[50px] h-[50px] mr-[10px]" v-else src="@/app/assets/images/default_headimg.png" alt="">
|
||||
<img class="w-[50px] h-[50px] mr-[10px] rounded-full" v-else src="@/app/assets/images/member_head.png" alt="">
|
||||
<div class="flex flex flex-col">
|
||||
<span>{{ row.member.nickname || '' }}</span>
|
||||
</div>
|
||||
|
||||
@ -73,7 +73,7 @@ const sexSelectData = ref([
|
||||
name: t('girlSex')
|
||||
}
|
||||
])
|
||||
const labelSelectData = ref(null)
|
||||
const labelSelectData:any = ref(null)
|
||||
// 获取全部标签
|
||||
const getMemberLabelAllFn = async () => {
|
||||
labelSelectData.value = await (await getMemberLabelAll()).data
|
||||
@ -127,7 +127,11 @@ const confirm = async (formEl: FormInstance | undefined) => {
|
||||
if (repeat.value) return
|
||||
repeat.value = true
|
||||
|
||||
const val = saveData[type.value] ? deepClone(saveData[type.value]) : ''
|
||||
let val = saveData[type.value];
|
||||
if(type.value == 'member_label'){
|
||||
// 将saveData[type.value]中的值,转换为字符串
|
||||
val = saveData[type.value] && saveData[type.value].length ? deepClone(saveData[type.value]).join(',').split(',') : '';
|
||||
}
|
||||
|
||||
const data = ref({
|
||||
member_id: memberId.value,
|
||||
@ -155,8 +159,20 @@ const setDialogType = async (row: any = null) => {
|
||||
memberId.value = row.id
|
||||
saveData[type.value] = row.data[type.value]
|
||||
if (type.value == 'member_label' && saveData[type.value]) {
|
||||
saveData[type.value].forEach((item:any, index:any) => {
|
||||
saveData[type.value][index] = Number.parseFloat(item)
|
||||
saveData[type.value].forEach((item: any, index: any) => {
|
||||
let isExist = false;
|
||||
for (let i = 0; i < labelSelectData.value.length; i++) {
|
||||
if (labelSelectData.value[i].label_id == item) {
|
||||
isExist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isExist) {
|
||||
saveData[type.value][index] = Number.parseFloat(item)
|
||||
} else {
|
||||
saveData[type.value].splice(index, 1); // 删除不存在的id
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
loading.value = false
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<el-form-item :label="t('headimg')" >
|
||||
<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-else src="@/app/assets/images/default_headimg.png" alt="" >
|
||||
<img class="w-[50px] h-[50px] mr-[10px] rounded-full" v-else src="@/app/assets/images/member_head.png" alt="">
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<el-form-item :label="t('headimg')">
|
||||
<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-else src="@/app/assets/images/default_headimg.png" alt="">
|
||||
<img class="w-[50px] h-[50px] mr-[10px] rounded-full" v-else src="@/app/assets/images/member_head.png" alt="">
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<el-form-item :label="t('headimg')" >
|
||||
<div class="flex items-center">
|
||||
<img class="w-[50px] h-[50px] mr-[10px]" v-if="formData.headimg" :src="img(formData.headimg)" alt="" >
|
||||
<img class="w-[50px] h-[50px] mr-[10px]" v-else src="@/app/assets/images/default_headimg.png" alt="" >
|
||||
<img class="w-[50px] h-[50px] mr-[10px] rounded-full" v-else src="@/app/assets/images/member_head.png" alt="">
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<el-form-item :label="t('headimg')" >
|
||||
<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-else src="@/app/assets/images/default_headimg.png" alt="" >
|
||||
<img class="w-[50px] h-[50px] mr-[10px] rounded-full" v-else src="@/app/assets/images/member_head.png" alt="">
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@
|
||||
<template #default="{ row }">
|
||||
<div class="flex items-center cursor-pointer" @click="toMember(row.member_id)">
|
||||
<img class="w-[50px] h-[50px] mr-[10px]" v-if="row.member.headimg" :src="img(row.member.headimg)" alt="">
|
||||
<img class="w-[50px] h-[50px] mr-[10px]" v-else src="@/app/assets/images/default_headimg.png" alt="">
|
||||
<img class="w-[50px] h-[50px] mr-[10px] rounded-full" v-else src="@/app/assets/images/member_head.png" alt="">
|
||||
<div class="flex flex flex-col">
|
||||
<span>{{ row.member.nickname || '' }}</span>
|
||||
</div>
|
||||
|
||||
@ -57,7 +57,7 @@
|
||||
<template #default="{ row }">
|
||||
<div class="flex items-center">
|
||||
<img class="w-[50px] h-[50px] mr-[10px]" v-if="row.headimg" :src="img(row.headimg)" alt="">
|
||||
<img class="w-[50px] h-[50px] mr-[10px]" v-else src="@/app/assets/images/default_headimg.png" alt="">
|
||||
<img class="w-[50px] h-[50px] mr-[10px] rounded-full" v-else src="@/app/assets/images/member_head.png" alt="">
|
||||
<div class="flex flex flex-col">
|
||||
<span>{{ row.nickname || '' }}</span>
|
||||
</div>
|
||||
@ -72,7 +72,7 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="balance" :label="t('balance')" min-width="130" align="right" />
|
||||
<el-table-column prop="member_label" :label="t('lable')" min-width="120" align="center">
|
||||
<el-table-column prop="member_label" :label="t('memberLabelTag')" min-width="120" align="center">
|
||||
<template #default="{ row }">
|
||||
<div class="flex flex-col items-center">
|
||||
<div v-for="(item, key) in row.member_label_array" class="my-[3px]" :key="key">
|
||||
@ -105,7 +105,7 @@
|
||||
<template #default="{ row }">
|
||||
<div class="flex items-center">
|
||||
<el-button type="primary" link @click="detailEvent(row)">{{ t('detail') }}</el-button>
|
||||
<el-button type="primary" link @click="setMemberLablel(row)">{{ t('setLable') }}</el-button>
|
||||
<el-button type="primary" link @click="setMemberLabel(row)">{{ t('setLabel') }}</el-button>
|
||||
<!-- <el-button type="primary" link @click="deleteEvent(row)">{{ t('memberDelete') }}</el-button> -->
|
||||
</div>
|
||||
</template>
|
||||
@ -205,27 +205,14 @@ const router = useRouter()
|
||||
const addMemberDialog: Record<string, any> | null = ref(null)
|
||||
const editMemberDialog: Record<string, any> | null = ref(null)
|
||||
|
||||
/**
|
||||
* 获取标签
|
||||
*/
|
||||
function memberLablel(res: any) {
|
||||
let data
|
||||
if (!res.member_label_array) return ''
|
||||
data = res.member_label_array.map((item: any) => {
|
||||
return item.label_name
|
||||
})
|
||||
data = data.toString()
|
||||
return data
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置标签
|
||||
*/
|
||||
function setMemberLablel(res: any) {
|
||||
function setMemberLabel(res: any) {
|
||||
const data = ref({
|
||||
type: 'member_label',
|
||||
id: res.member_id,
|
||||
title: t('setLable'),
|
||||
title: t('setLabel'),
|
||||
data: res
|
||||
})
|
||||
editMemberDialog.value.setDialogType(data.value)
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
<span class="text-[14px] min-w-[110px] text-right mr-[20px]">{{ t('headimg') }}</span>
|
||||
<span class="flex items-end text-[14px]">
|
||||
<img class="w-[50px] h-[50px] inline-block" v-if="formData.headimg" :src="img(formData.headimg)" alt="">
|
||||
<img class="w-[50px] h-[50px] inline-block" v-else src="@/app/assets/images/default_headimg.png" alt="">
|
||||
<img class="w-[50px] h-[50px] inline-block rounded-full" v-else src="@/app/assets/images/member_head.png" alt="">
|
||||
<el-icon @click="editMemberInfo('headimg')" class="-bottom-[2px] -right-[4px] cursor-pointer">
|
||||
<EditPen color="#273CE2" />
|
||||
</el-icon>
|
||||
|
||||
@ -71,7 +71,7 @@
|
||||
<template #default="{ row }">
|
||||
<div class="flex items-center cursor-pointer" @click="toMember(row.member_id)">
|
||||
<img class="w-[50px] h-[50px] mr-[10px]" v-if="row.member.headimg" :src="img(row.member.headimg)" alt="">
|
||||
<img class="w-[50px] h-[50px] mr-[10px]" v-else src="@/app/assets/images/default_headimg.png" alt="">
|
||||
<img class="w-[50px] h-[50px] mr-[10px] rounded-full" v-else src="@/app/assets/images/member_head.png" alt="">
|
||||
<div class="flex flex flex-col">
|
||||
<span>{{ row.member.nickname || '' }}</span>
|
||||
</div>
|
||||
|
||||
@ -7,8 +7,15 @@
|
||||
</div>
|
||||
|
||||
<!-- 组件公共属性 -->
|
||||
<slot name="common"></slot>
|
||||
|
||||
<slot name="common"></slot>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('imgShape')">
|
||||
<div class="flex items-center">
|
||||
<div class="bg-[#DFDFDF] cursor-pointer w-[50px] h-[50px] border-solid border-[1px] border-transparent rounded-[50%]" :class="{'border-[var(--el-color-primary)]': posterStore.editComponent.shape == 'circle'}" @click="imgShapeChangeFn('circle')"></div>
|
||||
<div class="bg-[#DFDFDF] cursor-pointer w-[50px] h-[50px] ml-[25px] border-solid border-[1px] border-transparent" :class="{'border-[var(--el-color-primary)]': posterStore.editComponent.shape == 'normal'}" @click="imgShapeChangeFn('normal')"></div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -19,6 +26,11 @@ import usePosterStore from '@/stores/modules/poster'
|
||||
|
||||
const posterStore = usePosterStore()
|
||||
|
||||
// 图片形状改变
|
||||
const imgShapeChangeFn = (data)=>{
|
||||
posterStore.editComponent.shape = data;
|
||||
}
|
||||
|
||||
defineExpose({})
|
||||
|
||||
</script>
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
<div class="text-sm text-gray-400 mt-[10px]">{{ t('bgUrlTips') }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('bgColor')" v-show="posterStore.global.bgType == 'color'">
|
||||
<el-color-picker v-model="posterStore.editComponent.bgColor" show-alpha :predefine="posterStore.predefineColors" />
|
||||
<el-color-picker v-model="posterStore.editComponent.bgColor" :predefine="posterStore.predefineColors" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('statusLabel')" class="display-block">
|
||||
<el-switch v-model="posterStore.status" :active-value="1" :inactive-value="0"/>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="pointer-events-none max-w-[360px]" :style="componentStyle">
|
||||
<img src="@/app/assets/images/default_headimg.png" class="w-full h-full" />
|
||||
<div class="pointer-events-none max-w-[720px]" :style="componentStyle">
|
||||
<img src="@/app/assets/images/default_headimg_square.jpg" class="w-full h-full" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -22,6 +22,9 @@ const data = computed(()=> {
|
||||
const componentStyle = computed(()=> {
|
||||
var style = '';
|
||||
style += `width: ${prop.value.width}px;`;
|
||||
if(prop.value.shape == 'circle'){
|
||||
style += `border-radius: 50%; overflow: hidden;`;
|
||||
}
|
||||
return style;
|
||||
})
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="pointer-events-none max-w-[360px]" :style="componentStyle">
|
||||
<div class="pointer-events-none max-w-[720px]" :style="componentStyle">
|
||||
<img v-if="data.value" :src="img(data.value)" class="w-full h-full" />
|
||||
<img v-else :src="img('static/resource/images/diy/crack_figure.png')" class="w-full h-full" />
|
||||
</div>
|
||||
|
||||
@ -4,6 +4,9 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref,computed } from 'vue'
|
||||
import usePosterStore from '@/stores/modules/poster'
|
||||
|
||||
const posterStore = usePosterStore()
|
||||
|
||||
const prop = defineProps({
|
||||
value: {
|
||||
@ -18,7 +21,22 @@ const data = computed(()=> {
|
||||
|
||||
const componentStyle = computed(()=> {
|
||||
var style = '';
|
||||
style += `font-size: ${prop.value.fontSize}px;color: ${prop.value.fontColor};`;
|
||||
style += `font-size: ${prop.value.fontSize}px;color: ${prop.value.fontColor};line-height: ${prop.value.lineHeight + prop.value.fontSize}px;`;
|
||||
if(prop.value.x == 'left' || prop.value.x == 'center' || prop.value.x == 'right'){
|
||||
style += `text-align: ${prop.value.x};`;
|
||||
}
|
||||
if(prop.value.weight){
|
||||
style += `font-weight: bold;`;
|
||||
}
|
||||
if(!prop.value.fontFamily || prop.value.fontFamily == 'static/font/SourceHanSansCN-Regular.ttf'){
|
||||
style += `font-family: poster_default_font;`;
|
||||
}
|
||||
let box: any = document.getElementById(prop.value.id)
|
||||
if (box) {
|
||||
style += `width:${box.offsetWidth}px;height:${box.offsetHeight}px;`;
|
||||
}else{
|
||||
style += `width:${prop.value.width}px;height:${prop.value.height}px;`;
|
||||
}
|
||||
return style;
|
||||
})
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="pointer-events-none max-w-[360px]" :style="componentStyle">
|
||||
<div class="pointer-events-none max-w-[720px]" :style="componentStyle">
|
||||
<img :src="img('static/resource/images/diy/qrcode.png')" class="w-full h-full" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -4,6 +4,9 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref,computed } from 'vue'
|
||||
import usePosterStore from '@/stores/modules/poster'
|
||||
|
||||
const posterStore = usePosterStore()
|
||||
|
||||
const prop = defineProps({
|
||||
value: {
|
||||
@ -18,10 +21,21 @@ const data = computed(()=> {
|
||||
|
||||
const componentStyle = computed(()=> {
|
||||
var style = '';
|
||||
style += `font-size: ${prop.value.fontSize}px;color: ${prop.value.fontColor};`;
|
||||
style += `font-size: ${prop.value.fontSize}px;color: ${prop.value.fontColor};line-height: ${prop.value.lineHeight + prop.value.fontSize}px;`;
|
||||
if(prop.value.x == 'left' || prop.value.x == 'center' || prop.value.x == 'right'){
|
||||
style += `text-align: ${prop.value.x};`;
|
||||
}
|
||||
if(prop.value.weight){
|
||||
style += `font-weight: bold;`;
|
||||
}
|
||||
if(!prop.value.fontFamily || prop.value.fontFamily == 'static/font/SourceHanSansCN-Regular.ttf'){
|
||||
style += `font-family: poster_default_font;`;
|
||||
}
|
||||
let box: any = document.getElementById(prop.value.id)
|
||||
if (box) {
|
||||
style += `width:${box.offsetWidth}px;height:${box.offsetHeight}px;`;
|
||||
}else{
|
||||
style += `width:${prop.value.width}px;height:${prop.value.height}px;`;
|
||||
}
|
||||
return style;
|
||||
})
|
||||
|
||||
@ -12,12 +12,14 @@
|
||||
<span class="mr-[5px] text-[14px]">{{ t('decorating') }}:{{ posterStore.typeName }}</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="flex items-center">
|
||||
<span class="text-white mr-[10px] text-base">{{ t('templatePosterPlaceholder') }}</span>
|
||||
<el-select size="small" v-model="template" class="w-[180px]" :placeholder="t('templatePosterPlaceholder')" @change="changeTemplatePoster">
|
||||
<el-option :label="t('templatePosterEmpty')" value="" />
|
||||
<el-option v-for="(item, index) in templatePoster" :label="item.name" :value="index" :key="index"/>
|
||||
</el-select>
|
||||
<div class="w-[180px]">
|
||||
<el-select size="small" v-model="template" :placeholder="t('templatePosterPlaceholder')" @change="changeTemplatePoster">
|
||||
<el-option :label="t('templatePosterEmpty')" value="" />
|
||||
<el-option v-for="(item, index) in templatePoster" :label="item.name" :value="index" :key="index"/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1"></div>
|
||||
<el-button @click="preview()" v-if="posterStore.id">{{ t('preview') }}</el-button>
|
||||
@ -55,7 +57,7 @@
|
||||
<div class="title-wrap text-center text-[14px]">{{ posterStore.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="preview-block relative">
|
||||
<div class="preview-block relative max-h-[640px]">
|
||||
<ul class="quick-action absolute text-center -right-[70px] top-[20px] w-[42px] rounded shadow-md">
|
||||
<el-tooltip effect="light" :content="t('moveUpComponentZIndex')" placement="right">
|
||||
<icon name="iconfont iconjiantoushang" size="20px" class="block cursor-pointer leading-[40px]" @click="posterStore.moveUpComponent" />
|
||||
@ -76,8 +78,8 @@
|
||||
|
||||
<!-- 组件预览渲染区域 -->
|
||||
<div class="preview-iframe" :style="posterStore.getGlobalStyle()" @click="posterStore.changeCurrentIndex(-99)">
|
||||
<div class="item-wrap area-box select-none max-w-[360px] cursor-move" v-for="(item,index) in posterStore.value" :id="item.id" :key="item.id"
|
||||
:style="{ top: item.y + 'px', left: item.x + 'px', zIndex: item.zIndex, transform : 'rotate(' + item.angle + 'deg)' }"
|
||||
<div class="item-wrap area-box select-none max-w-[720px] cursor-move" v-for="(item,index) in posterStore.value" :id="item.id" :key="item.id"
|
||||
:style="previewIframeStyle(item)"
|
||||
:class="{ 'selected' : posterStore.currentIndex == index }"
|
||||
@mousedown="posterStore.mouseDown($event,item.id,index)"
|
||||
@click.stop="posterStore.changeCurrentIndex(index,item)"
|
||||
@ -104,7 +106,7 @@
|
||||
<el-card class="box-card" shadow="never">
|
||||
<template #header>
|
||||
<div class="card-header flex justify-between items-center">
|
||||
<span class="title flex-1">{{ posterStore.currentIndex == -99 ? t('posterSet') : posterStore.editComponent.componentTitle }}</span>
|
||||
<span class="title flex-1">{{ posterStore.currentIndex == -99 ? t('posterSet') : posterStore.editComponent?.componentTitle }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -114,7 +116,7 @@
|
||||
<template #common>
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('componentStyleTitle') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form label-width="100px" class="px-[10px]">
|
||||
|
||||
<!-- 角度旋转、这里根据类型展示 文本、图片、绘画的编辑属性 -->
|
||||
|
||||
@ -122,22 +124,30 @@
|
||||
<span>{{ posterStore.editComponent.zIndex }}</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('coordinate')">
|
||||
<!-- <el-form-item :label="t('coordinate')">
|
||||
<el-slider v-model="posterStore.editComponent.x" show-input size="small" class="ml-[10px]" :min="0" :max="posterStore.getMaxX()" />
|
||||
<div class="my-[10px]"></div>
|
||||
<el-slider v-model="posterStore.editComponent.y" show-input size="small" class="ml-[10px]" :min="0" :max="posterStore.getMaxY()" />
|
||||
</el-form-item>
|
||||
|
||||
<div class="ml-[92px] mb-[18px] text-sm text-gray-400">{{ t('coordinateTips') }}</div>
|
||||
<div class="ml-[92px] mb-[18px] text-sm text-gray-400">{{ t('coordinateTips') }}</div> -->
|
||||
|
||||
<!-- 文本 -->
|
||||
<template v-if="posterStore.editComponent.type == 'text'">
|
||||
<el-form-item :label="t('textFontSize')">
|
||||
<el-slider v-model="posterStore.editComponent.fontSize" show-input size="small" class="ml-[10px]" :min="14" :max="36" />
|
||||
<el-slider v-model="posterStore.editComponent.fontSize" show-input size="small" class="ml-[10px]" :min="14" :max="50" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('textColor')">
|
||||
<el-color-picker v-model="posterStore.editComponent.fontColor" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('weight')">
|
||||
<el-switch v-model="posterStore.editComponent.weight" />
|
||||
</el-form-item>
|
||||
<!-- <el-form-item :label="t('space')">
|
||||
<el-slider v-model="posterStore.editComponent.space" show-input size="small" class="ml-[10px]" :min="0" :max="20" />
|
||||
</el-form-item> -->
|
||||
<el-form-item :label="t('lineHeight')">
|
||||
<el-slider v-model="posterStore.editComponent.lineHeight" show-input size="small" class="ml-[10px]" :min="0" :max="50" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<!-- 图片 -->
|
||||
@ -160,6 +170,31 @@
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<!-- 对齐方式 -->
|
||||
<template v-if="posterStore.editComponent.type != 'draw' && posterStore.editComponent.type != 'image' && posterStore.editComponent.type != 'qrcode'">
|
||||
<el-form-item :label="t('horizontalAlignment')">
|
||||
<ul class="flex items-center">
|
||||
<template v-for="(item,i) in xAlignList">
|
||||
<li :class="['w-[50px] h-[32px] flex items-center justify-center border-solid border-[1px] border-[#eee] cursor-pointer', {'border-r-transparent': xAlignList.length != (i+1)}, (item.className == posterStore.editComponent.x) ? '!border-[var(--el-color-primary)]' : '' ]" @click="alignChangeFn('x',item)">
|
||||
<span :class="['iconfont !text-[20px]', item.src]" :title="item.name"></span>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
<div class="text-sm mt-[10px] leading-[1.4] text-gray-400">{{ t('AlignTips') }}</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('verticalAlignment')">
|
||||
<ul class="flex items-center">
|
||||
<template v-for="(item,i) in yAlignList">
|
||||
<li :class="['w-[50px] h-[32px] flex items-center justify-center border-solid border-[1px] border-[#eee] cursor-pointer', {'border-r-transparent': yAlignList.length != (i+1)}, (item.className == posterStore.editComponent.y) ? '!border-[var(--el-color-primary)]' : '' ]" @click="alignChangeFn('y',item)">
|
||||
<span :class="['iconfont !text-[20px]', item.src]" :title="item.name"></span>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
|
||||
<!-- <el-form-item :label="t('旋转角度')">-->
|
||||
<!-- <el-slider v-model="posterStore.editComponent.angle" show-input size="small" class="ml-[10px]" :min="0" :max="360" />-->
|
||||
<!-- </el-form-item>-->
|
||||
@ -207,10 +242,13 @@ const posterStore = usePosterStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
route.query.id = route.query.id || 0
|
||||
route.query.type = route.query.type || '' // 海报类型
|
||||
route.query.name = route.query.name || ''
|
||||
route.query.back = route.query.back || '/site/poster/list'
|
||||
if(route && route.query){
|
||||
route.query.id = route.query.id || 0
|
||||
route.query.type = route.query.type || '' // 海报类型
|
||||
route.query.name = route.query.name || ''
|
||||
route.query.back = route.query.back || '/site/poster/list'
|
||||
}
|
||||
|
||||
|
||||
const backPath:any = route.query.back
|
||||
const template = ref('');
|
||||
@ -224,6 +262,90 @@ const activeNames = ref(componentType)
|
||||
const handleChange = (val: string[]) => {
|
||||
}
|
||||
|
||||
const previewIframeStyle = (data)=>{
|
||||
let style = {
|
||||
transform: '',
|
||||
zIndex: '',
|
||||
top: '',
|
||||
left: '',
|
||||
right: '',
|
||||
bottom: ''
|
||||
};
|
||||
style.transform = `rotate(${data.angle}deg)`;
|
||||
style.zIndex = `${data.zIndex}`;
|
||||
switch(data.y) {
|
||||
case 'top':
|
||||
style.top = 0;
|
||||
break;
|
||||
case 'center':
|
||||
style.top = '50%';
|
||||
style.transform = style.transform + ' translateY(-50%)';
|
||||
break;
|
||||
case 'bottom':
|
||||
style.bottom = 0;
|
||||
break;
|
||||
default:
|
||||
style.top = data.y + 'px';
|
||||
}
|
||||
switch(data.x) {
|
||||
case 'left':
|
||||
style.left = 0;
|
||||
break;
|
||||
case 'center':
|
||||
style.left = '50%';
|
||||
style.transform = style.transform + ' translateX(-50%)';
|
||||
break;
|
||||
case 'right':
|
||||
style.right = 0;
|
||||
break;
|
||||
default:
|
||||
style.left = data.x + 'px';
|
||||
}
|
||||
// console.log(data.x,data.y)
|
||||
return style;
|
||||
}
|
||||
|
||||
// 水平方向对齐
|
||||
const xAlignList = ref([
|
||||
{
|
||||
name: '左',
|
||||
src: 'iconzuoduiqi1',
|
||||
className: 'left'
|
||||
},
|
||||
{
|
||||
name: '中',
|
||||
src: 'iconshuipingjuzhong1',
|
||||
className: 'center'
|
||||
},
|
||||
{
|
||||
name: '右',
|
||||
src: 'iconyouduiqi1',
|
||||
className: 'right'
|
||||
}
|
||||
])
|
||||
// 水平方向对齐
|
||||
const yAlignList = ref([
|
||||
{
|
||||
name: '上',
|
||||
src: 'icondingduiqi1',
|
||||
className: 'top'
|
||||
},
|
||||
{
|
||||
name: '中',
|
||||
src: 'iconchuizhijuzhong1',
|
||||
className: 'center'
|
||||
},
|
||||
{
|
||||
name: '下',
|
||||
src: 'icondiduiqi1',
|
||||
className: 'bottom'
|
||||
},
|
||||
])
|
||||
const alignChangeFn = (type,data)=>{
|
||||
posterStore.editComponent[type] = data.className;
|
||||
|
||||
}
|
||||
|
||||
// 返回上一页
|
||||
const isChange = ref(true) // 数据是否发生变化,true:没变化,false:变化了
|
||||
const goBack = () => {
|
||||
@ -374,17 +496,17 @@ const save = (callback: any) => {
|
||||
if (isRepeat.value) return
|
||||
isRepeat.value = true
|
||||
|
||||
posterStore.value.forEach((item:any,index:any)=> {
|
||||
posterStore.value.forEach((item:any,index:any, originalArr:any)=> {
|
||||
const box: any = document.getElementById(item.id)
|
||||
if (box) {
|
||||
item.width = box.offsetWidth;
|
||||
item.height = box.offsetHeight;
|
||||
if (item.type == 'draw') {
|
||||
// [x,y]:左上,右上,右下,左下
|
||||
let leftTop = [item.x * 2, item.y * 2]; // 左上
|
||||
let rightTop = [(item.x + item.width) * 2, item.y * 2]; // 右上
|
||||
let rightBottom = [(item.x + item.width) * 2, (item.y + item.height) * 2]; // 右下
|
||||
let leftBottom = [item.x * 2, (item.y + item.height) * 2]; // 左下
|
||||
let leftTop = [item.x * 1, item.y * 1]; // 左上
|
||||
let rightTop = [(item.x + item.width) * 1, item.y * 1]; // 右上
|
||||
let rightBottom = [(item.x + item.width) * 1, (item.y + item.height) * 1]; // 右下
|
||||
let leftBottom = [item.x * 1, (item.y + item.height) * 1]; // 左下
|
||||
item.points = [leftTop, rightTop, rightBottom, leftBottom];
|
||||
}
|
||||
}
|
||||
@ -479,12 +601,14 @@ const preview = () => {
|
||||
}
|
||||
|
||||
.preview-iframe {
|
||||
transform: scale(0.5);
|
||||
margin: 0 auto;
|
||||
width: 360px;
|
||||
height: 640px;
|
||||
background-size: 100% 640px;
|
||||
width: 720px;
|
||||
height: 1280px;
|
||||
background-size: 100% 1280px;
|
||||
background-repeat: no-repeat;
|
||||
position: relative;
|
||||
transform-origin: left top;
|
||||
|
||||
.item-wrap {
|
||||
position: absolute;
|
||||
@ -522,8 +646,8 @@ const preview = () => {
|
||||
.box2,
|
||||
.box3,
|
||||
.box4 {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: #fff;
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
@ -532,26 +656,26 @@ const preview = () => {
|
||||
}
|
||||
|
||||
.box1 {
|
||||
top: -4px;
|
||||
left: -4px;
|
||||
top: -8px;
|
||||
left: -8px;
|
||||
cursor: nw-resize;
|
||||
}
|
||||
|
||||
.box2 {
|
||||
top: -4px;
|
||||
right: -4px;
|
||||
top: -8px;
|
||||
right: -8px;
|
||||
cursor: ne-resize;
|
||||
}
|
||||
|
||||
.box3 {
|
||||
left: -4px;
|
||||
bottom: -4px;
|
||||
left: -8px;
|
||||
bottom: -8px;
|
||||
cursor: sw-resize;
|
||||
}
|
||||
|
||||
.box4 {
|
||||
bottom: -4px;
|
||||
right: -4px;
|
||||
bottom: -8px;
|
||||
right: -8px;
|
||||
cursor: se-resize;
|
||||
}
|
||||
}
|
||||
|
||||
363
admin/src/app/views/printer/edit.vue
Normal file
363
admin/src/app/views/printer/edit.vue
Normal file
@ -0,0 +1,363 @@
|
||||
<template>
|
||||
<div class="main-container">
|
||||
<el-card class="card !border-none mb-[15px]" shadow="never">
|
||||
<el-page-header :content="pageName" :icon="ArrowLeft" @back="back" />
|
||||
</el-card>
|
||||
|
||||
<el-form class="page-form" :model="formData" :rules="formRules" label-width="150px" ref="formRef" v-loading="loading">
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
|
||||
<h3 class="panel-title !text-sm">{{ t('printerSet') }}</h3>
|
||||
|
||||
<el-form-item :label="t('printerName')" prop="printer_name">
|
||||
<el-input v-model.trim="formData.printer_name" clearable :placeholder="t('printerNamePlaceholder')" class="input-width" maxlength="20" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('brand')" prop="brand">
|
||||
<el-select v-model="formData.brand" :placeholder="t('brandPlaceholder')" clearable>
|
||||
<el-option v-for="(item,key) in brandList" :key="key" :label="item" :value="key" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('printerCode')" prop="printer_code">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.printer_code" clearable :placeholder="t('printerCodePlaceholder')" class="input-width" maxlength="30" />
|
||||
<p class="text-[12px] text-[#b2b2b2]">{{ t('printerCodeTips') }}</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('printerKey')" prop="printer_key">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.printer_key" clearable :placeholder="t('printerKeyPlaceholder')" class="input-width" maxlength="30" />
|
||||
<p class="text-[12px] text-[#b2b2b2]">{{ t('printerKeyTips') }}</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('openId')" prop="open_id">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.open_id" clearable :placeholder="t('openIdPlaceholder')" class="input-width" maxlength="30" />
|
||||
<p class="text-[12px] text-[#b2b2b2]">{{ t('openIdTips') }}</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('apikey')" prop="apikey">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.apikey" clearable :placeholder="t('apikeyPlaceholder')" class="input-width" maxlength="60" />
|
||||
<p class="text-[12px] text-[#b2b2b2]">{{ t('apikeyTips') }}</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('printWidth')" prop="print_width">
|
||||
<el-radio-group v-model="formData.print_width">
|
||||
<el-radio value="58mm">58mm</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('status')">
|
||||
<el-switch v-model="formData.status" :active-value="1" :inactive-value="0" />
|
||||
</el-form-item>
|
||||
|
||||
</el-card>
|
||||
<el-card v-for="(item,index) in printerType" :key="item.key" class="box-card !border-none" shadow="never">
|
||||
<h3 class="panel-title !text-sm">{{ item.title }}</h3>
|
||||
|
||||
<div class="flex mb-[10px] py-[8px] bg-[#F5F7F9] text-[14px]">
|
||||
<div class="px-[12px] w-[200px]">{{ t('printTrigger') }}</div>
|
||||
<div class="px-[12px] w-[100px]">{{ t('status') }}</div>
|
||||
<div class="px-[12px] w-[250px]">{{ t('usePrintTemplate') }}</div>
|
||||
<div class="px-[12px] w-[300px] flex-1" v-for="childItem in item.condition" :key="childItem.key">{{ childItem.title }}</div>
|
||||
<div class="px-[12px] w-[200px]">{{ t('printNum') }}</div>
|
||||
</div>
|
||||
|
||||
<template v-if="item.trigger">
|
||||
<div class="flex bg-[#f8f8f9] mb-[10px] py-[20px]" v-for="(triggerItem,triggerKey) in item.trigger" :key="triggerKey">
|
||||
<template v-if="formData.value[item.key]['trigger_' + triggerKey]">
|
||||
<div class="font-bold w-[200px] px-[12px]">{{ triggerItem }}</div>
|
||||
<div class="w-[100px] px-[12px]">
|
||||
<el-switch v-model="formData.value[item.key]['trigger_' + triggerKey].status" :active-value="1" :inactive-value="0" />
|
||||
</div>
|
||||
<div class="w-[250px] px-[12px]">
|
||||
<el-select v-model="formData.value[item.key]['trigger_' + triggerKey].template_id" :placeholder="t('请选择小票打印模板')" clearable>
|
||||
<el-option v-for="templateItem in templateList[item.key]" :key="templateItem.template_id" :label="templateItem.template_name" :value="templateItem.template_id" />
|
||||
</el-select>
|
||||
</div>
|
||||
<template v-for="childItem in item.condition">
|
||||
<div class="w-[300px] px-[12px] flex-1" v-if="childItem.type == 'checkbox'">
|
||||
<el-checkbox-group v-model="formData.value[item.key]['trigger_' + triggerKey][childItem.key]">
|
||||
<el-checkbox v-for="(checkboxItem, index) in childItem.list" :label="checkboxItem.value" :key="index">{{ checkboxItem.name }}</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
</template>
|
||||
<div class="w-[200px] px-[12px]">
|
||||
<el-select v-model="formData.value[item.key]['trigger_' + triggerKey].print_num">
|
||||
<el-option label="1联" :value="1" />
|
||||
<el-option label="2联" :value="2" />
|
||||
<el-option label="3联" :value="3" />
|
||||
<el-option label="4联" :value="4" />
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</el-card>
|
||||
</el-form>
|
||||
|
||||
<div class="fixed-footer-wrap">
|
||||
<div class="fixed-footer">
|
||||
<el-button type="primary" :loading="repeat" @click="confirm(formRef)">{{ t('save') }}</el-button>
|
||||
<el-button @click="back()">{{ t('cancel') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { FormInstance, ElMessage } from 'element-plus'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { deepClone } from '@/utils/common';
|
||||
import { addPrinter, editPrinter,getPrinterInfo,getPrinterType,getPrinterBrand,getPrinterTemplateList } from '@/app/api/printer'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const repeat = ref(false)
|
||||
const loading = ref(true)
|
||||
|
||||
const pageName = route.meta.title
|
||||
|
||||
/**
|
||||
* 表单数据
|
||||
*/
|
||||
const initialFormData:any = {
|
||||
printer_id: route.query.printer_id || 0,
|
||||
brand: '',
|
||||
printer_name: '',
|
||||
printer_code: '',
|
||||
printer_key: '',
|
||||
open_id: '',
|
||||
apikey: '',
|
||||
template_type: [],
|
||||
trigger: [],
|
||||
value: {},
|
||||
print_width: '58mm',
|
||||
status: 1,
|
||||
}
|
||||
|
||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = computed(() => {
|
||||
return {
|
||||
printer_name: [
|
||||
{ required: true, message: t('printerNamePlaceholder'), trigger: 'blur' },
|
||||
],
|
||||
brand: [
|
||||
{ required: true, message: t('brandPlaceholder'), trigger: 'blur' },
|
||||
],
|
||||
printer_code: [
|
||||
{ required: true, message: t('printerCodePlaceholder'), trigger: 'blur' },
|
||||
],
|
||||
printer_key: [
|
||||
{ required: true, message: t('printerKeyPlaceholder'), trigger: 'blur' },
|
||||
],
|
||||
open_id: [
|
||||
{ required: true, message: t('openIdPlaceholder'), trigger: 'blur' },
|
||||
],
|
||||
apikey: [
|
||||
{ required: true, message: t('apikeyPlaceholder'), trigger: 'blur' },
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
const printerType = ref([])
|
||||
|
||||
const init = async ()=> {
|
||||
await getPrinterType({}).then((res: any) => {
|
||||
if (res.data) {
|
||||
printerType.value = res.data;
|
||||
|
||||
for (let i = 0; i < printerType.value.length; i++) {
|
||||
let item: any = printerType.value[i];
|
||||
|
||||
formData.value[item.key] = {};
|
||||
|
||||
let extendData: any = {};
|
||||
for (let ci = 0; ci < item.condition.length; ci++) {
|
||||
let condition = item.condition[ci];
|
||||
extendData[condition.key] = [];
|
||||
if (condition.type == 'checkbox') {
|
||||
extendData[condition.key] = []; // 默认全选
|
||||
for (let k = 0; k < condition.list.length; k++) {
|
||||
extendData[condition.key].push(condition.list[k].value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let key in item.trigger) {
|
||||
formData.value[item.key]['trigger_' + key] = {
|
||||
status: 1,
|
||||
template_id: '',
|
||||
print_num: 1,
|
||||
};
|
||||
Object.assign(formData.value[item.key]['trigger_' + key], deepClone(extendData));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (!formData.printer_id) {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
|
||||
if (formData.printer_id) {
|
||||
getPrinterInfo(formData.printer_id).then((res: any) => {
|
||||
let data = res.data;
|
||||
if (data) Object.keys(formData).forEach((key: string) => {
|
||||
if (data[key] != undefined) {
|
||||
if (key == 'value') {
|
||||
for (let ck in formData[key]){
|
||||
Object.assign(formData[key][ck],data[key][ck])
|
||||
}
|
||||
} else {
|
||||
formData[key] = data[key]
|
||||
}
|
||||
}
|
||||
})
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
init()
|
||||
|
||||
const brandList = ref([])
|
||||
getPrinterBrand({}).then((res: any) => {
|
||||
brandList.value = res.data;
|
||||
})
|
||||
|
||||
const templateList:any = ref({}) // 小票打印模板列表
|
||||
getPrinterTemplateList({}).then((res:any)=> {
|
||||
if (res.data) {
|
||||
let data = res.data;
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
let item = data[i];
|
||||
if (templateList.value[item.template_type] == undefined) {
|
||||
templateList.value[item.template_type] = []
|
||||
}
|
||||
templateList.value[item.template_type].push({
|
||||
template_id: item.template_id,
|
||||
template_name: item.template_name,
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 确认
|
||||
* @param formEl
|
||||
*/
|
||||
const confirm = async(formEl: FormInstance | undefined) => {
|
||||
if (loading.value || !formEl) return
|
||||
|
||||
if (printerType.value.length == 0) {
|
||||
ElMessage({
|
||||
type: 'warning',
|
||||
message: t('printTypeEmpty')
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
let save = formData.printer_id ? editPrinter : addPrinter
|
||||
|
||||
await formEl.validate(async(valid) => {
|
||||
if (valid) {
|
||||
|
||||
let validateFlag = false;
|
||||
let validateMessage = '';
|
||||
|
||||
for (let i = 0; i < printerType.value.length; i++) {
|
||||
let item: any = printerType.value[i];
|
||||
|
||||
for (let k = 0; k < Object.keys(item.trigger).length; k++) {
|
||||
let triggerItem = Object.keys(item.trigger)[k];
|
||||
if (formData.value[item.key]['trigger_' + triggerItem].status == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!formData.value[item.key]['trigger_' + triggerItem].template_id) {
|
||||
validateFlag = true;
|
||||
validateMessage = `请设置${ item.title }[${ item.trigger[triggerItem] }]的小票打印模板`
|
||||
break;
|
||||
}
|
||||
|
||||
let isFail = false;
|
||||
for (let ck = 0; ck < item.condition.length; ck++) {
|
||||
let condition = item.condition[ck];
|
||||
if (condition.type == 'checkbox') {
|
||||
if (formData.value[item.key]['trigger_' + triggerItem][condition.key].length == 0) {
|
||||
validateFlag = true;
|
||||
validateMessage = `请设置${ item.title }[${ item.trigger[triggerItem] }]的${ condition.title }`
|
||||
isFail = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 防止重复循环
|
||||
if (isFail) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 防止重复循环
|
||||
if (validateFlag) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (validateFlag) {
|
||||
ElMessage({
|
||||
type: 'warning',
|
||||
message: validateMessage
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
formData.template_type = [];
|
||||
formData.trigger = [];
|
||||
|
||||
for (let key in formData.value) {
|
||||
for (let childKey in formData.value[key]) {
|
||||
formData.trigger.push(key + '_' + childKey);
|
||||
}
|
||||
formData.template_type.push(key)
|
||||
}
|
||||
|
||||
if (repeat.value) return
|
||||
repeat.value = true
|
||||
|
||||
let data = formData
|
||||
|
||||
save(data).then(res => {
|
||||
repeat.value = false
|
||||
if (!formData.printer_id) {
|
||||
router.push('/printer/list')
|
||||
}
|
||||
}).catch(err => {
|
||||
repeat.value = false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const back = () => {
|
||||
router.push('/printer/list')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
227
admin/src/app/views/printer/list.vue
Normal file
227
admin/src/app/views/printer/list.vue
Normal file
@ -0,0 +1,227 @@
|
||||
<template>
|
||||
<div class="main-container">
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
|
||||
<div class="flex justify-between items-center mb-[5px]">
|
||||
<span class="text-lg">{{pageName}}</span>
|
||||
<el-button type="primary" @click="addEvent">
|
||||
{{ t('addPrinter') }}
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<el-tabs class="demo-tabs" model-value="/printer/list" @tab-change="handleClick">
|
||||
<el-tab-pane :label="t('tabPrinterManager')" name="/printer/list" />
|
||||
<el-tab-pane :label="t('tabPrinterTemplate')" name="/printer/template/list" />
|
||||
</el-tabs>
|
||||
|
||||
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
|
||||
<el-form :inline="true" :model="printerTable.searchParam" ref="searchFormRef">
|
||||
<el-form-item :label="t('printerName')" prop="printer_name">
|
||||
<el-input v-model.trim="printerTable.searchParam.printer_name" :placeholder="t('printerNamePlaceholder')" maxlength="20" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="loadPrinterList()">{{ t('search') }}</el-button>
|
||||
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<div class="mt-[10px]">
|
||||
<el-table :data="printerTable.data" size="large" v-loading="printerTable.loading">
|
||||
<template #empty>
|
||||
<span>{{ !printerTable.loading ? t('emptyData') : '' }}</span>
|
||||
</template>
|
||||
|
||||
<el-table-column prop="printer_name" :label="t('printerName')" min-width="220" :show-overflow-tooltip="true"/>
|
||||
|
||||
<el-table-column prop="brand_name" :label="t('brand')" min-width="120" :show-overflow-tooltip="true"/>
|
||||
|
||||
<el-table-column prop="print_width" :label="t('printWidth')" min-width="120" :show-overflow-tooltip="true"/>
|
||||
|
||||
<el-table-column prop="status" :label="t('status')" min-width="80" :show-overflow-tooltip="true" >
|
||||
<template #default="{ row }">
|
||||
<el-tag type="success" v-if="row.status == 1" @click="modifyPrinterStatusEvent(row.printer_id, 0)" class="cursor-pointer">{{ t('statusOn') }}</el-tag>
|
||||
<el-tag type="info" v-else @click="modifyPrinterStatusEvent(row.printer_id, 1)" class="cursor-pointer">{{ t('statusOff') }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column :label="t('operation')" fixed="right" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link @click="testPrintEvent(row.printer_id)">{{ t('testPrint') }}</el-button>
|
||||
<el-button type="primary" link @click="refreshTokenEvent(row.printer_id)">{{ t('refreshToken') }}</el-button>
|
||||
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
|
||||
<el-button type="primary" link @click="deleteEvent(row.printer_id)">{{ t('delete') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
<div class="mt-[16px] flex justify-end">
|
||||
<el-pagination v-model:current-page="printerTable.page" v-model:page-size="printerTable.limit"
|
||||
layout="total, sizes, prev, pager, next, jumper" :total="printerTable.total"
|
||||
@size-change="loadPrinterList()" @current-change="loadPrinterList" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getPrinterPageList, modifyPrinterStatus, deletePrinter,refreshPrinterToken,testPrint } from '@/app/api/printer'
|
||||
import { ElMessageBox,FormInstance } from 'element-plus'
|
||||
import { useRoute,useRouter } from 'vue-router'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const pageName = route.meta.title;
|
||||
const repeat = ref(false)
|
||||
|
||||
const handleClick = (path: string) => {
|
||||
router.push({ path })
|
||||
}
|
||||
|
||||
const printerTable = reactive({
|
||||
page: 1,
|
||||
limit: 10,
|
||||
total: 0,
|
||||
loading: true,
|
||||
data: [],
|
||||
searchParam:{
|
||||
printer_name:''
|
||||
}
|
||||
})
|
||||
|
||||
const searchFormRef = ref<FormInstance>()
|
||||
|
||||
/**
|
||||
* 获取小票打印机列表
|
||||
*/
|
||||
const loadPrinterList = (page: number = 1) => {
|
||||
printerTable.loading = true
|
||||
printerTable.page = page
|
||||
|
||||
getPrinterPageList({
|
||||
page: printerTable.page,
|
||||
limit: printerTable.limit,
|
||||
...printerTable.searchParam
|
||||
}).then(res => {
|
||||
printerTable.loading = false
|
||||
printerTable.data = res.data.data
|
||||
printerTable.total = res.data.total
|
||||
}).catch(() => {
|
||||
printerTable.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
loadPrinterList()
|
||||
|
||||
const isRepeat = ref(false)
|
||||
|
||||
// 修改小票打印机状态
|
||||
const modifyPrinterStatusEvent = (printer_id: any, status: any) => {
|
||||
if (isRepeat.value) return
|
||||
isRepeat.value = true
|
||||
|
||||
modifyPrinterStatus({
|
||||
printer_id,
|
||||
status
|
||||
}).then((res) => {
|
||||
loadPrinterList()
|
||||
isRepeat.value = false
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加小票打印机
|
||||
*/
|
||||
const addEvent = () => {
|
||||
router.push('/printer/add')
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑小票打印机
|
||||
* @param data
|
||||
*/
|
||||
const editEvent = (data: any) => {
|
||||
router.push('/printer/edit?printer_id=' + data.printer_id)
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除小票打印机
|
||||
*/
|
||||
const deleteEvent = (id: number) => {
|
||||
ElMessageBox.confirm(t('printerDeleteTips'), t('warning'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning',
|
||||
}
|
||||
).then(() => {
|
||||
if (repeat.value) return
|
||||
repeat.value = true
|
||||
deletePrinter(id).then(() => {
|
||||
loadPrinterList()
|
||||
repeat.value = false
|
||||
}).catch(() => {
|
||||
repeat.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const resetForm = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
formEl.resetFields()
|
||||
loadPrinterList()
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试打印
|
||||
* @param printer_id
|
||||
*/
|
||||
const testPrintEvent = (printer_id: any) => {
|
||||
ElMessageBox.confirm(t('testPrintTips'), t('warning'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning',
|
||||
}
|
||||
).then(() => {
|
||||
if (repeat.value) return
|
||||
repeat.value = true
|
||||
testPrint(printer_id).then((res: any) => {
|
||||
repeat.value = false
|
||||
}).catch(() => {
|
||||
repeat.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 授权(重新获取token)
|
||||
* @param printer_id
|
||||
*/
|
||||
const refreshTokenEvent = (printer_id: any) => {
|
||||
ElMessageBox.confirm(t('refreshTokenTips'), t('warning'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning',
|
||||
}
|
||||
).then(() => {
|
||||
if (repeat.value) return
|
||||
repeat.value = true
|
||||
refreshPrinterToken(printer_id).then((res: any) => {
|
||||
loadPrinterList()
|
||||
repeat.value = false
|
||||
}).catch(() => {
|
||||
repeat.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
350
admin/src/app/views/printer/template_edit.vue
Normal file
350
admin/src/app/views/printer/template_edit.vue
Normal file
@ -0,0 +1,350 @@
|
||||
<template>
|
||||
<div class="main-container">
|
||||
<el-card class="card !border-none mb-[15px]" shadow="never">
|
||||
<el-page-header :content="pageName" :icon="ArrowLeft" @back="back" />
|
||||
</el-card>
|
||||
|
||||
<el-form class="page-form" :model="formData" :rules="formRules" label-width="150px" ref="formRef" v-loading="loading">
|
||||
|
||||
<div class="flex">
|
||||
|
||||
<div class="flex-1 mr-[20px] bg-[#fff]">
|
||||
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
|
||||
<h3 class="panel-title !text-sm">{{ t('templateInfoLabel') }}</h3>
|
||||
|
||||
<el-form-item :label="t('templateName')" prop="template_name">
|
||||
<el-input v-model.trim="formData.template_name" clearable :placeholder="t('templateNamePlaceholder')" class="input-width" maxlength="20" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('templateType')" prop="template_type" v-if="printerType.length">
|
||||
<el-radio-group v-model="formData.template_type">
|
||||
<el-radio v-for="item in printerType" :key="item.key" :label="item.key" @change="handlePrintType">{{ item.title }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
</el-card>
|
||||
<el-card class="box-card !border-none" shadow="never" v-if="printerType.length">
|
||||
|
||||
<h3 class="panel-title !text-sm">{{ t('templateEditLabel') }}</h3>
|
||||
|
||||
<div v-for="item in template" :key="item.key" class="bg-[#f8f8f9] mb-[20px] py-[20px] px-[40px] text-[14px]">
|
||||
<h4 class="panel-title !text-sm">{{ item.title }}</h4>
|
||||
<div v-for="(childItem,index) in item.list" :key="childItem.key" class="ml-[30px]" :style="{ 'margin-bottom' : item.list.length == (index + 1) ? '0' : '20px' }">
|
||||
<div class="flex">
|
||||
<el-checkbox v-model="formData.value[item.key][childItem.key].status" v-if="childItem.label" :label="childItem.label" :value="childItem.status" :true-value="1" :false-value="0" class="w-[180px] mr-[10px]" :disabled="childItem.disabled" />
|
||||
|
||||
<template v-if="childItem.type == 'input'">
|
||||
<el-input v-model.trim="formData.value[item.key][childItem.key].value" clearable :placeholder="'请输入' + (childItem.placeholder ? childItem.placeholder : childItem.label)" class="input-width mr-[30px]" maxlength="32" />
|
||||
</template>
|
||||
|
||||
<template v-if="childItem.type == 'checkbox'">
|
||||
<el-checkbox-group v-model="formData.value[item.key][childItem.key].value" class="mr-[30px]">
|
||||
<el-checkbox v-for="(checkboxItem, key) in childItem.list" :label="key" :key="key" :disabled="childItem.disabled">{{ checkboxItem }}</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</template>
|
||||
|
||||
<template v-if="childItem.type == 'select'">
|
||||
|
||||
<div class="leading-[30px] w-[50px] text-center text-[#707070] bg-[#d7d7d7] border-1 border-solid border-[#ededed]">{{ childItem.text }}</div>
|
||||
<el-select v-model="formData.value[item.key][childItem.key].value" class="!w-[130px] mr-[30px]">
|
||||
<el-option v-for="(item,key) in childItem.list" :key="key" :label="item" :value="key" />
|
||||
</el-select>
|
||||
|
||||
</template>
|
||||
|
||||
<template v-if="childItem.fontSize">
|
||||
<div class="flex mr-[30px]">
|
||||
<div class="leading-[30px] w-[50px] text-center text-[#707070] bg-[#d7d7d7] border-1 border-solid border-[#ededed]">字号</div>
|
||||
<el-select v-model="formData.value[item.key][childItem.key].fontSize" class="!w-[130px]">
|
||||
<el-option label="小" value="normal" />
|
||||
<!-- <el-option label="小" value="small" />-->
|
||||
<el-option label="大" value="big" />
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<template v-if="childItem.fontWeight">
|
||||
|
||||
<div class="flex mr-[30px]">
|
||||
<div class="leading-[30px] w-[50px] text-center text-[#707070] bg-[#d7d7d7] border-1 border-solid border-[#ededed]">粗细</div>
|
||||
<el-select v-model="formData.value[item.key][childItem.key].fontWeight" class="!w-[130px]">
|
||||
<el-option label="正常" value="normal" />
|
||||
<el-option label="加粗" value="bold" />
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
|
||||
<div v-if="childItem.remark" class="text-[12px] text-[#b2b2b2] mt-[10px]">{{ childItem.remark }}</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<el-card class="box-card !border-none w-[450px]" shadow="never">
|
||||
|
||||
<h3 class="panel-title !text-sm">{{ t('preview') }}</h3>
|
||||
|
||||
<!-- 动态加载组件 -->
|
||||
<component :is="modules[previewPath]" :value="formData.value"/>
|
||||
|
||||
</el-card>
|
||||
|
||||
</div>
|
||||
|
||||
</el-form>
|
||||
|
||||
<div class="fixed-footer-wrap">
|
||||
<div class="fixed-footer">
|
||||
<el-button type="primary" :loading="repeat" @click="confirm(formRef)">{{ t('save') }}</el-button>
|
||||
<el-button @click="back()">{{ t('cancel') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { FormInstance, ElMessage } from 'element-plus'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { getPrinterType, addPrinterTemplate, editPrinterTemplate, getPrinterTemplateInfo } from '@/app/api/printer'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const pageName = route.meta.title
|
||||
const repeat = ref(false)
|
||||
const loading = ref(true)
|
||||
|
||||
/**
|
||||
* 表单数据
|
||||
*/
|
||||
const initialFormData:any = {
|
||||
template_id: route.query.template_id || 0,
|
||||
template_type: '',
|
||||
template_name: '',
|
||||
value: {},
|
||||
}
|
||||
|
||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = computed(() => {
|
||||
return {
|
||||
template_name: [
|
||||
{ required: true, message: t('templateNamePlaceholder'), trigger: 'blur' },
|
||||
],
|
||||
template_type: [
|
||||
{ required: true, message: t('templateTypePlaceholder'), trigger: 'blur' },
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
// 动态加载组件
|
||||
const modulesFiles = import.meta.glob('./components/*.vue', { eager: true })
|
||||
const addonModulesFiles = import.meta.glob('@/addon/**/views/printer/components/*.vue', { eager: true })
|
||||
addonModulesFiles && Object.assign(modulesFiles, addonModulesFiles)
|
||||
|
||||
const modules:any = {}
|
||||
for (const [key, value] of Object.entries(modulesFiles)) {
|
||||
const moduleName:any = key.split('/').pop()
|
||||
const name = moduleName.split('.')[0]
|
||||
modules[name] = value.default
|
||||
}
|
||||
|
||||
const previewPath = ref('')
|
||||
const printerType:any = ref([])
|
||||
const template:any = ref([])
|
||||
|
||||
const init = async ()=> {
|
||||
await getPrinterType({}).then((res: any) => {
|
||||
if (res.data && res.data.length) {
|
||||
printerType.value = res.data;
|
||||
handlePrintType(printerType.value[0].key, Boolean(parseInt(formData.template_id)));
|
||||
}
|
||||
if (!formData.template_id) {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
|
||||
if(formData.template_id) {
|
||||
getPrinterTemplateInfo(formData.template_id).then((res:any)=>{
|
||||
let data = res.data;
|
||||
if (data && Object.keys(data).length) {
|
||||
Object.keys(formData).forEach((key: string) => {
|
||||
if (key == 'value') {
|
||||
for (let ck in formData[key]){
|
||||
Object.assign(formData[key][ck],data[key][ck])
|
||||
}
|
||||
} else {
|
||||
formData[key] = data[key]
|
||||
}
|
||||
})
|
||||
loading.value = false
|
||||
}else {
|
||||
ElMessage({
|
||||
type: 'warning',
|
||||
duration: 1500,
|
||||
message: t('printTemplateEmpty')
|
||||
})
|
||||
setTimeout(()=>{
|
||||
back();
|
||||
loading.value = false
|
||||
}, 2000);
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
init();
|
||||
|
||||
// 切换模板类型
|
||||
const handlePrintType = (value: any, load: boolean = false) => {
|
||||
for (let i = 0; i < printerType.value.length; i++) {
|
||||
if (printerType.value[i].key == value) {
|
||||
formData.template_type = printerType.value[i].key;
|
||||
previewPath.value = printerType.value[i].path;
|
||||
template.value = printerType.value[i].template;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 清空模板内容数据
|
||||
for (let key in formData.value) {
|
||||
delete formData.value[key];
|
||||
}
|
||||
|
||||
refreshTemplateData();
|
||||
}
|
||||
|
||||
// 刷新模板内容数据
|
||||
const refreshTemplateData = ()=> {
|
||||
for (let i = 0; i < template.value.length; i++) {
|
||||
let item: any = template.value[i];
|
||||
formData.value[item.key] = {};
|
||||
for (let k = 0; k < item.list.length; k++) {
|
||||
let childItem = item.list[k];
|
||||
formData.value[item.key][childItem.key] = {
|
||||
type: childItem.type,
|
||||
value: childItem.value,
|
||||
status: childItem.status,
|
||||
fontSize: childItem.fontSize,
|
||||
fontWeight: childItem.fontWeight,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认
|
||||
* @param formEl
|
||||
*/
|
||||
const confirm = async(formEl: FormInstance | undefined) => {
|
||||
if (loading.value || !formEl) return
|
||||
|
||||
if (printerType.value.length == 0) {
|
||||
ElMessage({
|
||||
type: 'warning',
|
||||
message: t('printTypeEmpty')
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
let save = formData.template_id ? editPrinterTemplate : addPrinterTemplate
|
||||
|
||||
await formEl.validate(async(valid) => {
|
||||
if (valid) {
|
||||
|
||||
let validateFlag = false;
|
||||
let validateMessage = '';
|
||||
|
||||
for (let i = 0; i < template.value.length; i++) {
|
||||
|
||||
let item: any = template.value[i];
|
||||
let isFail = false;
|
||||
|
||||
for (let k = 0; k < item.list.length; k++) {
|
||||
let childItem = item.list[k];
|
||||
if (formData.value[item.key][childItem.key].status == 0) {
|
||||
continue;
|
||||
}
|
||||
if (childItem.type == 'input') {
|
||||
if (formData.value[item.key][childItem.key].value == '') {
|
||||
validateFlag = true;
|
||||
validateMessage = `请输入${ childItem.label }`;
|
||||
isFail = true;
|
||||
break;
|
||||
}
|
||||
} else if (childItem.type == 'select') {
|
||||
if (formData.value[item.key][childItem.key].value == '') {
|
||||
validateFlag = true;
|
||||
validateMessage = `${ childItem.label }未设置[${ childItem.text }]`;
|
||||
isFail = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 防止重复循环
|
||||
if (isFail) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (validateFlag) {
|
||||
ElMessage({
|
||||
type: 'warning',
|
||||
message: validateMessage
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < template.value.length; i++) {
|
||||
|
||||
let item: any = template.value[i];
|
||||
|
||||
for (let k = 0; k < item.list.length; k++) {
|
||||
let childItem = item.list[k];
|
||||
if (childItem.type == 'checkbox') {
|
||||
if (formData.value[item.key][childItem.key].value.length) {
|
||||
formData.value[item.key][childItem.key].status = 1;
|
||||
} else {
|
||||
formData.value[item.key][childItem.key].status = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (repeat.value) return
|
||||
repeat.value = true
|
||||
|
||||
let data = formData
|
||||
|
||||
save(data).then(res => {
|
||||
repeat.value = false
|
||||
if (!formData.template_id) {
|
||||
back()
|
||||
}
|
||||
}).catch(err => {
|
||||
repeat.value = false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const back = () => {
|
||||
router.push('/printer/template/list')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
162
admin/src/app/views/printer/template_list.vue
Normal file
162
admin/src/app/views/printer/template_list.vue
Normal file
@ -0,0 +1,162 @@
|
||||
<template>
|
||||
<div class="main-container">
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
|
||||
<div class="flex justify-between items-center mb-[5px]">
|
||||
<span class="text-lg">{{pageName}}</span>
|
||||
<el-button type="primary" @click="addEvent">
|
||||
{{ t('addPrinterTemplate') }}
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<el-tabs class="demo-tabs" model-value="/printer/template/list" @tab-change="handleClick">
|
||||
<el-tab-pane :label="t('tabPrinterManager')" name="/printer/list" />
|
||||
<el-tab-pane :label="t('tabPrinterTemplate')" name="/printer/template/list" />
|
||||
</el-tabs>
|
||||
|
||||
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
|
||||
<el-form :inline="true" :model="printerTemplateTable.searchParam" ref="searchFormRef">
|
||||
<el-form-item :label="t('templateName')" prop="template_name">
|
||||
<el-input v-model="printerTemplateTable.searchParam.template_name" :placeholder="t('templateNamePlaceholder')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('templateType')" prop="template_type">
|
||||
<el-select v-model="printerTemplateTable.searchParam.template_type" :placeholder="t('templateTypePlaceholder')" clearable>
|
||||
<el-option v-for="(item,key) in printerType" :key="itemkey" :label="item.title" :value="item.key" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="loadPrinterTemplateList()">{{ t('search') }}</el-button>
|
||||
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<div class="mt-[10px]">
|
||||
<el-table :data="printerTemplateTable.data" size="large" v-loading="printerTemplateTable.loading">
|
||||
<template #empty>
|
||||
<span>{{ !printerTemplateTable.loading ? t('emptyData') : '' }}</span>
|
||||
</template>
|
||||
|
||||
<el-table-column prop="template_name" :label="t('templateName')" min-width="220" :show-overflow-tooltip="true"/>
|
||||
|
||||
<el-table-column prop="template_type_name" :label="t('templateType')" min-width="180" :show-overflow-tooltip="true"/>
|
||||
|
||||
<el-table-column prop="create_time" :label="t('createTime')" min-width="120" />
|
||||
|
||||
<el-table-column :label="t('operation')" fixed="right" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
|
||||
<el-button type="primary" link @click="deleteEvent(row.template_id)">{{ t('delete') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
<div class="mt-[16px] flex justify-end">
|
||||
<el-pagination v-model:current-page="printerTemplateTable.page" v-model:page-size="printerTemplateTable.limit"
|
||||
layout="total, sizes, prev, pager, next, jumper" :total="printerTemplateTable.total"
|
||||
@size-change="loadPrinterTemplateList()" @current-change="loadPrinterTemplateList" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getPrinterTemplatePageList, deletePrinterTemplate,getPrinterType } from '@/app/api/printer'
|
||||
import { ElMessageBox,FormInstance } from 'element-plus'
|
||||
import { useRoute,useRouter } from 'vue-router'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const pageName = route.meta.title;
|
||||
|
||||
const handleClick = (path: string) => {
|
||||
router.push({ path })
|
||||
}
|
||||
|
||||
const printerTemplateTable = reactive({
|
||||
page: 1,
|
||||
limit: 10,
|
||||
total: 0,
|
||||
loading: true,
|
||||
data: [],
|
||||
searchParam: {
|
||||
template_name: '',
|
||||
template_type: '',
|
||||
}
|
||||
})
|
||||
|
||||
const searchFormRef = ref<FormInstance>()
|
||||
|
||||
const printerType = ref([])
|
||||
getPrinterType({}).then((res: any) => {
|
||||
if (res.data) {
|
||||
printerType.value = res.data;
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 获取小票打印模板列表
|
||||
*/
|
||||
const loadPrinterTemplateList = (page: number = 1) => {
|
||||
printerTemplateTable.loading = true
|
||||
printerTemplateTable.page = page
|
||||
|
||||
getPrinterTemplatePageList({
|
||||
page: printerTemplateTable.page,
|
||||
limit: printerTemplateTable.limit,
|
||||
...printerTemplateTable.searchParam
|
||||
}).then(res => {
|
||||
printerTemplateTable.loading = false
|
||||
printerTemplateTable.data = res.data.data
|
||||
printerTemplateTable.total = res.data.total
|
||||
}).catch(() => {
|
||||
printerTemplateTable.loading = false
|
||||
})
|
||||
}
|
||||
loadPrinterTemplateList()
|
||||
|
||||
/**
|
||||
* 添加小票打印模板
|
||||
*/
|
||||
const addEvent = () => {
|
||||
router.push('/printer/template/add')
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑小票打印模板
|
||||
* @param data
|
||||
*/
|
||||
const editEvent = (data: any) => {
|
||||
router.push('/printer/template/edit?template_id=' + data.template_id)
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除小票打印模板
|
||||
*/
|
||||
const deleteEvent = (id: number) => {
|
||||
ElMessageBox.confirm(t('printerTemplateDeleteTips'), t('warning'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning',
|
||||
}
|
||||
).then(() => {
|
||||
deletePrinterTemplate(id).then(() => {
|
||||
loadPrinterTemplateList()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const resetForm = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
formEl.resetFields()
|
||||
loadPrinterTemplateList()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@ -91,8 +91,6 @@ const formRules = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
// const emit = defineEmits(['complete'])
|
||||
|
||||
const setFormData = async (row: any = null) => {
|
||||
loading.value = true
|
||||
Object.assign(formData, initialFormData)
|
||||
|
||||
@ -40,7 +40,6 @@
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import type { FormInstance } from 'element-plus'
|
||||
// import { editNoticeStatus } from '@/app/api/notice'
|
||||
|
||||
const showDialog = ref(false)
|
||||
const loading = ref(true)
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('weappTempKey')">
|
||||
<div class="input-width"> {{ formData.temp_key }} </div>
|
||||
<div class="input-width"> {{ formData.tid }} </div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('content')">
|
||||
@ -54,7 +54,7 @@ const initialFormData = {
|
||||
content: [],
|
||||
first: '',
|
||||
remark: '',
|
||||
temp_key: ''
|
||||
tid: ''
|
||||
}
|
||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||
|
||||
|
||||
@ -9,15 +9,15 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('aliSign')" prop="sign">
|
||||
<el-input v-model="formData.sign" :placeholder="t('aliSignPlaceholder')" class="input-width" show-word-limit clearable />
|
||||
<el-input v-model.trim="formData.sign" :placeholder="t('aliSignPlaceholder')" class="input-width" show-word-limit clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('aliAppKey')" prop="app_key">
|
||||
<el-input v-model="formData.app_key" :placeholder="t('aliAppKeyPlaceholder')" class="input-width" clearable />
|
||||
<el-input v-model.trim="formData.app_key" :placeholder="t('aliAppKeyPlaceholder')" class="input-width" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('aliSecretKey')" prop="secret_key">
|
||||
<el-input v-model="formData.secret_key" :placeholder="t('aliSecretKeyPlaceholder')" class="input-width" clearable />
|
||||
<el-input v-model.trim="formData.secret_key" :placeholder="t('aliSecretKeyPlaceholder')" class="input-width" clearable />
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
|
||||
@ -9,19 +9,19 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('tencentSign')" prop="sign">
|
||||
<el-input v-model="formData.sign" :placeholder="t('tencentSignPlaceholder')" class="input-width" show-word-limit clearable />
|
||||
<el-input v-model.trim="formData.sign" :placeholder="t('tencentSignPlaceholder')" class="input-width" show-word-limit clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('tencentAppId')" prop="app_id">
|
||||
<el-input v-model="formData.app_id" :placeholder="t('tencentAppIdPlaceholder')" class="input-width" show-word-limit clearable />
|
||||
<el-input v-model.trim="formData.app_id" :placeholder="t('tencentAppIdPlaceholder')" class="input-width" show-word-limit clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('tencentSecretId')" prop="secret_id">
|
||||
<el-input v-model="formData.secret_id" :placeholder="t('tencentSecretIdPlaceholder')" class="input-width" clearable />
|
||||
<el-input v-model.trim="formData.secret_id" :placeholder="t('tencentSecretIdPlaceholder')" class="input-width" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('tencentSecretKey')" prop="secret_key">
|
||||
<el-input v-model="formData.secret_key" :placeholder="t('tencentSecretKeyPlaceholder')" class="input-width" clearable />
|
||||
<el-input v-model.trim="formData.secret_key" :placeholder="t('tencentSecretKeyPlaceholder')" class="input-width" clearable />
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
|
||||
@ -63,19 +63,19 @@ const formData = reactive<Record<string, number | boolean>>({
|
||||
|
||||
const formRules = computed(() => {
|
||||
return {
|
||||
type: [
|
||||
{
|
||||
required: true,
|
||||
trigger: 'change',
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (!formData.is_mobile && !formData.is_username) {
|
||||
callback(new Error(t('mobileOrUsernameNoEmpty')))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
// type: [
|
||||
// {
|
||||
// required: true,
|
||||
// trigger: 'change',
|
||||
// validator: (rule: any, value: any, callback: any) => {
|
||||
// if (!formData.is_mobile && !formData.is_username) {
|
||||
// callback(new Error(t('mobileOrUsernameNoEmpty')))
|
||||
// } else {
|
||||
// callback()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('noticeKey')" prop="key">
|
||||
<el-select v-model="recordsTableData.searchParam.key" clearable :placeholder="t('groupIdPlaceholder')" class="input-width">
|
||||
<el-select v-model="recordsTableData.searchParam.key" clearable :placeholder="t('noticeKeyPlaceholder')" class="input-width" popper-class="notice">
|
||||
<el-option :label="t('selectPlaceholder')" value="" />
|
||||
<el-option-group v-for="(group, gindex) in templateList" :key="gindex" :label="group.label">
|
||||
<el-option :label="item.name" :value="item.value" :disabled="item.disabled ?? false" v-for="(item, index) in group.list" :key="index" />
|
||||
@ -172,4 +172,9 @@ const infoEvent = (data: any) => {
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss">
|
||||
.notice .el-select-group__title{
|
||||
font-size: 14px;;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
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