Merge remote-tracking branch 'origin/leng_dev' into lei_dev

This commit is contained in:
aeizzz 2023-03-06 10:44:21 +08:00
commit bb001b05a3
317 changed files with 25966 additions and 23936 deletions

View File

@ -1,7 +1,7 @@
## 全局组件
- 组件支持`四种`svg图标
- `四种`图标均支持 color 和 size 属性,使用示例见下文:
- 组件支持`四种`svg 图标
- `四种`图标均支持 color 和 size 属性,使用示例见下文:
```mermaid
# font-awesome的图标使用 fa 作为前缀(带个空格)
@ -18,31 +18,30 @@
<SvgIcon name="iconfont icon-user" size="20" />
```
有时Icon组件会覆盖不了图标的原有颜色或大小请检查SVG文件的源代码。
有时Icon 组件会覆盖不了图标的原有颜色或大小,请检查 SVG 文件的源代码。
## 图标添加与配置
### 本地图标
1. 将SVG图标文件放入本地`/src/assets/icons`文件夹,然后重新编译项目。
1. 将 SVG 图标文件,放入本地`/src/assets/icons`文件夹,然后重新编译项目。
2. 系统会自动加载该目录下的所有图标文件备用,现在你可以使用`Icon`组件来显示图标了。
3. 示例:`<SvgIcon name="local-SVG的文件名" />`
4. 不建议在此文件夹放置`非常大、非常多`的文件,可能会影响系统加载速度,当确有此方面需求时,请将文件放置到其他位置,并单独导入和使用图标。
### font-awesome 图标
1. 此图标库目前 `pigx-ui` 已经默认加载。加载代码在 `/src/utils/setIconfont.ts`中的cssUrls中。
2. 你可以直接使用font-awesome 4.7.0的所有图标,这些图标可以在这里 https://fontawesome.com.cn/faicons/ 找到,当然你也可以直接使用图标选择器寻找图标。
3. 示例:<SvgIcon name="fa fa-pencil" />注意图标名称一定是以fa加一个空格开头
1. 此图标库目前 `pigx-ui` 已经默认加载。加载代码在 `/src/utils/setIconfont.ts`中的 cssUrls 中。
2. 你可以直接使用 font-awesome 4.7.0 的所有图标,这些图标可以在这里 https://fontawesome.com.cn/faicons/ 找到,当然你也可以直接使用图标选择器寻找图标。
3. 示例:<SvgIcon name="fa fa-pencil" />,注意图标名称一定是以 fa 加一个空格开头
### element-plus 图标
1. 此图标库目前 `pigx-ui` 已经默认加载,加载代码在 `/src/main.ts` 执行的 elementIcons 方法中。
2. 你可以直接使用 `element-plus/icons-vue ^2.0.10` 的所有图标,在使用 `element-plus` 图标时,请使用`ele` 作为前缀,图标名称请使用:首字母大写的驼峰语法。
3. 示例:<SvgIcon name="ele-RefreshRight" />
### iconfont 图标
1. 目前系统未使用任何iconfont图标你可以获取iconfont图标库项目的Font class链接后设置到 `/src/utils/setIconfont.ts` 中的 `cssUrls` 中,系统会自动加载链接中的所有图标以供使用。
2. 示例:`<SvgIcon name="iconfont icon-user" />`注意图标名称一定是以iconfont加一个空格开头以图标名称结尾。
1. 目前系统未使用任何 iconfont 图标,你可以获取 iconfont 图标库项目的 Font class 链接后,设置到 `/src/utils/setIconfont.ts` 中的 `cssUrls` 中,系统会自动加载链接中的所有图标以供使用。
2. 示例:`<SvgIcon name="iconfont icon-user" />`,注意图标名称一定是以 iconfont 加一个空格开头,以图标名称结尾。

View File

@ -1,7 +1,9 @@
## 登录流程路由拦截
### 登录
登录通过pinia 调用一步接口将返回的token 通过 `Session.set('token', res.access_token);` 保存下来。
登录通过 pinia 调用一步接口,将返回的 token 通过 `Session.set('token', res.access_token);` 保存下来。
```
export const Session = {
// 设置临时缓存
@ -27,11 +29,13 @@ export const Session = {
},
};
```
根据代码可以看出 如果是存储的是token 则存储到 `cookies` 中 否则存储到 `sessionStorage`
根据代码可以看出 如果是存储的是 token 则存储到 `cookies` 中 否则存储到 `sessionStorage`
### 路由拦截
通过路由的加载前拦截中
```javascript
router.beforeEach(async (to, from, next) => {
NProgress.configure({ showSpinner: false });
@ -62,45 +66,46 @@ router.beforeEach(async (to, from, next) => {
}
});
```
显而易见如果没有token 信息则跳转到登录页面并且带着当前页面的信息,以便登录成功后跳转回之前的页面
有token 则处理是不是login 页面。
在不是login 页面的时候 查询 pinia 中是否有存储的路由和菜单信息,如果没有则进行路由初始化
显而易见,如果没有 token 信息则跳转到登录页面并且带着当前页面的信息,以便登录成功后跳转回之前的页面
有 token 则处理是不是 login 页面。
在不是 login 页面的时候 查询 pinia 中是否有存储的路由和菜单信息,如果没有则进行路由初始化
```javascript
export async function initBackEndControlRoutes() {
// 界面 loading 动画开始执行
if (window.nextLoading === undefined) NextLoading.start();
// 无 token 停止执行下一步
if (!Session.get('token')) return false;
// 触发初始化用户信息 pinia
await useUserInfo().setUserInfos();
// 获取路由菜单数据
const res = await getBackEndControlRoutes();
// 无登录权限时,添加判断
// https://gitee.com/lyt-top/vue-next-admin/issues/I64HVO
if (res.data.length <= 0) return Promise.resolve(true);
// 存储接口原始路由未处理component根据需求选择使用
useRequestOldRoutes().setRequestOldRoutes(JSON.parse(JSON.stringify(res.data)));
// 处理路由component替换 dynamicRoutes/@/router/route第一个顶级 children 的路由
dynamicRoutes[0].children = [...home,...await backEndComponent(res.data), ...staticConfigRoutes]
// 添加动态路由
await setAddRoute();
// 设置路由到 pinia routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
await setFilterMenuAndCacheTagsViewRoutes();
// 界面 loading 动画开始执行
if (window.nextLoading === undefined) NextLoading.start();
// 无 token 停止执行下一步
if (!Session.get('token')) return false;
// 触发初始化用户信息 pinia
await useUserInfo().setUserInfos();
// 获取路由菜单数据
const res = await getBackEndControlRoutes();
// 无登录权限时,添加判断
// https://gitee.com/lyt-top/vue-next-admin/issues/I64HVO
if (res.data.length <= 0) return Promise.resolve(true);
// 存储接口原始路由未处理component根据需求选择使用
useRequestOldRoutes().setRequestOldRoutes(JSON.parse(JSON.stringify(res.data)));
// 处理路由component替换 dynamicRoutes/@/router/route第一个顶级 children 的路由
dynamicRoutes[0].children = [...home, ...(await backEndComponent(res.data)), ...staticConfigRoutes];
// 添加动态路由
await setAddRoute();
// 设置路由到 pinia routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
await setFilterMenuAndCacheTagsViewRoutes();
}
```
1. 整体逻辑是校验token 是否存储,
1. 整体逻辑是校验 token 是否存储,
2. 获取登录用户的信息 `await useUserInfo().setUserInfos()`
3. 获取登录用户的菜单信息 `const res = await getBackEndControlRoutes()`
4. 讲菜单信息动态添加到前端可以读取到的内容中,供左侧菜单使用 `dynamicRoutes[0].children = [...home,...await backEndComponent(res.data), ...staticConfigRoutes]` 这里我们将 `home` 放在菜单的第一个位置上
4. 根据菜单信息生成路由信息 `await setAddRoute();`
5. 保存路信息到pinia`await setFilterMenuAndCacheTagsViewRoutes();`
4. 讲菜单信息动态添加到前端可以读取到的内容中,供左侧菜单使用 `dynamicRoutes[0].children = [...home,...await backEndComponent(res.data), ...staticConfigRoutes]` 这里我们将 `home` 放在菜单的第一个位置上
5. 根据菜单信息生成路由信息 `await setAddRoute();`
6. 保存路信息到 pinia `await setFilterMenuAndCacheTagsViewRoutes();`
### 拦截请求增加 token
### 拦截请求增加token
在使用 axios 发送请求时,拦截请求信息,如果有 token 信息则带着 token 信息进行请求
在使用axios 发送请求时拦截请求信息如果有token 信息则带着token 信息进行请求
```javascript
service.interceptors.request.use((config: InternalAxiosRequestConfig) => {
// get查询参数序列化
@ -122,36 +127,38 @@ service.interceptors.request.use((config: InternalAxiosRequestConfig) => {
);
```
发送请求之后如果后端返回信息中不是200表明请求有异常针对 `424` 进行令牌过期提醒,并跳转丁路界面进行重新登录
发送请求之后如果后端返回信息中不是 200 表明请求有异常,针对 `424` 进行令牌过期提醒,并跳转丁路界面进行重新登录
```javascript
service.interceptors.response.use((res: any) => {
if (res.data.code === 1) {
throw res.data
}
return res.data;
}, error => {
const status = Number(error.response.status) || 200
const message = error.response.data.msg || errorCode[status] || errorCode['default']
if (status === 424) {
ElMessageBox.confirm('令牌状态已过期,请点击重新登录', '系统提示', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
Session.clear(); // 清除浏览器全部临时缓存
window.location.href = '/'; // 去登录页
return
})
.catch(() => {
})
}
service.interceptors.response.use(
(res: any) => {
if (res.data.code === 1) {
throw res.data;
}
return res.data;
},
(error) => {
const status = Number(error.response.status) || 200;
const message = error.response.data.msg || errorCode[status] || errorCode['default'];
if (status === 424) {
ElMessageBox.confirm('令牌状态已过期,请点击重新登录', '系统提示', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
Session.clear(); // 清除浏览器全部临时缓存
window.location.href = '/'; // 去登录页
return;
})
.catch(() => {});
}
if (status !== 200 || error.response.data.code === 1) {
ElMessage.error(message)
return Promise.reject(new Error(message))
}
return Promise.reject(error);
})
if (status !== 200 || error.response.data.code === 1) {
ElMessage.error(message);
return Promise.reject(new Error(message));
}
return Promise.reject(error);
}
);
```

View File

@ -1,34 +1,37 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="keywords" content="
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
name="keywords"
content="
微服务,pig开发平台,oauth2,微服务框架,java微服务框架,微服务开发框架,微服务治理框架,开源微服务框架,微服务器框架,微服务框架图,微服务快速开发框架,微服务java框架,微服务开源框架,微服务开源框架,微服务架构框架,微服务基础框架,微服务常见框架,主流微服务框架,微服务框架搭建,java主流微服务框架,java微服务开发框架,微服务前端框架,Spring
Boot,Spring Cloud,Spring" />
Boot,Spring Cloud,Spring"
/>
<meta name="description"
content="PIG应用微服务、容器、DevOps等云原生技术封装了大量技术开发包、技术应用组件、技术场景实现能力并支持SaaS模式应用提供了一个可支持企业各业务系统或产品快速开发实现的微服务应用数字化融合平台富含各类开箱即用的组件、微服务业务系统助力企业跨越CloudIaaS/PaaS与自身数字化的鸿沟共享业务服务的组合重用为企业服务化中台整合、数字化转型提供强力支撑也为企业提供了最佳架构实践。" />
<!--避免微信管理防盗链机制-->
<meta name="referrer" content="no-referrer" />
<link rel="icon" href="/favicon.ico" />
<title>PIGX 微服务快速开发平台</title>
</head>
<meta
name="description"
content="PIG应用微服务、容器、DevOps等云原生技术封装了大量技术开发包、技术应用组件、技术场景实现能力并支持SaaS模式应用提供了一个可支持企业各业务系统或产品快速开发实现的微服务应用数字化融合平台富含各类开箱即用的组件、微服务业务系统助力企业跨越CloudIaaS/PaaS与自身数字化的鸿沟共享业务服务的组合重用为企业服务化中台整合、数字化转型提供强力支撑也为企业提供了最佳架构实践。"
/>
<!--避免微信管理防盗链机制-->
<meta name="referrer" content="no-referrer" />
<link rel="icon" href="/favicon.ico" />
<title>PIGX 微服务快速开发平台</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript">
var _hmt = _hmt || [];
(function () {
var hm = document.createElement('script');
hm.src = 'https://hm.baidu.com/hm.js?0625618efb027ed02e88da84c121652e'
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
<body>
<div id="app"></div>
<script type="text/javascript">
var _hmt = _hmt || [];
(function () {
var hm = document.createElement('script');
hm.src = 'https://hm.baidu.com/hm.js?0625618efb027ed02e88da84c121652e';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

View File

@ -3,7 +3,7 @@
"version": "1.0.0",
"description": "PIGCLOUD微服务开发平台",
"author": "pig4cloud",
"license": "MIT",
"license": "不对外分发 pig4cloud 版权所有,请购买商业版权",
"scripts": {
"dev": "vite --force",
"build": "vite build",
@ -16,21 +16,21 @@
"@highlightjs/vue-plugin": "^2.1.0",
"@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^5.1.12",
"axios": "^1.2.1",
"axios": "^1.3.3",
"crypto-js": "^3.1.9-1",
"echarts": "^5.4.1",
"element-plus": "^2.2.26",
"element-plus": "^2.2.32",
"form-designer": "^0.0.2",
"highlight.js": "^11.7.0",
"js-cookie": "^3.0.1",
"mitt": "^3.0.0",
"nprogress": "^0.2.0",
"pinia": "^2.0.28",
"pinia": "^2.0.32",
"qrcode": "1.5.1",
"qs": "^6.11.0",
"screenfull": "^6.0.2",
"sortablejs": "^1.15.0",
"vue": "3.2.47",
"vue": "^3.2.47",
"vue-clipboard3": "^2.0.0",
"vue-i18n": "^9.2.2",
"vue-router": "^4.1.6",
@ -38,22 +38,22 @@
"xe-utils": "^3.5.4"
},
"devDependencies": {
"@types/node": "^18.11.13",
"@types/node": "^18.14.0",
"@types/nprogress": "^0.2.0",
"@types/sortablejs": "^1.15.0",
"@typescript-eslint/eslint-plugin": "^5.46.0",
"@typescript-eslint/parser": "^5.46.0",
"@typescript-eslint/eslint-plugin": "^5.53.0",
"@typescript-eslint/parser": "^5.53.0",
"@vitejs/plugin-vue": "^4.0.0",
"@vue/compiler-sfc": "^3.2.45",
"@vue/compiler-sfc": "^3.2.47",
"consola": "^2.15.3",
"eslint": "8.22.0",
"eslint-plugin-vue": "^9.8.0",
"eslint": "^8.34.0",
"eslint-plugin-vue": "^9.9.0",
"pinia-plugin-persist": "^1.0.0",
"prettier": "^2.8.4",
"sass": "^1.56.2",
"typescript": "^4.9.4",
"prettier": "2.8.4",
"sass": "^1.58.3",
"typescript": "^4.9.5",
"unplugin-auto-import": "^0.13.0",
"vite": "^4.0.0",
"vite": "^4.1.4",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-style-import": "^2.0.0",
"vite-plugin-top-level-await": "^1.2.4",

File diff suppressed because it is too large Load Diff

View File

@ -34,13 +34,11 @@ const { themeConfig } = storeToRefs(storesThemeConfig);
//
const setLockScreen = computed(() => {
//
// https://gitee.com/lyt-top/vue-next-admin/issues/I6AF8P
return themeConfig.value.isLockScreen ? themeConfig.value.lockScreenTime > 1 : themeConfig.value.lockScreenTime >= 0;
//
// https://gitee.com/lyt-top/vue-next-admin/issues/I6AF8P
return themeConfig.value.isLockScreen ? themeConfig.value.lockScreenTime > 1 : themeConfig.value.lockScreenTime >= 0;
});
//
const getGlobalComponentSize = computed(() => {
return other.globalComponentSize();

View File

@ -1,24 +1,24 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query?: Object) {
return request({
url: '/admin/audit/page',
method: 'get',
params: query
})
return request({
url: '/admin/audit/page',
method: 'get',
params: query,
});
}
export function getObj(id?: string) {
return request({
url: '/admin/audit/' + id,
method: 'get'
})
return request({
url: '/admin/audit/' + id,
method: 'get',
});
}
export function delObjs(ids?: Object) {
return request({
url: '/admin/audit',
method: 'delete',
data: ids
})
return request({
url: '/admin/audit',
method: 'delete',
data: ids,
});
}

View File

@ -1,47 +1,47 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query?: Object) {
return request({
url: '/admin/client/page',
method: 'get',
params: query
})
return request({
url: '/admin/client/page',
method: 'get',
params: query,
});
}
export function addObj(obj?: Object) {
return request({
url: '/admin/client',
method: 'post',
data: obj
})
return request({
url: '/admin/client',
method: 'post',
data: obj,
});
}
export function getObj(id?: string) {
return request({
url: '/admin/client/' + id,
method: 'get'
})
return request({
url: '/admin/client/' + id,
method: 'get',
});
}
export function delObj(ids?: object) {
return request({
url: '/admin/client',
method: 'delete',
data: ids
})
return request({
url: '/admin/client',
method: 'delete',
data: ids,
});
}
export function putObj(obj?: Object) {
return request({
url: '/admin/client',
method: 'put',
data: obj
})
return request({
url: '/admin/client',
method: 'put',
data: obj,
});
}
export function refreshCache() {
return request({
url: '/admin/client/sync',
method: 'put'
})
return request({
url: '/admin/client/sync',
method: 'put',
});
}

View File

@ -1,70 +1,67 @@
import request from "/@/utils/request";
import request from '/@/utils/request';
export const depttree = (params?: Object) => {
return request({
url: '/admin/dept/tree',
method: "get",
params
})
}
return request({
url: '/admin/dept/tree',
method: 'get',
params,
});
};
export const addObj = (obj: Object) => {
return request({
url: '/admin/dept/',
method: 'post',
data: obj
})
}
return request({
url: '/admin/dept/',
method: 'post',
data: obj,
});
};
export const getObj = (id:string) => {
return request({
url: '/admin/dept/' + id,
method: 'get'
})
}
export const getObj = (id: string) => {
return request({
url: '/admin/dept/' + id,
method: 'get',
});
};
export const delObj = (id: string) => {
return request({
url: '/admin/dept/' + id,
method: 'delete'
})
}
export const delObj = (id: string) => {
return request({
url: '/admin/dept/' + id,
method: 'delete',
});
};
export const putObj = (obj: Object) => {
return request({
url: '/admin/dept/',
method: 'put',
data: obj
})
}
return request({
url: '/admin/dept/',
method: 'put',
data: obj,
});
};
export const syncUser = () => {
return request({
url: '/admin/connect/sync/ding/user',
method: 'post'
})
}
return request({
url: '/admin/connect/sync/ding/user',
method: 'post',
});
};
export const syncDept= () => {
return request({
url: '/admin/connect/sync/ding/dept',
method: 'post'
})
}
export const syncCpUser= () => {
return request({
url: '/admin/connect/sync/cp/user',
method: 'post'
})
}
export const syncCpDept= () => {
return request({
url: '/admin/connect/sync/cp/dept',
method: 'post'
})
}
export const syncDept = () => {
return request({
url: '/admin/connect/sync/ding/dept',
method: 'post',
});
};
export const syncCpUser = () => {
return request({
url: '/admin/connect/sync/cp/user',
method: 'post',
});
};
export const syncCpDept = () => {
return request({
url: '/admin/connect/sync/cp/dept',
method: 'post',
});
};

View File

@ -1,93 +1,92 @@
import request from "/@/utils/request";
import request from '/@/utils/request';
export const getDicts = (type: String) => {
return request({
url: `/admin/dict/type/${type}`,
method: "get",
})
}
return request({
url: `/admin/dict/type/${type}`,
method: 'get',
});
};
export function fetchList(query: any) {
return request({
url: '/admin/dict/page',
method: 'get',
params: query
})
return request({
url: '/admin/dict/page',
method: 'get',
params: query,
});
}
export function fetchItemList(query: any) {
return request({
url: '/admin/dict/item/page',
method: 'get',
params: query
})
return request({
url: '/admin/dict/item/page',
method: 'get',
params: query,
});
}
export function addItemObj(obj: any) {
return request({
url: '/admin/dict/item',
method: 'post',
data: obj
})
return request({
url: '/admin/dict/item',
method: 'post',
data: obj,
});
}
export function getItemObj(id: string) {
return request({
url: '/admin/dict/item/' + id,
method: 'get'
})
return request({
url: '/admin/dict/item/' + id,
method: 'get',
});
}
export function delItemObj(id: string) {
return request({
url: '/admin/dict/item/' + id,
method: 'delete'
})
return request({
url: '/admin/dict/item/' + id,
method: 'delete',
});
}
export function putItemObj(obj: any) {
return request({
url: '/admin/dict/item',
method: 'put',
data: obj
})
return request({
url: '/admin/dict/item',
method: 'put',
data: obj,
});
}
export function addObj(obj: any) {
return request({
url: '/admin/dict/',
method: 'post',
data: obj
})
return request({
url: '/admin/dict/',
method: 'post',
data: obj,
});
}
export function getObj(id: string) {
return request({
url: '/admin/dict/' + id,
method: 'get'
})
return request({
url: '/admin/dict/' + id,
method: 'get',
});
}
export function delObj(ids: Object) {
return request({
url: '/admin/dict',
method: 'delete',
data: ids
})
return request({
url: '/admin/dict',
method: 'delete',
data: ids,
});
}
export function putObj(obj: any) {
return request({
url: '/admin/dict/',
method: 'put',
data: obj
})
return request({
url: '/admin/dict/',
method: 'put',
data: obj,
});
}
export function refreshCache() {
return request({
url: '/admin/dict/sync',
method: 'put'
})
return request({
url: '/admin/dict/sync',
method: 'put',
});
}

View File

@ -1,40 +1,40 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query?: Object) {
return request({
url: '/admin/sys-file/page',
method: 'get',
params: query
})
return request({
url: '/admin/sys-file/page',
method: 'get',
params: query,
});
}
export function addObj(obj?: Object) {
return request({
url: '/admin/sys-file',
method: 'post',
data: obj
})
return request({
url: '/admin/sys-file',
method: 'post',
data: obj,
});
}
export function getObj(id?: string) {
return request({
url: '/admin/sys-file/' + id,
method: 'get'
})
return request({
url: '/admin/sys-file/' + id,
method: 'get',
});
}
export function delObj(ids?: Object) {
return request({
url: '/admin/sys-file',
method: 'delete',
data: ids
})
return request({
url: '/admin/sys-file',
method: 'delete',
data: ids,
});
}
export function putObj(obj?: Object) {
return request({
url: '/admin/sys-file',
method: 'put',
data: obj
})
return request({
url: '/admin/sys-file',
method: 'put',
data: obj,
});
}

View File

@ -1,48 +1,47 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query?: Object) {
return request({
url: '/admin/i18n/page',
method: 'get',
params: query
})
return request({
url: '/admin/i18n/page',
method: 'get',
params: query,
});
}
export function addObj(obj?: Object) {
return request({
url: '/admin/i18n',
method: 'post',
data: obj
})
return request({
url: '/admin/i18n',
method: 'post',
data: obj,
});
}
export function getObj(id?: string) {
return request({
url: '/admin/i18n/' + id,
method: 'get'
})
return request({
url: '/admin/i18n/' + id,
method: 'get',
});
}
export function delObj(ids?: object) {
return request({
url: '/admin/i18n',
method: 'delete',
data: ids
})
return request({
url: '/admin/i18n',
method: 'delete',
data: ids,
});
}
export function putObj(obj?: Object) {
return request({
url: '/admin/i18n',
method: 'put',
data: obj
})
return request({
url: '/admin/i18n',
method: 'put',
data: obj,
});
}
export function info() {
return request({
url: '/admin/i18n/info',
method: 'get',
})
return request({
url: '/admin/i18n/info',
method: 'get',
});
}

View File

@ -1,18 +1,17 @@
import request from "/@/utils/request";
import request from '/@/utils/request';
export const pageList = (params?: Object) => {
return request({
url: '/admin/log/page',
method: "get",
params
})
}
return request({
url: '/admin/log/page',
method: 'get',
params,
});
};
export const delObj = (ids: object) => {
return request({
url: '/admin/log',
method: 'delete',
data: ids
})
}
return request({
url: '/admin/log',
method: 'delete',
data: ids,
});
};

View File

@ -1,48 +1,47 @@
import request from "/@/utils/request";
import request from '/@/utils/request';
export const pageList = (params?: Object) => {
return request({
url: '/admin/menu/tree',
method: "get",
params
})
}
return request({
url: '/admin/menu/tree',
method: 'get',
params,
});
};
export const info = (id: String) => {
return request({
url: `/admin/menu/${id}`,
method: "get",
})
}
return request({
url: `/admin/menu/${id}`,
method: 'get',
});
};
export const save = (data: Object) => {
return request({
url: '/admin/menu',
method: "post",
data: data
})
}
return request({
url: '/admin/menu',
method: 'post',
data: data,
});
};
export const update = (data: Object) => {
return request({
url: '/admin/menu',
method: "put",
data: data
})
}
return request({
url: '/admin/menu',
method: 'put',
data: data,
});
};
export const addObj = (data: Object) => {
return request({
url: '/admin/menu',
method: "post",
data: data
})
}
export const delObj = (id:string) => {
return request({
url: '/admin/menu/' + id,
method: 'delete'
})
}
return request({
url: '/admin/menu',
method: 'post',
data: data,
});
};
export const delObj = (id: string) => {
return request({
url: '/admin/menu/' + id,
method: 'delete',
});
};

View File

@ -1,47 +1,47 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query?: Object) {
return request({
url: '/admin/param/page',
method: 'get',
params: query
})
return request({
url: '/admin/param/page',
method: 'get',
params: query,
});
}
export function addObj(obj?: Object) {
return request({
url: '/admin/param',
method: 'post',
data: obj
})
return request({
url: '/admin/param',
method: 'post',
data: obj,
});
}
export function getObj(id?: string) {
return request({
url: '/admin/param/' + id,
method: 'get'
})
return request({
url: '/admin/param/' + id,
method: 'get',
});
}
export function delObj(ids?: Object) {
return request({
url: '/admin/param',
method: 'delete',
data: ids
})
return request({
url: '/admin/param',
method: 'delete',
data: ids,
});
}
export function putObj(obj?: Object) {
return request({
url: '/admin/param',
method: 'put',
data: obj
})
return request({
url: '/admin/param',
method: 'put',
data: obj,
});
}
export function refreshCache() {
return request({
url: '/admin/param/sync',
method: 'put'
})
return request({
url: '/admin/param/sync',
method: 'put',
});
}

View File

@ -1,48 +1,48 @@
import request from "/@/utils/request";
import request from '/@/utils/request';
export function fetchList(query?: Object) {
return request({
url: '/admin/post/page',
method: 'get',
params: query
})
return request({
url: '/admin/post/page',
method: 'get',
params: query,
});
}
export const list = (params?: Object) => {
return request({
url: '/admin/post/list',
method: "get",
params
})
}
return request({
url: '/admin/post/list',
method: 'get',
params,
});
};
export function addObj(obj?: Object) {
return request({
url: '/admin/post',
method: 'post',
data: obj
})
return request({
url: '/admin/post',
method: 'post',
data: obj,
});
}
export function getObj(id?: string) {
return request({
url: '/admin/post/' + id,
method: 'get'
})
return request({
url: '/admin/post/' + id,
method: 'get',
});
}
export function delObj(ids?: object) {
return request({
url: '/admin/post',
method: 'delete',
data: ids
})
return request({
url: '/admin/post',
method: 'delete',
data: ids,
});
}
export function putObj(obj?: Object) {
return request({
url: '/admin/post',
method: 'put',
data: obj
})
return request({
url: '/admin/post',
method: 'put',
data: obj,
});
}

View File

@ -1,82 +1,80 @@
import request from "/@/utils/request";
import request from '/@/utils/request';
export const list = (params?: Object) => {
return request({
url: '/admin/role/list',
method: "get",
params
})
}
return request({
url: '/admin/role/list',
method: 'get',
params,
});
};
export const pageList = (params?: Object) => {
return request({
url: '/admin/role/page',
method: "get",
params
})
}
return request({
url: '/admin/role/page',
method: 'get',
params,
});
};
export const deptRoleList = () => {
return request({
url: '/admin/role/list',
method: 'get'
})
}
return request({
url: '/admin/role/list',
method: 'get',
});
};
export const getObj = (id: string) => {
return request({
url: '/admin/role/' + id,
method: 'get'
})
}
return request({
url: '/admin/role/' + id,
method: 'get',
});
};
export const getObjByCode = (code: string) => {
return request({
url: '/admin/role/code/' + code,
method: 'get'
})
}
return request({
url: '/admin/role/code/' + code,
method: 'get',
});
};
export const addObj = (obj: Object) => {
return request({
url: '/admin/role',
method: 'post',
data: obj
})
}
return request({
url: '/admin/role',
method: 'post',
data: obj,
});
};
export const putObj = (obj: Object) => {
return request({
url: '/admin/role',
method: 'put',
data: obj
})
}
return request({
url: '/admin/role',
method: 'put',
data: obj,
});
};
export const delObj = (ids: Object) => {
return request({
url: '/admin/role/',
method: 'delete',
data: ids
})
}
return request({
url: '/admin/role/',
method: 'delete',
data: ids,
});
};
export const permissionUpd = (roleId: string, menuIds: string) => {
return request({
url: '/admin/role/menu',
method: 'put',
data: {
roleId: roleId,
menuIds: menuIds
}
})
}
return request({
url: '/admin/role/menu',
method: 'put',
data: {
roleId: roleId,
menuIds: menuIds,
},
});
};
export const fetchRoleTree = (roleId: string) => {
return request({
url: '/admin/menu/tree/' + roleId,
method: 'get'
})
}
return request({
url: '/admin/menu/tree/' + roleId,
method: 'get',
});
};

View File

@ -1,40 +1,40 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query?: Object) {
return request({
url: '/admin/social/page',
method: 'get',
params: query
})
return request({
url: '/admin/social/page',
method: 'get',
params: query,
});
}
export function addObj(obj?: Object) {
return request({
url: '/admin/social',
method: 'post',
data: obj
})
return request({
url: '/admin/social',
method: 'post',
data: obj,
});
}
export function getObj(id?: string) {
return request({
url: '/admin/social/getById/' + id,
method: 'get'
})
return request({
url: '/admin/social/getById/' + id,
method: 'get',
});
}
export function delObj(ids?: Object) {
return request({
url: '/admin/social',
method: 'delete',
data: ids
})
return request({
url: '/admin/social',
method: 'delete',
data: ids,
});
}
export function putObj(obj?: Object) {
return request({
url: '/admin/social',
method: 'put',
data: obj
})
return request({
url: '/admin/social',
method: 'put',
data: obj,
});
}

View File

@ -1,57 +1,56 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query?: Object) {
return request({
url: '/admin/tenant-menu/page',
method: 'get',
params: query
})
return request({
url: '/admin/tenant-menu/page',
method: 'get',
params: query,
});
}
export function addObj (obj: object) {
return request({
url: '/admin/tenant-menu',
method: 'post',
data: obj
})
export function addObj(obj: object) {
return request({
url: '/admin/tenant-menu',
method: 'post',
data: obj,
});
}
export function getObj(id: string) {
return request({
url: '/admin/tenant-menu/',
method: 'get',
params: {
id: id
}
})
return request({
url: '/admin/tenant-menu/',
method: 'get',
params: {
id: id,
},
});
}
export function delObj(id: string) {
return request({
url: '/admin/tenant-menu/' + id,
method: 'delete'
})
return request({
url: '/admin/tenant-menu/' + id,
method: 'delete',
});
}
export function putObj(obj:Object) {
return request({
url: '/admin/tenant-menu',
method: 'put',
data: obj
})
export function putObj(obj: Object) {
return request({
url: '/admin/tenant-menu',
method: 'put',
data: obj,
});
}
export function menuList() {
return request({
url: '/admin/tenant-menu/list',
method: 'get'
})
return request({
url: '/admin/tenant-menu/list',
method: 'get',
});
}
export function treemenu(){
return request({
url: '/admin/tenant-menu/tree/menu',
method: 'get'
})
export function treemenu() {
return request({
url: '/admin/tenant-menu/tree/menu',
method: 'get',
});
}

View File

@ -1,49 +1,49 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchPage(query?: Object) {
return request({
url: '/admin/tenant/page',
method: 'get',
params: query
})
return request({
url: '/admin/tenant/page',
method: 'get',
params: query,
});
}
export function fetchList(query?: object) {
return request({
url: '/admin/tenant/list',
method: 'get',
params: query
})
return request({
url: '/admin/tenant/list',
method: 'get',
params: query,
});
}
export function addObj(obj?: Object) {
return request({
url: '/admin/tenant',
method: 'post',
data: obj
})
return request({
url: '/admin/tenant',
method: 'post',
data: obj,
});
}
export function getObj(id?: string) {
return request({
url: '/admin/tenant',
method: 'get',
params: { id }
})
return request({
url: '/admin/tenant',
method: 'get',
params: { id },
});
}
export function delObj(ids?: Object) {
return request({
url: '/admin/tenant',
method: 'delete',
data: ids
})
return request({
url: '/admin/tenant',
method: 'delete',
data: ids,
});
}
export function putObj(obj?: Object) {
return request({
url: '/admin/tenant',
method: 'put',
data: obj
})
return request({
url: '/admin/tenant',
method: 'put',
data: obj,
});
}

View File

@ -1,17 +1,17 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query: object) {
return request({
url: '/admin/token/page',
method: 'post',
data: query
})
return request({
url: '/admin/token/page',
method: 'post',
data: query,
});
}
export function delObj(accessTokens: string[]) {
return request({
url: '/admin/token/delete',
method: 'delete',
data: accessTokens
})
return request({
url: '/admin/token/delete',
method: 'delete',
data: accessTokens,
});
}

View File

@ -1,119 +1,116 @@
import request from "/@/utils/request";
import request from '/@/utils/request';
export const pageList = (params?: Object) => {
return request({
url: '/admin/user/page',
method: "get",
params
})
}
return request({
url: '/admin/user/page',
method: 'get',
params,
});
};
export const addObj = (obj: Object) => {
return request({
url: '/admin/user',
method: 'post',
data: obj
})
}
return request({
url: '/admin/user',
method: 'post',
data: obj,
});
};
export const getObj = (id: String) => {
return request({
url: '/admin/user/' + id,
method: 'get'
})
}
return request({
url: '/admin/user/' + id,
method: 'get',
});
};
export const delObj = (ids: Object) => {
return request({
url: '/admin/user',
method: 'delete',
data: ids
})
}
return request({
url: '/admin/user',
method: 'delete',
data: ids,
});
};
export const putObj = (obj: Object) => {
return request({
url: '/admin/user',
method: 'put',
data: obj
})
}
return request({
url: '/admin/user',
method: 'put',
data: obj,
});
};
export function getDetails(obj: Object) {
return request({
url: '/admin/user/details/' + obj,
method: 'get'
})
return request({
url: '/admin/user/details/' + obj,
method: 'get',
});
}
export function getDetailsByPhone(obj: Object) {
return request({
url: '/admin/user/detailsByPhone/' + obj,
method: 'get'
})
return request({
url: '/admin/user/detailsByPhone/' + obj,
method: 'get',
});
}
// 更改个人信息
export function editInfo(obj: Object) {
return request({
url: '/admin/user/edit',
method: 'put',
data: obj
})
return request({
url: '/admin/user/edit',
method: 'put',
data: obj,
});
}
export function password(obj: Object) {
return request({
url: '/admin/user/password',
method: 'put',
data: obj
})
return request({
url: '/admin/user/password',
method: 'put',
data: obj,
});
}
/**
*
*/
export const registerUser = (userInfo: object) => {
return request({
url: '/admin/register/user',
method: 'post',
data: userInfo
})
}
return request({
url: '/admin/register/user',
method: 'post',
data: userInfo,
});
};
export function validateUsername(rule: any, value: any, callback: any, isEdit: boolean) {
const flag = new RegExp(/^([a-z\u4e00-\u9fa5\d]+?)$/).test(value)
if (!flag) {
callback(new Error('用户名支持小写英文、数字、中文'))
}
const flag = new RegExp(/^([a-z\u4e00-\u9fa5\d]+?)$/).test(value);
if (!flag) {
callback(new Error('用户名支持小写英文、数字、中文'));
}
if (isEdit) {
return callback()
}
if (isEdit) {
return callback();
}
getDetails(value).then(response => {
const result = response.data
if (result !== null) {
callback(new Error('用户名已经存在'))
} else {
callback()
}
})
getDetails(value).then((response) => {
const result = response.data;
if (result !== null) {
callback(new Error('用户名已经存在'));
} else {
callback();
}
});
}
export function validatePhone(rule: any, value: any, callback: any, isEdit: boolean) {
if (isEdit) {
return callback()
}
getDetailsByPhone(value).then(response => {
const result = response.data
if (result !== null) {
callback(new Error('手机号已经存在'))
} else {
callback()
}
})
if (isEdit) {
return callback();
}
getDetailsByPhone(value).then((response) => {
const result = response.data;
if (result !== null) {
callback(new Error('手机号已经存在'));
} else {
callback();
}
});
}

View File

@ -1,94 +1,92 @@
import request from "/@/utils/request";
import {getDetailsByPhone} from "/@/api/admin/user";
import request from '/@/utils/request';
import { getDetailsByPhone } from '/@/api/admin/user';
export const pageList = (params?: Object) => {
return request({
url: '/admin/appmenu/tree',
method: "get",
params
})
}
return request({
url: '/admin/appmenu/tree',
method: 'get',
params,
});
};
export const info = (id: String) => {
return request({
url: `/admin/appmenu/${id}`,
method: "get",
})
}
return request({
url: `/admin/appmenu/${id}`,
method: 'get',
});
};
export const save = (data: Object) => {
return request({
url: '/admin/appmenu',
method: "post",
data: data
})
}
return request({
url: '/admin/appmenu',
method: 'post',
data: data,
});
};
export const update = (data: Object) => {
return request({
url: '/admin/appmenu',
method: "put",
data: data
})
}
return request({
url: '/admin/appmenu',
method: 'put',
data: data,
});
};
export const addObj = (data: Object) => {
return request({
url: '/admin/appmenu',
method: "post",
data: data
})
}
return request({
url: '/admin/appmenu',
method: 'post',
data: data,
});
};
export function delObj(ids?: object) {
return request({
url: '/admin/appmenu',
method: 'delete',
data: ids
})
return request({
url: '/admin/appmenu',
method: 'delete',
data: ids,
});
}
export function getDetails(obj: Object) {
return request({
url: '/admin/appmenu/details/' + obj,
method: 'get'
})
return request({
url: '/admin/appmenu/details/' + obj,
method: 'get',
});
}
export function getDetailsByName(obj: Object) {
return request({
url: '/admin/appmenu/detailsByName/' + obj,
method: 'get'
})
return request({
url: '/admin/appmenu/detailsByName/' + obj,
method: 'get',
});
}
export function validatePermission(rule: any, value: any, callback: any, isEdit: boolean) {
if (isEdit) {
return callback()
}
if (isEdit) {
return callback();
}
getDetails(value).then(response => {
const result = response.data
if (result !== null) {
callback(new Error('权限标识已经存在'))
} else {
callback()
}
})
getDetails(value).then((response) => {
const result = response.data;
if (result !== null) {
callback(new Error('权限标识已经存在'));
} else {
callback();
}
});
}
export function validateByName(rule: any, value: any, callback: any, isEdit: boolean) {
if (isEdit) {
return callback()
}
getDetailsByName(value).then(response => {
const result = response.data
if (result !== null) {
callback(new Error('菜单名称已经存在'))
} else {
callback()
}
})
if (isEdit) {
return callback();
}
getDetailsByName(value).then((response) => {
const result = response.data;
if (result !== null) {
callback(new Error('菜单名称已经存在'));
} else {
callback();
}
});
}

View File

@ -1,115 +1,113 @@
import request from "/@/utils/request";
import request from '/@/utils/request';
export function fetchList(query: any) {
return request({
url: '/admin/approle/page',
method: 'get',
params: query
})
return request({
url: '/admin/approle/page',
method: 'get',
params: query,
});
}
export function list() {
return request({
url: '/admin/approle/list',
method: 'get'
})
return request({
url: '/admin/approle/list',
method: 'get',
});
}
export function addObj(obj: any) {
return request({
url: '/admin/approle',
method: 'post',
data: obj
})
return request({
url: '/admin/approle',
method: 'post',
data: obj,
});
}
export function getObj(id: string) {
return request({
url: '/admin/approle/' + id,
method: 'get'
})
return request({
url: '/admin/approle/' + id,
method: 'get',
});
}
export function delObj(ids?: object) {
return request({
url: '/admin/approle',
method: 'delete',
data: ids
})
return request({
url: '/admin/approle',
method: 'delete',
data: ids,
});
}
export function putObj(obj: any) {
return request({
url: '/admin/approle',
method: 'put',
data: obj
})
return request({
url: '/admin/approle',
method: 'put',
data: obj,
});
}
export function fetchRoleTree(roleId: string) {
return request({
url: '/admin/appmenu/tree/' + roleId,
method: 'get'
})
return request({
url: '/admin/appmenu/tree/' + roleId,
method: 'get',
});
}
export function permissionUpd(roleId: string, menuIds: string) {
return request({
url: '/admin/approle/menu',
method: 'put',
data: {
roleId: roleId,
menuIds: menuIds
}
})
return request({
url: '/admin/approle/menu',
method: 'put',
data: {
roleId: roleId,
menuIds: menuIds,
},
});
}
export function getDetails(obj: Object) {
return request({
url: '/admin/approle/details/' + obj,
method: 'get'
})
return request({
url: '/admin/approle/details/' + obj,
method: 'get',
});
}
export function getDetailsByPhone(obj: Object) {
return request({
url: '/admin/approle/detailsByCode/' + obj,
method: 'get'
})
return request({
url: '/admin/approle/detailsByCode/' + obj,
method: 'get',
});
}
export function validateApproleName(rule: any, value: any, callback: any, isEdit: boolean) {
const flag = new RegExp(/^([a-z\u4e00-\u9fa5\d]+?)$/).test(value)
if (!flag) {
callback(new Error('用户名支持小写英文、数字、中文'))
}
const flag = new RegExp(/^([a-z\u4e00-\u9fa5\d]+?)$/).test(value);
if (!flag) {
callback(new Error('用户名支持小写英文、数字、中文'));
}
if (isEdit) {
return callback()
}
if (isEdit) {
return callback();
}
getDetails(value).then(response => {
const result = response.data
if (result !== null) {
callback(new Error('用户名已经存在'))
} else {
callback()
}
})
getDetails(value).then((response) => {
const result = response.data;
if (result !== null) {
callback(new Error('用户名已经存在'));
} else {
callback();
}
});
}
export function validateAppRoleCode(rule: any, value: any, callback: any, isEdit: boolean) {
if (isEdit) {
return callback()
}
getDetailsByPhone(value).then(response => {
const result = response.data
if (result !== null) {
callback(new Error('角色标识已经存在'))
} else {
callback()
}
})
if (isEdit) {
return callback();
}
getDetailsByPhone(value).then((response) => {
const result = response.data;
if (result !== null) {
callback(new Error('角色标识已经存在'));
} else {
callback();
}
});
}

View File

@ -1,39 +1,39 @@
import request from "/@/utils/request";
import request from '/@/utils/request';
export function fetchList(query: any) {
return request({
url: '/admin/approlemenu/page',
method: 'get',
params: query
})
return request({
url: '/admin/approlemenu/page',
method: 'get',
params: query,
});
}
export function addObj(obj: any) {
return request({
url: '/admin/approlemenu',
method: 'post',
data: obj
})
return request({
url: '/admin/approlemenu',
method: 'post',
data: obj,
});
}
export function getObj(id:string) {
return request({
url: '/admin/approlemenu/' + id,
method: 'get'
})
export function getObj(id: string) {
return request({
url: '/admin/approlemenu/' + id,
method: 'get',
});
}
export function delObj(id:string) {
return request({
url: '/admin/approlemenu/' + id,
method: 'delete'
})
export function delObj(id: string) {
return request({
url: '/admin/approlemenu/' + id,
method: 'delete',
});
}
export function putObj(obj: string) {
return request({
url: '/admin/approlemenu',
method: 'put',
data: obj
})
return request({
url: '/admin/approlemenu',
method: 'put',
data: obj,
});
}

View File

@ -1,40 +1,40 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query?: Object) {
return request({
url: '/admin/appsocial/page',
method: 'get',
params: query
})
return request({
url: '/admin/appsocial/page',
method: 'get',
params: query,
});
}
export function addObj(obj?: Object) {
return request({
url: '/admin/appsocial',
method: 'post',
data: obj
})
return request({
url: '/admin/appsocial',
method: 'post',
data: obj,
});
}
export function getObj(id?: string) {
return request({
url: '/admin/appsocial/' + id,
method: 'get'
})
return request({
url: '/admin/appsocial/' + id,
method: 'get',
});
}
export function delObj(ids?: object) {
return request({
url: '/admin/appsocial/',
method: 'delete',
data:ids
})
return request({
url: '/admin/appsocial/',
method: 'delete',
data: ids,
});
}
export function putObj(obj?: Object) {
return request({
url: '/admin/appsocial',
method: 'put',
data: obj
})
return request({
url: '/admin/appsocial',
method: 'put',
data: obj,
});
}

View File

@ -1,92 +1,88 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query: any) {
return request({
url: '/admin/appuser/page',
method: 'get',
params: query
})
return request({
url: '/admin/appuser/page',
method: 'get',
params: query,
});
}
export function addObj(obj: any) {
return request({
url: '/admin/appuser',
method: 'post',
data: obj
})
return request({
url: '/admin/appuser',
method: 'post',
data: obj,
});
}
export function getObj(id: string) {
return request({
url: '/admin/appuser/' + id,
method: 'get'
})
return request({
url: '/admin/appuser/' + id,
method: 'get',
});
}
export function delObj(ids?: object) {
return request({
url: '/admin/appuser/',
method: 'delete',
data: ids
})
return request({
url: '/admin/appuser/',
method: 'delete',
data: ids,
});
}
export function putObj(obj: any) {
return request({
url: '/admin/appuser',
method: 'put',
data: obj
})
return request({
url: '/admin/appuser',
method: 'put',
data: obj,
});
}
export function getDetails(obj: Object) {
return request({
url: '/admin/appuser/details/' + obj,
method: 'get'
})
return request({
url: '/admin/appuser/details/' + obj,
method: 'get',
});
}
export function getDetailsByPhone(obj: Object) {
return request({
url: '/admin/appuser/detailsByPhone/' + obj,
method: 'get'
})
return request({
url: '/admin/appuser/detailsByPhone/' + obj,
method: 'get',
});
}
export function validateUsername(rule: any, value: any, callback: any, isEdit: boolean) {
const flag = new RegExp(/^([a-z\u4e00-\u9fa5\d]+?)$/).test(value)
if (!flag) {
callback(new Error('用户名支持小写英文、数字、中文'))
}
const flag = new RegExp(/^([a-z\u4e00-\u9fa5\d]+?)$/).test(value);
if (!flag) {
callback(new Error('用户名支持小写英文、数字、中文'));
}
if (isEdit) {
return callback()
}
if (isEdit) {
return callback();
}
getDetails(value).then(response => {
const result = response.data
if (result !== null) {
callback(new Error('用户名已经存在'))
} else {
callback()
}
})
getDetails(value).then((response) => {
const result = response.data;
if (result !== null) {
callback(new Error('用户名已经存在'));
} else {
callback();
}
});
}
export function validatePhone(rule: any, value: any, callback: any, isEdit: boolean) {
if (isEdit) {
return callback()
}
getDetailsByPhone(value).then(response => {
const result = response.data
if (result !== null) {
callback(new Error('手机号已经存在'))
} else {
callback()
}
})
if (isEdit) {
return callback();
}
getDetailsByPhone(value).then((response) => {
const result = response.data;
if (result !== null) {
callback(new Error('手机号已经存在'));
} else {
callback();
}
});
}

View File

@ -1,39 +1,39 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query: any) {
return request({
url: '/admin/appuserrole/page',
method: 'get',
params: query
})
return request({
url: '/admin/appuserrole/page',
method: 'get',
params: query,
});
}
export function addObj(obj: any) {
return request({
url: '/admin/appuserrole',
method: 'post',
data: obj
})
return request({
url: '/admin/appuserrole',
method: 'post',
data: obj,
});
}
export function getObj(id: string) {
return request({
url: '/admin/appuserrole/' + id,
method: 'get'
})
return request({
url: '/admin/appuserrole/' + id,
method: 'get',
});
}
export function delObj(id: string) {
return request({
url: '/admin/appuserrole/' + id,
method: 'delete'
})
return request({
url: '/admin/appuserrole/' + id,
method: 'delete',
});
}
export function putObj(obj: any) {
return request({
url: '/admin/appuserrole',
method: 'put',
data: obj
})
return request({
url: '/admin/appuserrole',
method: 'put',
data: obj,
});
}

View File

@ -1,17 +1,17 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query: any) {
return request({
url: '/admin/sys-job-log/page',
method: 'get',
params: query
})
return request({
url: '/admin/sys-job-log/page',
method: 'get',
params: query,
});
}
export function delObjs(ids: object) {
return request({
url: '/admin/sys-job-log',
method: 'delete',
data: ids
})
return request({
url: '/admin/sys-job-log',
method: 'delete',
data: ids,
});
}

View File

@ -1,60 +1,60 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query?: Object) {
return request({
url: '/admin/sys-job/page',
method: 'get',
params: query
})
return request({
url: '/admin/sys-job/page',
method: 'get',
params: query,
});
}
export function addObj(obj?: Object) {
return request({
url: '/admin/sys-job',
method: 'post',
data: obj
})
return request({
url: '/admin/sys-job',
method: 'post',
data: obj,
});
}
export function getObj(id?: string) {
return request({
url: '/admin/sys-job/' + id,
method: 'get'
})
return request({
url: '/admin/sys-job/' + id,
method: 'get',
});
}
export function delObj(id?: string) {
return request({
url: '/admin/sys-job/' + id,
method: 'delete'
})
return request({
url: '/admin/sys-job/' + id,
method: 'delete',
});
}
export function putObj(obj?: Object) {
return request({
url: '/admin/sys-job',
method: 'put',
data: obj
})
return request({
url: '/admin/sys-job',
method: 'put',
data: obj,
});
}
export function startJobRa(jobId:string) {
return request({
url: '/admin/sys-job/start-job/' + jobId,
method: 'post'
})
export function startJobRa(jobId: string) {
return request({
url: '/admin/sys-job/start-job/' + jobId,
method: 'post',
});
}
export function runJobRa(jobId: string) {
return request({
url: '/admin/sys-job/run-job/' + jobId,
method: 'post'
})
return request({
url: '/admin/sys-job/run-job/' + jobId,
method: 'post',
});
}
export function shutDownJobRa(jobId: string) {
return request({
url: '/admin/sys-job/shutdown-job/' + jobId,
method: 'post'
})
}
return request({
url: '/admin/sys-job/shutdown-job/' + jobId,
method: 'post',
});
}

View File

@ -1,55 +1,55 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query?: Object) {
return request({
url: '/gen/dsconf/page',
method: 'get',
params: query
})
return request({
url: '/gen/dsconf/page',
method: 'get',
params: query,
});
}
export function list(query?: Object) {
return request({
url: '/gen/dsconf/list',
method: 'get',
params: query
})
return request({
url: '/gen/dsconf/list',
method: 'get',
params: query,
});
}
export function listTable(query?: Object) {
return request({
url: '/gen/dsconf/table/list',
method: 'get',
params: query
})
return request({
url: '/gen/dsconf/table/list',
method: 'get',
params: query,
});
}
export function addObj(obj?: Object) {
return request({
url: '/gen/dsconf',
method: 'post',
data: obj
})
return request({
url: '/gen/dsconf',
method: 'post',
data: obj,
});
}
export function getObj(id?: string) {
return request({
url: '/gen/dsconf/' + id,
method: 'get'
})
return request({
url: '/gen/dsconf/' + id,
method: 'get',
});
}
export function delObj(id?: string) {
return request({
url: '/gen/dsconf/' + id,
method: 'delete'
})
return request({
url: '/gen/dsconf/' + id,
method: 'delete',
});
}
export function putObj(obj?: Object) {
return request({
url: '/gen/dsconf',
method: 'put',
data: obj
})
return request({
url: '/gen/dsconf',
method: 'put',
data: obj,
});
}

View File

@ -1,47 +1,47 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query?: Object) {
return request({
url: '/gen/fieldtype/page',
method: 'get',
params: query
})
return request({
url: '/gen/fieldtype/page',
method: 'get',
params: query,
});
}
export function list(query?: Object) {
return request({
url: '/gen/fieldtype/list',
method: 'get',
params: query
})
return request({
url: '/gen/fieldtype/list',
method: 'get',
params: query,
});
}
export function addObj(obj?: Object) {
return request({
url: '/gen/fieldtype',
method: 'post',
data: obj
})
return request({
url: '/gen/fieldtype',
method: 'post',
data: obj,
});
}
export function getObj(id?: string) {
return request({
url: '/gen/fieldtype/' + id,
method: 'get'
})
return request({
url: '/gen/fieldtype/' + id,
method: 'get',
});
}
export function delObj(id?: string) {
return request({
url: '/gen/fieldtype/' + id,
method: 'delete'
})
return request({
url: '/gen/fieldtype/' + id,
method: 'delete',
});
}
export function putObj(obj?: Object) {
return request({
url: '/gen/fieldtype',
method: 'put',
data: obj
})
return request({
url: '/gen/fieldtype',
method: 'put',
data: obj,
});
}

View File

@ -1,47 +1,47 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query?: Object) {
return request({
url: '/gen/group/page',
method: 'get',
params: query
})
return request({
url: '/gen/group/page',
method: 'get',
params: query,
});
}
export function addObj(obj?: Object) {
return request({
url: '/gen/group',
method: 'post',
data: obj
})
return request({
url: '/gen/group',
method: 'post',
data: obj,
});
}
export function getObj(id?: string) {
return request({
url: '/gen/group/' + id,
method: 'get'
})
return request({
url: '/gen/group/' + id,
method: 'get',
});
}
export function delObjs(ids?: Object) {
return request({
url: '/gen/group',
method: 'delete',
data: ids
})
return request({
url: '/gen/group',
method: 'delete',
data: ids,
});
}
export function putObj(obj?: Object) {
return request({
url: '/gen/group',
method: 'put',
data: obj
})
return request({
url: '/gen/group',
method: 'put',
data: obj,
});
}
export function list() {
return request({
url: '/gen/group/list',
method: 'get',
})
return request({
url: '/gen/group/list',
method: 'get',
});
}

View File

@ -1,101 +1,98 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query?: Object) {
return request({
url: '/gen/table/page',
method: 'get',
params: query
})
return request({
url: '/gen/table/page',
method: 'get',
params: query,
});
}
export function addObj(obj?: Object) {
return request({
url: '/gen/table',
method: 'post',
data: obj
})
return request({
url: '/gen/table',
method: 'post',
data: obj,
});
}
export function getObj(id?: string) {
return request({
url: '/gen/table/' + id,
method: 'get'
})
return request({
url: '/gen/table/' + id,
method: 'get',
});
}
export function delObj(id?: string) {
return request({
url: '/gen/table/' + id,
method: 'delete'
})
return request({
url: '/gen/table/' + id,
method: 'delete',
});
}
export function putObj(obj?: Object) {
return request({
url: '/gen/table',
method: 'put',
data: obj
})
return request({
url: '/gen/table',
method: 'put',
data: obj,
});
}
export const useSyncTableApi = (dsName: string, tableName: string) => {
return request.get('/gen/table/sync/' + dsName + "/" + tableName)
}
return request.get('/gen/table/sync/' + dsName + '/' + tableName);
};
export const useTableApi = (dsName: string, tableName: string) => {
return request.get('/gen/table/' + dsName + "/" + tableName)
}
return request.get('/gen/table/' + dsName + '/' + tableName);
};
export const useTableFieldSubmitApi = (dsName: string, tableName: string, fieldList: any) => {
return request.put('/gen/table/field/' + dsName + '/' + tableName, fieldList)
}
return request.put('/gen/table/field/' + dsName + '/' + tableName, fieldList);
};
export const useGeneratorCodeApi = (tableIds: any) => {
return request({
url: '/gen/generator/code',
method: 'get',
params: { tableIds: tableIds }
})
}
return request({
url: '/gen/generator/code',
method: 'get',
params: { tableIds: tableIds },
});
};
export const useGeneratorVFormApi = (dsName: any, tableName: any) => {
return request({
url: '/gen/generator/vform',
method: 'get',
params: { dsName: dsName, tableName: tableName }
})
}
return request({
url: '/gen/generator/vform',
method: 'get',
params: { dsName: dsName, tableName: tableName },
});
};
export const useGeneratorVFormSfcApi = (dsName: any, tableName: any) => {
return request({
url: '/gen/generator/vform/sfc',
method: 'get',
params: { dsName: dsName, tableName: tableName }
})
}
return request({
url: '/gen/generator/vform/sfc',
method: 'get',
params: { dsName: dsName, tableName: tableName },
});
};
export const useGeneratorPreviewApi = (tableId: any) => {
return request({
url: '/gen/generator/preview',
method: 'get',
params: { tableId: tableId }
})
}
return request({
url: '/gen/generator/preview',
method: 'get',
params: { tableId: tableId },
});
};
export function fetchDictList() {
return request({
url: '/admin/dict/list',
method: 'get'
})
return request({
url: '/admin/dict/list',
method: 'get',
});
}
export function useFormConfSaveApi(obj?: Object) {
return request({
url: '/gen/form',
method: 'post',
data: obj
})
return request({
url: '/gen/form',
method: 'post',
data: obj,
});
}

View File

@ -1,47 +1,47 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query?: Object) {
return request({
url: '/gen/template/page',
method: 'get',
params: query
})
return request({
url: '/gen/template/page',
method: 'get',
params: query,
});
}
export function list() {
return request({
url: '/gen/template/list',
method: 'get'
})
return request({
url: '/gen/template/list',
method: 'get',
});
}
export function addObj(obj?: Object) {
return request({
url: '/gen/template',
method: 'post',
data: obj
})
return request({
url: '/gen/template',
method: 'post',
data: obj,
});
}
export function getObj(id?: string) {
return request({
url: '/gen/template/' + id,
method: 'get'
})
return request({
url: '/gen/template/' + id,
method: 'get',
});
}
export function delObjs(ids?: Object) {
return request({
url: '/gen/template',
method: 'delete',
data: ids
})
return request({
url: '/gen/template',
method: 'delete',
data: ids,
});
}
export function putObj(obj?: Object) {
return request({
url: '/gen/template',
method: 'put',
data: obj
})
return request({
url: '/gen/template',
method: 'put',
data: obj,
});
}

View File

@ -1,134 +1,137 @@
import request from '/@/utils/request';
import { Session } from "/@/utils/storage";
import { validateNull } from "/@/utils/validate"
import { useUserInfo } from "/@/stores/userInfo";
import { Session } from '/@/utils/storage';
import { validateNull } from '/@/utils/validate';
import { useUserInfo } from '/@/stores/userInfo';
/**
*
* @param data
*/
export const login = (data: any) => {
const basicAuth = 'Basic ' + window.btoa(import.meta.env.VITE_OAUTH2_PASSWORD_CLIENT)
Session.set('basicAuth', basicAuth)
return request({
url: '/admin/oauth2/token',
method: 'post',
params: data,
headers: {
'isToken': false,
'TENANT-ID': '1',
'Authorization': basicAuth
}
})
}
const basicAuth = 'Basic ' + window.btoa(import.meta.env.VITE_OAUTH2_PASSWORD_CLIENT);
Session.set('basicAuth', basicAuth);
return request({
url: '/admin/oauth2/token',
method: 'post',
params: data,
headers: {
isToken: false,
'TENANT-ID': '1',
Authorization: basicAuth,
},
});
};
export const loginByMobile = (mobile: any, code: any) => {
const grant_type = 'mobile'
const scope = 'server'
const basicAuth = 'Basic ' + window.btoa(import.meta.env.VITE_OAUTH2_MOBILE_CLIENT)
Session.set('basicAuth', basicAuth)
const grant_type = 'mobile';
const scope = 'server';
const basicAuth = 'Basic ' + window.btoa(import.meta.env.VITE_OAUTH2_MOBILE_CLIENT);
Session.set('basicAuth', basicAuth);
return request({
url: '/admin/oauth2/token',
headers: {
'isToken': false,
'TENANT-ID': '1',
'Authorization': basicAuth
},
method: 'post',
params: { mobile: 'SMS@' + mobile, code: code, grant_type, scope }
})
}
return request({
url: '/admin/oauth2/token',
headers: {
isToken: false,
'TENANT-ID': '1',
Authorization: basicAuth,
},
method: 'post',
params: { mobile: 'SMS@' + mobile, code: code, grant_type, scope },
});
};
export const loginBySocial = (state: string, code: string) => {
const grant_type = 'mobile'
const scope = 'server'
const basicAuth = 'Basic ' + window.btoa(import.meta.env.VITE_OAUTH2_SOCIAL_CLIENT)
Session.set('basicAuth', basicAuth)
const grant_type = 'mobile';
const scope = 'server';
const basicAuth = 'Basic ' + window.btoa(import.meta.env.VITE_OAUTH2_SOCIAL_CLIENT);
Session.set('basicAuth', basicAuth);
return request({
url: '/admin/oauth2/token',
headers: {
'isToken': false,
'TENANT-ID': '1',
'Authorization': basicAuth
},
method: 'post',
params: { mobile: state + '@' + code, code: code, grant_type, scope }
})
}
return request({
url: '/admin/oauth2/token',
headers: {
isToken: false,
'TENANT-ID': '1',
Authorization: basicAuth,
},
method: 'post',
params: { mobile: state + '@' + code, code: code, grant_type, scope },
});
};
export const sendMobileCode = (mobile: any) => {
return request({
url: "/admin/mobile/" + mobile,
method: "get",
})
}
return request({
url: '/admin/mobile/' + mobile,
method: 'get',
});
};
export const refreshTokenApi = (refresh_token: string) => {
const grant_type = 'refresh_token'
const scope = 'server'
// 获取当前选中的 basic 认证信息
const basicAuth = Session.get('basicAuth')
const grant_type = 'refresh_token';
const scope = 'server';
// 获取当前选中的 basic 认证信息
const basicAuth = Session.get('basicAuth');
return request({
url: '/admin/oauth2/token',
headers: {
'isToken': false,
'TENANT-ID': '1',
'Authorization': basicAuth
},
method: 'post',
params: { refresh_token, grant_type, scope }
})
}
return request({
url: '/admin/oauth2/token',
headers: {
isToken: false,
'TENANT-ID': '1',
Authorization: basicAuth,
},
method: 'post',
params: { refresh_token, grant_type, scope },
});
};
/**
*
* @param refreshLock
*/
export const checkToken = (refreshTime: number, refreshLock: boolean) => {
const basicAuth = Session.get('basicAuth')
request({
url: '/admin/token/check_token',
headers: {
'isToken': false,
Authorization: basicAuth
},
method: 'get',
params: { token: Session.get("token") }
})
.then((response) => {
if (validateNull(response) || response.code === 1) {
clearInterval(refreshTime)
return
}
const expire = Date.parse(response.data.expiresAt)
if (expire) {
const expiredPeriod = expire - new Date().getTime()
//小于半小时自动续约
if (expiredPeriod <= 10 * 30 * 1000) {
if (!refreshLock) {
refreshLock = true
useUserInfo().refreshToken().catch(() => {
clearInterval(refreshTime)
})
refreshLock = false
}
}
}
}).catch(() => {
// 发生异常关闭定时器
clearInterval(refreshTime)
})
}
const basicAuth = Session.get('basicAuth');
request({
url: '/admin/token/check_token',
headers: {
isToken: false,
Authorization: basicAuth,
},
method: 'get',
params: { token: Session.get('token') },
})
.then((response) => {
if (validateNull(response) || response.code === 1) {
clearInterval(refreshTime);
return;
}
const expire = Date.parse(response.data.expiresAt);
if (expire) {
const expiredPeriod = expire - new Date().getTime();
//小于半小时自动续约
if (expiredPeriod <= 10 * 30 * 1000) {
if (!refreshLock) {
refreshLock = true;
useUserInfo()
.refreshToken()
.catch(() => {
clearInterval(refreshTime);
});
refreshLock = false;
}
}
}
})
.catch(() => {
// 发生异常关闭定时器
clearInterval(refreshTime);
});
};
/**
*
*/
export const getUserInfo = () => {
return request({
url: '/admin/user/info',
method: 'get'
})
}
return request({
url: '/admin/user/info',
method: 'get',
});
};

View File

@ -12,8 +12,6 @@ export function useMenuApi() {
method: 'get',
params,
});
}
},
};
}

View File

@ -18,46 +18,46 @@
import request from '/@/utils/request';
export function fetchList(query) {
return request({
url: '/admin/wx-account-fans/page',
method: 'get',
params: query
})
return request({
url: '/admin/wx-account-fans/page',
method: 'get',
params: query,
});
}
export function addObj(obj) {
return request({
url: '/admin/wx-account-fans',
method: 'post',
data: obj
})
return request({
url: '/admin/wx-account-fans',
method: 'post',
data: obj,
});
}
export function sync(appId) {
return request({
url: '/admin/wx-account-fans/sync/' + appId,
method: 'post'
})
return request({
url: '/admin/wx-account-fans/sync/' + appId,
method: 'post',
});
}
export function getObj(id) {
return request({
url: '/admin/wx-account-fans/' + id,
method: 'get'
})
return request({
url: '/admin/wx-account-fans/' + id,
method: 'get',
});
}
export function delObjs(id) {
return request({
url: '/admin/wx-account-fans/' + id,
method: 'delete'
})
return request({
url: '/admin/wx-account-fans/' + id,
method: 'delete',
});
}
export function putObj(obj) {
return request({
url: '/admin/wx-account-fans',
method: 'put',
data: obj
})
return request({
url: '/admin/wx-account-fans',
method: 'put',
data: obj,
});
}

View File

@ -18,49 +18,48 @@
import request from '/@/utils/request';
export function getPage(query) {
return request({
url: '/admin/wx-account-tag/page',
method: 'get',
params: query
})
return request({
url: '/admin/wx-account-tag/page',
method: 'get',
params: query,
});
}
export function addObj(obj) {
return request({
url: '/admin/wx-account-tag',
method: 'post',
data: obj
})
return request({
url: '/admin/wx-account-tag',
method: 'post',
data: obj,
});
}
export function delObjs(obj) {
return request({
url: '/admin/wx-account-tag',
method: 'delete',
data: obj
})
return request({
url: '/admin/wx-account-tag',
method: 'delete',
data: obj,
});
}
export function putObj(obj) {
return request({
url: '/admin/wx-account-tag',
method: 'put',
data: obj
})
return request({
url: '/admin/wx-account-tag',
method: 'put',
data: obj,
});
}
export function sync(appId) {
return request({
url: '/admin/wx-account-tag/sync/' + appId,
method: 'post'
})
return request({
url: '/admin/wx-account-tag/sync/' + appId,
method: 'post',
});
}
export function list(appId) {
return request({
url: '/admin/wx-account-tag/list/',
method: 'get',
params: { 'wxAccountAppid': appId }
})
return request({
url: '/admin/wx-account-tag/list/',
method: 'get',
params: { wxAccountAppid: appId },
});
}

View File

@ -18,68 +18,68 @@
import request from '/@/utils/request';
export function fetchList(query) {
return request({
url: '/admin/wx-account/page',
method: 'get',
params: query
})
return request({
url: '/admin/wx-account/page',
method: 'get',
params: query,
});
}
export function addObj(obj) {
return request({
url: '/admin/wx-account',
method: 'post',
data: obj
})
return request({
url: '/admin/wx-account',
method: 'post',
data: obj,
});
}
export function getObj(id) {
return request({
url: '/admin/wx-account/' + id,
method: 'get'
})
return request({
url: '/admin/wx-account/' + id,
method: 'get',
});
}
export function generateQr(appid) {
return request({
url: '/admin/wx-account/qr/' + appid,
method: 'post'
})
return request({
url: '/admin/wx-account/qr/' + appid,
method: 'post',
});
}
export function clearQuota(appid) {
return request({
url: '/admin/wx-account/clear-quota/' + appid,
method: 'post'
})
return request({
url: '/admin/wx-account/clear-quota/' + appid,
method: 'post',
});
}
export function delObjs(id) {
return request({
url: '/admin/wx-account/' + id,
method: 'delete'
})
return request({
url: '/admin/wx-account/' + id,
method: 'delete',
});
}
export function putObj(obj) {
return request({
url: '/admin/wx-account',
method: 'put',
data: obj
})
return request({
url: '/admin/wx-account',
method: 'put',
data: obj,
});
}
export function fetchAccountList() {
return request({
url: '/admin/wx-account/list',
method: 'get'
})
return request({
url: '/admin/wx-account/list',
method: 'get',
});
}
export function fetchStatistics(q) {
return request({
url: '/admin/wx-account/statistics',
method: 'get',
params: q
})
return request({
url: '/admin/wx-account/statistics',
method: 'get',
params: q,
});
}

View File

@ -1,39 +1,39 @@
import request from '/@/utils/request';
export function getPage(query) {
return request({
url: '/admin/wx-auto-reply/page',
method: 'get',
params: query
})
return request({
url: '/admin/wx-auto-reply/page',
method: 'get',
params: query,
});
}
export function addObj(obj) {
return request({
url: '/admin/wx-auto-reply',
method: 'post',
data: obj
})
return request({
url: '/admin/wx-auto-reply',
method: 'post',
data: obj,
});
}
export function getObj(id) {
return request({
url: '/admin/wx-auto-reply/' + id,
method: 'get'
})
return request({
url: '/admin/wx-auto-reply/' + id,
method: 'get',
});
}
export function delObj(id) {
return request({
url: '/admin/wx-auto-reply/' + id,
method: 'delete'
})
return request({
url: '/admin/wx-auto-reply/' + id,
method: 'delete',
});
}
export function putObj(obj) {
return request({
url: '/admin/wx-auto-reply',
method: 'put',
data: obj
})
return request({
url: '/admin/wx-auto-reply',
method: 'put',
data: obj,
});
}

View File

@ -18,62 +18,62 @@
import request from '/@/utils/request';
export function fetchList(query) {
return request({
url: '/admin/wx-fans-msg/page',
method: 'get',
params: query
})
return request({
url: '/admin/wx-fans-msg/page',
method: 'get',
params: query,
});
}
export function addObj(obj) {
return request({
url: '/admin/wx-fans-msg',
method: 'post',
data: obj
})
return request({
url: '/admin/wx-fans-msg',
method: 'post',
data: obj,
});
}
export function getObj(id) {
return request({
url: '/admin/wxfansmsg/' + id,
method: 'get'
})
return request({
url: '/admin/wxfansmsg/' + id,
method: 'get',
});
}
export function delObjs(id) {
return request({
url: '/admin/wxfansmsg/' + id,
method: 'delete'
})
return request({
url: '/admin/wxfansmsg/' + id,
method: 'delete',
});
}
export function putObj(obj) {
return request({
url: '/admin/wxfansmsg',
method: 'put',
data: obj
})
return request({
url: '/admin/wxfansmsg',
method: 'put',
data: obj,
});
}
export function fetchResList(query) {
return request({
url: '/admin/wx-fans-msg/page',
method: 'get',
params: query
})
return request({
url: '/admin/wx-fans-msg/page',
method: 'get',
params: query,
});
}
export function addResObj(obj) {
return request({
url: '/admin/wx-fans-msg',
method: 'post',
data: obj
})
return request({
url: '/admin/wx-fans-msg',
method: 'post',
data: obj,
});
}
export function delResObj(id) {
return request({
url: '/admin/wx-fans-msg/' + id,
method: 'delete'
})
return request({
url: '/admin/wx-fans-msg/' + id,
method: 'delete',
});
}

View File

@ -1,74 +1,74 @@
import request from '/@/utils/request';
export function getPage(query) {
return request({
url: '/admin/wx-material/page',
method: 'get',
params: query
})
return request({
url: '/admin/wx-material/page',
method: 'get',
params: query,
});
}
export function addObj(obj) {
return request({
url: '/admin/wx-material/materialNews',
method: 'post',
data: obj
})
return request({
url: '/admin/wx-material/materialNews',
method: 'post',
data: obj,
});
}
export function materialNewsUpdate(obj) {
return request({
url: '/admin/wx-material/materialNews',
method: 'put',
data: obj
})
return request({
url: '/admin/wx-material/materialNews',
method: 'put',
data: obj,
});
}
export function getObj(id) {
return request({
url: '/admin/wx-material/' + id,
method: 'get'
})
return request({
url: '/admin/wx-material/' + id,
method: 'get',
});
}
export function delObj(query) {
return request({
url: '/admin/wx-material',
method: 'delete',
params: query
})
return request({
url: '/admin/wx-material',
method: 'delete',
params: query,
});
}
export function putObj(obj) {
return request({
url: '/admin/wx-material',
method: 'put',
data: obj
})
return request({
url: '/admin/wx-material',
method: 'put',
data: obj,
});
}
export function getMaterialOther(query) {
return request({
url: '/admin/wx-material/materialOther',
method: 'get',
params: query,
responseType: 'blob'
})
return request({
url: '/admin/wx-material/materialOther',
method: 'get',
params: query,
responseType: 'blob',
});
}
export function getMaterialVideo(query) {
return request({
url: '/admin/wx-material/materialVideo',
method: 'get',
params: query
})
return request({
url: '/admin/wx-material/materialVideo',
method: 'get',
params: query,
});
}
export function getTempMaterialOther(query) {
return request({
url: '/admin/wx-material/tempMaterialOther',
method: 'get',
params: query,
responseType: 'blob'
})
return request({
url: '/admin/wx-material/tempMaterialOther',
method: 'get',
params: query,
responseType: 'blob',
});
}

View File

@ -18,23 +18,23 @@
import request from '/@/utils/request';
export function getObj(id) {
return request({
url: '/admin/wx-menu/' + id,
method: 'get'
})
return request({
url: '/admin/wx-menu/' + id,
method: 'get',
});
}
export function saveObj(appId, data) {
return request({
url: '/admin/wx-menu/' + appId,
method: 'post',
data: data
})
return request({
url: '/admin/wx-menu/' + appId,
method: 'post',
data: data,
});
}
export function publishObj(id) {
return request({
url: '/admin/wx-menu/' + id,
method: 'put'
})
return request({
url: '/admin/wx-menu/' + id,
method: 'put',
});
}

View File

@ -1,46 +1,46 @@
import request from '/@/utils/request';
export function fetchList(query) {
return request({
url: '/admin/leave-bill/page',
method: 'get',
params: query
})
return request({
url: '/admin/leave-bill/page',
method: 'get',
params: query,
});
}
export function addObj(obj) {
return request({
url: '/admin/leave-bill',
method: 'post',
data: obj
})
return request({
url: '/admin/leave-bill',
method: 'post',
data: obj,
});
}
export function getObj(id) {
return request({
url: '/admin/leave-bill/' + id,
method: 'get'
})
return request({
url: '/admin/leave-bill/' + id,
method: 'get',
});
}
export function submit(id) {
return request({
url: '/admin/leave-bill/submit/' + id,
method: 'get'
})
return request({
url: '/admin/leave-bill/submit/' + id,
method: 'get',
});
}
export function delObj(id) {
return request({
url: '/admin/leave-bill/' + id,
method: 'delete'
})
return request({
url: '/admin/leave-bill/' + id,
method: 'delete',
});
}
export function putObj(obj) {
return request({
url: '/admin/leave-bill/',
method: 'put',
data: obj
})
return request({
url: '/admin/leave-bill/',
method: 'put',
data: obj,
});
}

View File

@ -1,46 +1,47 @@
import request from '/@/utils/request';
export function fetchList(query) {
return request({
url: '/admin/model',
method: 'get',
params: query
})
return request({
url: '/admin/model',
method: 'get',
params: query,
});
}
export function delObj(id) {
return request({
url: '/admin/model/' + id,
method: 'delete'
})
export function delObj(ids: Object) {
return request({
url: '/admin/model',
method: 'delete',
data: ids,
});
}
export function deploy(id) {
return request({
url: '/admin/model/deploy/' + id,
method: 'post'
})
return request({
url: '/admin/model/deploy/' + id,
method: 'post',
});
}
export function addObj(obj) {
return request({
url: '/admin/model/insert',
method: 'post',
data: obj
})
export function addObj(obj?: Object) {
return request({
url: '/admin/model/insert',
method: 'post',
data: obj,
});
}
export function getObj(id) {
return request({
url: '/admin/log/' + id,
method: 'get'
})
return request({
url: '/admin/log/' + id,
method: 'get',
});
}
export function putObj(obj) {
return request({
url: '/admin/log/',
method: 'put',
data: obj
})
return request({
url: '/admin/log/',
method: 'put',
data: obj,
});
}

View File

@ -1,23 +1,23 @@
import request from '/@/utils/request';
export function fetchList(query) {
return request({
url: '/admin/process',
method: 'get',
params: query
})
return request({
url: '/admin/process',
method: 'get',
params: query,
});
}
export function delObj(id) {
return request({
url: '/admin/process/' + id,
method: 'delete'
})
return request({
url: '/admin/process/' + id,
method: 'delete',
});
}
export function status(id, type) {
return request({
url: '/admin/process/status/' + id + '/' + type,
method: 'put'
})
return request({
url: '/admin/process/status/' + id + '/' + type,
method: 'put',
});
}

View File

@ -1,31 +1,31 @@
import request from '/@/utils/request';
export function fetchList(query) {
return request({
url: '/admin/task/todo',
method: 'get',
params: query
})
return request({
url: '/admin/task/todo',
method: 'get',
params: query,
});
}
export function fetchDetail(id) {
return request({
url: '/admin/task/' + id,
method: 'get'
})
return request({
url: '/admin/task/' + id,
method: 'get',
});
}
export function fetchComment(id) {
return request({
url: '/admin/task/comment/' + id,
method: 'get'
})
return request({
url: '/admin/task/comment/' + id,
method: 'get',
});
}
export function doTask(obj) {
return request({
url: '/admin/task',
method: 'post',
data: obj
})
return request({
url: '/admin/task',
method: 'post',
data: obj,
});
}

View File

@ -1,9 +1,9 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function useBuyApi(amount?: any) {
return request({
url: '/admin/goods/merge/buy',
method: 'get',
params: { amount: amount }
})
return request({
url: '/admin/goods/merge/buy',
method: 'get',
params: { amount: amount },
});
}

View File

@ -1,40 +1,40 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query?: Object) {
return request({
url: '/admin/channel/page',
method: 'get',
params: query
})
return request({
url: '/admin/channel/page',
method: 'get',
params: query,
});
}
export function addObj(obj?: Object) {
return request({
url: '/admin/channel',
method: 'post',
data: obj
})
return request({
url: '/admin/channel',
method: 'post',
data: obj,
});
}
export function getObj(id?: string) {
return request({
url: '/admin/channel/' + id,
method: 'get'
})
return request({
url: '/admin/channel/' + id,
method: 'get',
});
}
export function delObjs(ids?: Object) {
return request({
url: '/admin/channel',
method: 'delete',
data: ids
})
return request({
url: '/admin/channel',
method: 'delete',
data: ids,
});
}
export function putObj(obj?: Object) {
return request({
url: '/admin/channel',
method: 'put',
data: obj
})
}
return request({
url: '/admin/channel',
method: 'put',
data: obj,
});
}

View File

@ -1,40 +1,40 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query?: Object) {
return request({
url: '/admin/goods/page',
method: 'get',
params: query
})
return request({
url: '/admin/goods/page',
method: 'get',
params: query,
});
}
export function addObj(obj?: Object) {
return request({
url: '/admin/goods',
method: 'post',
data: obj
})
return request({
url: '/admin/goods',
method: 'post',
data: obj,
});
}
export function getObj(id?: string) {
return request({
url: '/admin/goods/' + id,
method: 'get'
})
return request({
url: '/admin/goods/' + id,
method: 'get',
});
}
export function delObjs(ids?: Object) {
return request({
url: '/admin/goods',
method: 'delete',
data: ids
})
return request({
url: '/admin/goods',
method: 'delete',
data: ids,
});
}
export function putObj(obj?: Object) {
return request({
url: '/admin/goods',
method: 'put',
data: obj
})
}
return request({
url: '/admin/goods',
method: 'put',
data: obj,
});
}

View File

@ -1,40 +1,40 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query?: Object) {
return request({
url: '/admin/notify/page',
method: 'get',
params: query
})
return request({
url: '/admin/notify/page',
method: 'get',
params: query,
});
}
export function addObj(obj?: Object) {
return request({
url: '/admin/notify',
method: 'post',
data: obj
})
return request({
url: '/admin/notify',
method: 'post',
data: obj,
});
}
export function getObj(id?: string) {
return request({
url: '/admin/notify/' + id,
method: 'get'
})
return request({
url: '/admin/notify/' + id,
method: 'get',
});
}
export function delObjs(ids?: Object) {
return request({
url: '/admin/notify',
method: 'delete',
data: ids
})
return request({
url: '/admin/notify',
method: 'delete',
data: ids,
});
}
export function putObj(obj?: Object) {
return request({
url: '/admin/notify',
method: 'put',
data: obj
})
return request({
url: '/admin/notify',
method: 'put',
data: obj,
});
}

View File

@ -1,40 +1,40 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query?: Object) {
return request({
url: '/admin/refund/page',
method: 'get',
params: query
})
return request({
url: '/admin/refund/page',
method: 'get',
params: query,
});
}
export function useRefundApi(obj?: Object) {
return request({
url: '/admin/refund',
method: 'post',
data: obj
})
return request({
url: '/admin/refund',
method: 'post',
data: obj,
});
}
export function getObj(id?: string) {
return request({
url: '/pay/refund/' + id,
method: 'get'
})
return request({
url: '/pay/refund/' + id,
method: 'get',
});
}
export function delObjs(ids?: Object) {
return request({
url: '/admin/refund',
method: 'delete',
data: ids
})
return request({
url: '/admin/refund',
method: 'delete',
data: ids,
});
}
export function putObj(obj?: Object) {
return request({
url: '/admin/refund',
method: 'put',
data: obj
})
}
return request({
url: '/admin/refund',
method: 'put',
data: obj,
});
}

View File

@ -1,40 +1,40 @@
import request from "/@/utils/request"
import request from '/@/utils/request';
export function fetchList(query?: Object) {
return request({
url: '/admin/trade/page',
method: 'get',
params: query
})
return request({
url: '/admin/trade/page',
method: 'get',
params: query,
});
}
export function addObj(obj?: Object) {
return request({
url: '/admin/trade',
method: 'post',
data: obj
})
return request({
url: '/admin/trade',
method: 'post',
data: obj,
});
}
export function getObj(id?: string) {
return request({
url: '/admin/trade/' + id,
method: 'get'
})
return request({
url: '/admin/trade/' + id,
method: 'get',
});
}
export function delObjs(ids?: Object) {
return request({
url: '/admin/trade',
method: 'delete',
data: ids
})
return request({
url: '/admin/trade',
method: 'delete',
data: ids,
});
}
export function putObj(obj?: Object) {
return request({
url: '/admin/trade',
method: 'put',
data: obj
})
}
return request({
url: '/admin/trade',
method: 'put',
data: obj,
});
}

View File

@ -1,12 +1,12 @@
// base color
$blue: #324157;
$light-blue: #3A71A8;
$red: #C03639;
$pink: #E65D6E;
$green: #30B08F;
$tiffany: #4AB7BD;
$yellow: #FEC171;
$panGreen: #30B08F;
$light-blue: #3a71a8;
$red: #c03639;
$pink: #e65d6e;
$green: #30b08f;
$tiffany: #4ab7bd;
$yellow: #fec171;
$panGreen: #30b08f;
// 默认菜单主题风格
$base-menu-color: #bfcbd9;
@ -36,10 +36,10 @@ $base-sub-menu-background:#000c17;
$base-sub-menu-hover:#001528;
*/
$--color-primary: #409EFF;
$--color-success: #67C23A;
$--color-warning: #E6A23C;
$--color-danger: #F56C6C;
$--color-primary: #409eff;
$--color-success: #67c23a;
$--color-warning: #e6a23c;
$--color-danger: #f56c6c;
$--color-info: #909399;
$base-sidebar-width: 200px;
@ -47,19 +47,19 @@ $base-sidebar-width: 200px;
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
:export {
menuColor: $base-menu-color;
menuLightColor: $base-menu-light-color;
menuColorActive: $base-menu-color-active;
menuBackground: $base-menu-background;
menuLightBackground: $base-menu-light-background;
subMenuBackground: $base-sub-menu-background;
subMenuHover: $base-sub-menu-hover;
sideBarWidth: $base-sidebar-width;
logoTitleColor: $base-logo-title-color;
logoLightTitleColor: $base-logo-light-title-color;
primaryColor: $--color-primary;
successColor: $--color-success;
dangerColor: $--color-danger;
infoColor: $--color-info;
warningColor: $--color-warning;
menuColor: $base-menu-color;
menuLightColor: $base-menu-light-color;
menuColorActive: $base-menu-color-active;
menuBackground: $base-menu-background;
menuLightBackground: $base-menu-light-background;
subMenuBackground: $base-sub-menu-background;
subMenuHover: $base-sub-menu-hover;
sideBarWidth: $base-sidebar-width;
logoTitleColor: $base-logo-title-color;
logoLightTitleColor: $base-logo-light-title-color;
primaryColor: $--color-primary;
successColor: $--color-success;
dangerColor: $--color-danger;
infoColor: $--color-info;
warningColor: $--color-warning;
}

View File

@ -1,19 +1,19 @@
<template>
<div></div>
<div></div>
</template>
<script setup lang="ts" name="check-token">
import { checkToken } from '/@/api/login';
const refreshLock = ref(false)
const refreshTime = ref()
const refreshLock = ref(false);
const refreshTime = ref();
onMounted(() => {
refreshToken()
})
refreshToken();
});
const refreshToken = () => {
refreshTime.value = setInterval(() => {
checkToken(refreshTime.value, refreshLock.value)
}, 30000)
}
refreshTime.value = setInterval(() => {
checkToken(refreshTime.value, refreshLock.value);
}, 30000);
};
</script>

View File

@ -1,176 +1,174 @@
<template>
<el-form size="small">
<el-form-item>
<el-radio v-model='radioValue' :label="1">
允许的通配符[, - * ? / L W]
</el-radio>
</el-form-item>
<el-form size="small">
<el-form-item>
<el-radio v-model="radioValue" :label="1"> 允许的通配符[, - * ? / L W] </el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="2">
不指定
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="2"> 不指定 </el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="3">
周期从
<el-input-number v-model='cycle01' :min="1" :max="30" /> -
<el-input-number v-model='cycle02' :min="cycle01 + 1" :max="31" />
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="3">
周期从
<el-input-number v-model="cycle01" :min="1" :max="30" /> - <el-input-number v-model="cycle02" :min="cycle01 + 1" :max="31" />
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="4">
<el-input-number v-model='average01' :min="1" :max="30" /> 号开始
<el-input-number v-model='average02' :min="1" :max="31 - average01" /> 日执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="4">
<el-input-number v-model="average01" :min="1" :max="30" /> 号开始
<el-input-number v-model="average02" :min="1" :max="31 - average01" /> 日执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="5">
每月
<el-input-number v-model='workday' :min="1" :max="31" /> 号最近的那个工作日
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="5">
每月
<el-input-number v-model="workday" :min="1" :max="31" /> 号最近的那个工作日
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="6">
本月最后一天
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="6"> 本月最后一天 </el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="7">
指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="10">
<el-option v-for="item in 31" :key="item" :label="item" :value="item" />
</el-select>
</el-radio>
</el-form-item>
</el-form>
<el-form-item>
<el-radio v-model="radioValue" :label="7">
指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="10">
<el-option v-for="item in 31" :key="item" :label="item" :value="item" />
</el-select>
</el-radio>
</el-form-item>
</el-form>
</template>
<script setup>
const emit = defineEmits(['update'])
const emit = defineEmits(['update']);
const props = defineProps({
cron: {
type: Object,
default: () => {
return {
second: "*",
min: "*",
hour: "*",
day: "*",
month: "*",
week: "?",
year: "",
}
}
},
check: {
type: Function,
default: () => {
}
}
})
const radioValue = ref(1)
const cycle01 = ref(1)
const cycle02 = ref(2)
const average01 = ref(1)
const average02 = ref(1)
const workday = ref(1)
const checkboxList = ref([])
const checkCopy = ref([1])
cron: {
type: Object,
default: () => {
return {
second: '*',
min: '*',
hour: '*',
day: '*',
month: '*',
week: '?',
year: '',
};
},
},
check: {
type: Function,
default: () => {},
},
});
const radioValue = ref(1);
const cycle01 = ref(1);
const cycle02 = ref(2);
const average01 = ref(1);
const average02 = ref(1);
const workday = ref(1);
const checkboxList = ref([]);
const checkCopy = ref([1]);
const cycleTotal = computed(() => {
cycle01.value = props.check(cycle01.value, 1, 30)
cycle02.value = props.check(cycle02.value, cycle01.value + 1, 31)
return cycle01.value + '-' + cycle02.value
})
cycle01.value = props.check(cycle01.value, 1, 30);
cycle02.value = props.check(cycle02.value, cycle01.value + 1, 31);
return cycle01.value + '-' + cycle02.value;
});
const averageTotal = computed(() => {
average01.value = props.check(average01.value, 1, 30)
average02.value = props.check(average02.value, 1, 31 - average01.value)
return average01.value + '/' + average02.value
})
average01.value = props.check(average01.value, 1, 30);
average02.value = props.check(average02.value, 1, 31 - average01.value);
return average01.value + '/' + average02.value;
});
const workdayTotal = computed(() => {
workday.value = props.check(workday.value, 1, 31)
return workday.value + 'W'
})
workday.value = props.check(workday.value, 1, 31);
return workday.value + 'W';
});
const checkboxString = computed(() => {
return checkboxList.value.join(',')
})
watch(() => props.cron.day, value => changeRadioValue(value))
watch([radioValue, cycleTotal, averageTotal, workdayTotal, checkboxString], () => onRadioChange())
return checkboxList.value.join(',');
});
watch(
() => props.cron.day,
(value) => changeRadioValue(value)
);
watch([radioValue, cycleTotal, averageTotal, workdayTotal, checkboxString], () => onRadioChange());
function changeRadioValue(value) {
if (value === "*") {
radioValue.value = 1
} else if (value === "?") {
radioValue.value = 2
} else if (value.indexOf("-") > -1) {
const indexArr = value.split('-')
cycle01.value = Number(indexArr[0])
cycle02.value = Number(indexArr[1])
radioValue.value = 3
} else if (value.indexOf("/") > -1) {
const indexArr = value.split('/')
average01.value = Number(indexArr[0])
average02.value = Number(indexArr[1])
radioValue.value = 4
} else if (value.indexOf("W") > -1) {
const indexArr = value.split("W")
workday.value = Number(indexArr[0])
radioValue.value = 5
} else if (value === "L") {
radioValue.value = 6
} else {
checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))]
radioValue.value = 7
}
if (value === '*') {
radioValue.value = 1;
} else if (value === '?') {
radioValue.value = 2;
} else if (value.indexOf('-') > -1) {
const indexArr = value.split('-');
cycle01.value = Number(indexArr[0]);
cycle02.value = Number(indexArr[1]);
radioValue.value = 3;
} else if (value.indexOf('/') > -1) {
const indexArr = value.split('/');
average01.value = Number(indexArr[0]);
average02.value = Number(indexArr[1]);
radioValue.value = 4;
} else if (value.indexOf('W') > -1) {
const indexArr = value.split('W');
workday.value = Number(indexArr[0]);
radioValue.value = 5;
} else if (value === 'L') {
radioValue.value = 6;
} else {
checkboxList.value = [...new Set(value.split(',').map((item) => Number(item)))];
radioValue.value = 7;
}
}
//
function onRadioChange() {
if (radioValue.value === 2 && props.cron.week === '?') {
emit('update', 'week', '*', 'day')
}
if (radioValue.value !== 2 && props.cron.week !== '?') {
emit('update', 'week', '?', 'day')
}
switch (radioValue.value) {
case 1:
emit('update', 'day', '*', 'day')
break
case 2:
emit('update', 'day', '?', 'day')
break
case 3:
emit('update', 'day', cycleTotal.value, 'day')
break
case 4:
emit('update', 'day', averageTotal.value, 'day')
break
case 5:
emit('update', 'day', workdayTotal.value, 'day')
break
case 6:
emit('update', 'day', 'L', 'day')
break
case 7:
if (checkboxList.value.length === 0) {
checkboxList.value.push(checkCopy.value[0])
} else {
checkCopy.value = checkboxList.value
}
emit('update', 'day', checkboxString.value, 'day')
break
}
if (radioValue.value === 2 && props.cron.week === '?') {
emit('update', 'week', '*', 'day');
}
if (radioValue.value !== 2 && props.cron.week !== '?') {
emit('update', 'week', '?', 'day');
}
switch (radioValue.value) {
case 1:
emit('update', 'day', '*', 'day');
break;
case 2:
emit('update', 'day', '?', 'day');
break;
case 3:
emit('update', 'day', cycleTotal.value, 'day');
break;
case 4:
emit('update', 'day', averageTotal.value, 'day');
break;
case 5:
emit('update', 'day', workdayTotal.value, 'day');
break;
case 6:
emit('update', 'day', 'L', 'day');
break;
case 7:
if (checkboxList.value.length === 0) {
checkboxList.value.push(checkCopy.value[0]);
} else {
checkCopy.value = checkboxList.value;
}
emit('update', 'day', checkboxString.value, 'day');
break;
}
}
</script>
<style lang="scss" scoped>
.el-input-number--small, .el-select, .el-select--small {
margin: 0 0.2rem;
.el-input-number--small,
.el-select,
.el-select--small {
margin: 0 0.2rem;
}
.el-select, .el-select--small {
width: 18.8rem;
.el-select,
.el-select--small {
width: 18.8rem;
}
</style>

View File

@ -1,129 +1,131 @@
<template>
<el-form size="small">
<el-form-item>
<el-radio v-model='radioValue' :label="1">
小时允许的通配符[, - * /]
</el-radio>
</el-form-item>
<el-form size="small">
<el-form-item>
<el-radio v-model="radioValue" :label="1"> 小时允许的通配符[, - * /] </el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="2">
周期从
<el-input-number v-model='cycle01' :min="0" :max="22" /> -
<el-input-number v-model='cycle02' :min="cycle01 + 1" :max="23" />
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="2">
周期从
<el-input-number v-model="cycle01" :min="0" :max="22" /> - <el-input-number v-model="cycle02" :min="cycle01 + 1" :max="23" />
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="3">
<el-input-number v-model='average01' :min="0" :max="22" /> 时开始
<el-input-number v-model='average02' :min="1" :max="23 - average01" /> 小时执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="3">
<el-input-number v-model="average01" :min="0" :max="22" /> 时开始
<el-input-number v-model="average02" :min="1" :max="23 - average01" /> 小时执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="4">
指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="10">
<el-option v-for="item in 24" :key="item" :label="item - 1" :value="item - 1" />
</el-select>
</el-radio>
</el-form-item>
</el-form>
<el-form-item>
<el-radio v-model="radioValue" :label="4">
指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="10">
<el-option v-for="item in 24" :key="item" :label="item - 1" :value="item - 1" />
</el-select>
</el-radio>
</el-form-item>
</el-form>
</template>
<script setup>
const emit = defineEmits(['update'])
const emit = defineEmits(['update']);
const props = defineProps({
cron: {
type: Object,
default: () => {
return {
second: "*",
min: "*",
hour: "*",
day: "*",
month: "*",
week: "?",
year: "",
}
}
},
check: {
type: Function,
default: () => {
}
}
})
const radioValue = ref(1)
const cycle01 = ref(0)
const cycle02 = ref(1)
const average01 = ref(0)
const average02 = ref(1)
const checkboxList = ref([])
const checkCopy = ref([0])
cron: {
type: Object,
default: () => {
return {
second: '*',
min: '*',
hour: '*',
day: '*',
month: '*',
week: '?',
year: '',
};
},
},
check: {
type: Function,
default: () => {},
},
});
const radioValue = ref(1);
const cycle01 = ref(0);
const cycle02 = ref(1);
const average01 = ref(0);
const average02 = ref(1);
const checkboxList = ref([]);
const checkCopy = ref([0]);
const cycleTotal = computed(() => {
cycle01.value = props.check(cycle01.value, 0, 22)
cycle02.value = props.check(cycle02.value, cycle01.value + 1, 23)
return cycle01.value + '-' + cycle02.value
})
cycle01.value = props.check(cycle01.value, 0, 22);
cycle02.value = props.check(cycle02.value, cycle01.value + 1, 23);
return cycle01.value + '-' + cycle02.value;
});
const averageTotal = computed(() => {
average01.value = props.check(average01.value, 0, 22)
average02.value = props.check(average02.value, 1, 23 - average01.value)
return average01.value + '/' + average02.value
})
average01.value = props.check(average01.value, 0, 22);
average02.value = props.check(average02.value, 1, 23 - average01.value);
return average01.value + '/' + average02.value;
});
const checkboxString = computed(() => {
return checkboxList.value.join(',')
})
watch(() => props.cron.hour, value => changeRadioValue(value))
watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange())
return checkboxList.value.join(',');
});
watch(
() => props.cron.hour,
(value) => changeRadioValue(value)
);
watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange());
function changeRadioValue(value) {
if (value === '*') {
radioValue.value = 1
} else if (value.indexOf('-') > -1) {
const indexArr = value.split('-')
cycle01.value = Number(indexArr[0])
cycle02.value = Number(indexArr[1])
radioValue.value = 2
} else if (value.indexOf('/') > -1) {
const indexArr = value.split('/')
average01.value = Number(indexArr[0])
average02.value = Number(indexArr[1])
radioValue.value = 3
} else {
checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))]
radioValue.value = 4
}
if (value === '*') {
radioValue.value = 1;
} else if (value.indexOf('-') > -1) {
const indexArr = value.split('-');
cycle01.value = Number(indexArr[0]);
cycle02.value = Number(indexArr[1]);
radioValue.value = 2;
} else if (value.indexOf('/') > -1) {
const indexArr = value.split('/');
average01.value = Number(indexArr[0]);
average02.value = Number(indexArr[1]);
radioValue.value = 3;
} else {
checkboxList.value = [...new Set(value.split(',').map((item) => Number(item)))];
radioValue.value = 4;
}
}
function onRadioChange() {
switch (radioValue.value) {
case 1:
emit('update', 'hour', '*', 'hour')
break
case 2:
emit('update', 'hour', cycleTotal.value, 'hour')
break
case 3:
emit('update', 'hour', averageTotal.value, 'hour')
break
case 4:
if (checkboxList.value.length === 0) {
checkboxList.value.push(checkCopy.value[0])
} else {
checkCopy.value = checkboxList.value
}
emit('update', 'hour', checkboxString.value, 'hour')
break
}
switch (radioValue.value) {
case 1:
emit('update', 'hour', '*', 'hour');
break;
case 2:
emit('update', 'hour', cycleTotal.value, 'hour');
break;
case 3:
emit('update', 'hour', averageTotal.value, 'hour');
break;
case 4:
if (checkboxList.value.length === 0) {
checkboxList.value.push(checkCopy.value[0]);
} else {
checkCopy.value = checkboxList.value;
}
emit('update', 'hour', checkboxString.value, 'hour');
break;
}
}
</script>
<style lang="scss" scoped>
.el-input-number--small, .el-select, .el-select--small {
margin: 0 0.2rem;
.el-input-number--small,
.el-select,
.el-select--small {
margin: 0 0.2rem;
}
.el-select, .el-select--small {
width: 18.8rem;
.el-select,
.el-select--small {
width: 18.8rem;
}
</style>

View File

@ -1,295 +1,282 @@
<template>
<div>
<el-tabs type="border-card">
<el-tab-pane label="秒" v-if="shouldHide('second')">
<CrontabSecond @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj"
ref="cronsecond" />
</el-tab-pane>
<div>
<el-tabs type="border-card">
<el-tab-pane label="秒" v-if="shouldHide('second')">
<CrontabSecond @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronsecond" />
</el-tab-pane>
<el-tab-pane label="分钟" v-if="shouldHide('min')">
<CrontabMin @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronmin" />
</el-tab-pane>
<el-tab-pane label="分钟" v-if="shouldHide('min')">
<CrontabMin @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronmin" />
</el-tab-pane>
<el-tab-pane label="小时" v-if="shouldHide('hour')">
<CrontabHour @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronhour" />
</el-tab-pane>
<el-tab-pane label="小时" v-if="shouldHide('hour')">
<CrontabHour @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronhour" />
</el-tab-pane>
<el-tab-pane label="日" v-if="shouldHide('day')">
<CrontabDay @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronday" />
</el-tab-pane>
<el-tab-pane label="日" v-if="shouldHide('day')">
<CrontabDay @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronday" />
</el-tab-pane>
<el-tab-pane label="月" v-if="shouldHide('month')">
<CrontabMonth @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj"
ref="cronmonth" />
</el-tab-pane>
<el-tab-pane label="月" v-if="shouldHide('month')">
<CrontabMonth @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronmonth" />
</el-tab-pane>
<el-tab-pane label="周" v-if="shouldHide('week')">
<CrontabWeek @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronweek" />
</el-tab-pane>
<el-tab-pane label="周" v-if="shouldHide('week')">
<CrontabWeek @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronweek" />
</el-tab-pane>
<el-tab-pane label="年" v-if="shouldHide('year')">
<CrontabYear @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronyear" />
</el-tab-pane>
</el-tabs>
<el-tab-pane label="年" v-if="shouldHide('year')">
<CrontabYear @update="updateCrontabValue" :check="checkNumber" :cron="crontabValueObj" ref="cronyear" />
</el-tab-pane>
</el-tabs>
<div class="popup-main">
<div class="popup-result">
<p class="title">时间表达式</p>
<table>
<thead>
<th v-for="item of tabTitles" :key="item">{{ item }}</th>
<th>Cron 表达式</th>
</thead>
<tbody>
<td>
<span v-if="crontabValueObj.second.length < 10">{{ crontabValueObj.second }}</span>
<el-tooltip v-else :content="crontabValueObj.second" placement="top"><span>{{
crontabValueObj.second
}}</span></el-tooltip>
</td>
<td>
<span v-if="crontabValueObj.min.length < 10">{{ crontabValueObj.min }}</span>
<el-tooltip v-else :content="crontabValueObj.min" placement="top"><span>{{
crontabValueObj.min
}}</span></el-tooltip>
</td>
<td>
<span v-if="crontabValueObj.hour.length < 10">{{ crontabValueObj.hour }}</span>
<el-tooltip v-else :content="crontabValueObj.hour" placement="top"><span>{{
crontabValueObj.hour
}}</span></el-tooltip>
</td>
<td>
<span v-if="crontabValueObj.day.length < 10">{{ crontabValueObj.day }}</span>
<el-tooltip v-else :content="crontabValueObj.day" placement="top"><span>{{
crontabValueObj.day
}}</span></el-tooltip>
</td>
<td>
<span v-if="crontabValueObj.month.length < 10">{{ crontabValueObj.month }}</span>
<el-tooltip v-else :content="crontabValueObj.month" placement="top"><span>{{
crontabValueObj.month
}}</span></el-tooltip>
</td>
<td>
<span v-if="crontabValueObj.week.length < 10">{{ crontabValueObj.week }}</span>
<el-tooltip v-else :content="crontabValueObj.week" placement="top"><span>{{
crontabValueObj.week
}}</span></el-tooltip>
</td>
<td>
<span v-if="crontabValueObj.year.length < 10">{{ crontabValueObj.year }}</span>
<el-tooltip v-else :content="crontabValueObj.year" placement="top"><span>{{
crontabValueObj.year
}}</span></el-tooltip>
</td>
<td class="result">
<span v-if="crontabValueString.length < 90">{{ crontabValueString }}</span>
<el-tooltip v-else :content="crontabValueString" placement="top"><span>{{
crontabValueString
}}</span></el-tooltip>
</td>
</tbody>
</table>
</div>
<CrontabResult :ex="crontabValueString"></CrontabResult>
<div class="popup-main">
<div class="popup-result">
<p class="title">时间表达式</p>
<table>
<thead>
<th v-for="item of tabTitles" :key="item">{{ item }}</th>
<th>Cron 表达式</th>
</thead>
<tbody>
<td>
<span v-if="crontabValueObj.second.length < 10">{{ crontabValueObj.second }}</span>
<el-tooltip v-else :content="crontabValueObj.second" placement="top"
><span>{{ crontabValueObj.second }}</span></el-tooltip
>
</td>
<td>
<span v-if="crontabValueObj.min.length < 10">{{ crontabValueObj.min }}</span>
<el-tooltip v-else :content="crontabValueObj.min" placement="top"
><span>{{ crontabValueObj.min }}</span></el-tooltip
>
</td>
<td>
<span v-if="crontabValueObj.hour.length < 10">{{ crontabValueObj.hour }}</span>
<el-tooltip v-else :content="crontabValueObj.hour" placement="top"
><span>{{ crontabValueObj.hour }}</span></el-tooltip
>
</td>
<td>
<span v-if="crontabValueObj.day.length < 10">{{ crontabValueObj.day }}</span>
<el-tooltip v-else :content="crontabValueObj.day" placement="top"
><span>{{ crontabValueObj.day }}</span></el-tooltip
>
</td>
<td>
<span v-if="crontabValueObj.month.length < 10">{{ crontabValueObj.month }}</span>
<el-tooltip v-else :content="crontabValueObj.month" placement="top"
><span>{{ crontabValueObj.month }}</span></el-tooltip
>
</td>
<td>
<span v-if="crontabValueObj.week.length < 10">{{ crontabValueObj.week }}</span>
<el-tooltip v-else :content="crontabValueObj.week" placement="top"
><span>{{ crontabValueObj.week }}</span></el-tooltip
>
</td>
<td>
<span v-if="crontabValueObj.year.length < 10">{{ crontabValueObj.year }}</span>
<el-tooltip v-else :content="crontabValueObj.year" placement="top"
><span>{{ crontabValueObj.year }}</span></el-tooltip
>
</td>
<td class="result">
<span v-if="crontabValueString.length < 90">{{ crontabValueString }}</span>
<el-tooltip v-else :content="crontabValueString" placement="top"
><span>{{ crontabValueString }}</span></el-tooltip
>
</td>
</tbody>
</table>
</div>
<CrontabResult :ex="crontabValueString"></CrontabResult>
<div class="pop_btn">
<el-button type="primary" @click="submitFill">确定</el-button>
<el-button type="warning" @click="clearCron">重置</el-button>
<el-button @click="hidePopup">取消</el-button>
</div>
</div>
</div>
<div class="pop_btn">
<el-button type="primary" @click="submitFill">确定</el-button>
<el-button type="warning" @click="clearCron">重置</el-button>
<el-button @click="hidePopup">取消</el-button>
</div>
</div>
</div>
</template>
<script setup>
import CrontabSecond from "./second.vue"
import CrontabMin from "./min.vue"
import CrontabHour from "./hour.vue"
import CrontabDay from "./day.vue"
import CrontabMonth from "./month.vue"
import CrontabWeek from "./week.vue"
import CrontabYear from "./year.vue"
import CrontabResult from "./result.vue"
const emit = defineEmits(['hide', 'fill'])
import CrontabSecond from './second.vue';
import CrontabMin from './min.vue';
import CrontabHour from './hour.vue';
import CrontabDay from './day.vue';
import CrontabMonth from './month.vue';
import CrontabWeek from './week.vue';
import CrontabYear from './year.vue';
import CrontabResult from './result.vue';
const emit = defineEmits(['hide', 'fill']);
const props = defineProps({
hideComponent: {
type: Array,
default: () => [],
},
expression: {
type: String,
default: ""
}
})
const tabTitles = ref(["秒", "分钟", "小时", "日", "月", "周", "年"])
const hideComponent = ref([])
const expression = ref('')
hideComponent: {
type: Array,
default: () => [],
},
expression: {
type: String,
default: '',
},
});
const tabTitles = ref(['秒', '分钟', '小时', '日', '月', '周', '年']);
const hideComponent = ref([]);
const expression = ref('');
const crontabValueObj = ref({
second: "*",
min: "*",
hour: "*",
day: "*",
month: "*",
week: "?",
year: "",
})
second: '*',
min: '*',
hour: '*',
day: '*',
month: '*',
week: '?',
year: '',
});
const crontabValueString = computed(() => {
const obj = crontabValueObj.value
return obj.second
+ " "
+ obj.min
+ " "
+ obj.hour
+ " "
+ obj.day
+ " "
+ obj.month
+ " "
+ obj.week
+ (obj.year === "" ? "" : " " + obj.year)
})
watch(expression, () => resolveExp())
const obj = crontabValueObj.value;
return obj.second + ' ' + obj.min + ' ' + obj.hour + ' ' + obj.day + ' ' + obj.month + ' ' + obj.week + (obj.year === '' ? '' : ' ' + obj.year);
});
watch(expression, () => resolveExp());
function shouldHide(key) {
return !(hideComponent.value && hideComponent.value.includes(key))
return !(hideComponent.value && hideComponent.value.includes(key));
}
function resolveExp() {
//
if (expression.value) {
const arr = expression.value.split(/\s+/)
if (arr.length >= 6) {
//6
let obj = {
second: arr[0],
min: arr[1],
hour: arr[2],
day: arr[3],
month: arr[4],
week: arr[5],
year: arr[6] ? arr[6] : ""
}
crontabValueObj.value = {
...obj,
}
}
} else {
//
clearCron()
}
//
if (expression.value) {
const arr = expression.value.split(/\s+/);
if (arr.length >= 6) {
//6
let obj = {
second: arr[0],
min: arr[1],
hour: arr[2],
day: arr[3],
month: arr[4],
week: arr[5],
year: arr[6] ? arr[6] : '',
};
crontabValueObj.value = {
...obj,
};
}
} else {
//
clearCron();
}
}
//
function updateCrontabValue(name, value) {
crontabValueObj.value[name] = value
crontabValueObj.value[name] = value;
}
// -props
function checkNumber(value, minLimit, maxLimit) {
//
value = Math.floor(value)
if (value < minLimit) {
value = minLimit
} else if (value > maxLimit) {
value = maxLimit
}
return value
//
value = Math.floor(value);
if (value < minLimit) {
value = minLimit;
} else if (value > maxLimit) {
value = maxLimit;
}
return value;
}
//
function hidePopup() {
emit("hide")
emit('hide');
}
//
function submitFill() {
emit("fill", crontabValueString.value)
hidePopup()
emit('fill', crontabValueString.value);
hidePopup();
}
function clearCron() {
//
crontabValueObj.value = {
second: "*",
min: "*",
hour: "*",
day: "*",
month: "*",
week: "?",
year: "",
}
//
crontabValueObj.value = {
second: '*',
min: '*',
hour: '*',
day: '*',
month: '*',
week: '?',
year: '',
};
}
onMounted(() => {
expression.value = props.expression
hideComponent.value = props.hideComponent
})
expression.value = props.expression;
hideComponent.value = props.hideComponent;
});
</script>
<style lang="scss" scoped>
.pop_btn {
text-align: center;
margin-top: 20px;
text-align: center;
margin-top: 20px;
}
.popup-main {
position: relative;
margin: 10px auto;
background: #fff;
border-radius: 5px;
font-size: 12px;
overflow: hidden;
position: relative;
margin: 10px auto;
background: #fff;
border-radius: 5px;
font-size: 12px;
overflow: hidden;
}
.popup-title {
overflow: hidden;
line-height: 34px;
padding-top: 6px;
background: #f2f2f2;
overflow: hidden;
line-height: 34px;
padding-top: 6px;
background: #f2f2f2;
}
.popup-result {
box-sizing: border-box;
line-height: 24px;
margin: 25px auto;
padding: 15px 10px 10px;
border: 1px solid #ccc;
position: relative;
box-sizing: border-box;
line-height: 24px;
margin: 25px auto;
padding: 15px 10px 10px;
border: 1px solid #ccc;
position: relative;
}
.popup-result .title {
position: absolute;
top: -28px;
left: 50%;
width: 140px;
font-size: 14px;
margin-left: -70px;
text-align: center;
line-height: 30px;
background: #fff;
position: absolute;
top: -28px;
left: 50%;
width: 140px;
font-size: 14px;
margin-left: -70px;
text-align: center;
line-height: 30px;
background: #fff;
}
.popup-result table {
text-align: center;
width: 100%;
margin: 0 auto;
text-align: center;
width: 100%;
margin: 0 auto;
}
.popup-result table td:not(.result) {
width: 3.5rem;
min-width: 3.5rem;
max-width: 3.5rem;
width: 3.5rem;
min-width: 3.5rem;
max-width: 3.5rem;
}
.popup-result table span {
display: block;
width: 100%;
font-family: arial;
line-height: 30px;
height: 30px;
white-space: nowrap;
overflow: hidden;
border: 1px solid #e8e8e8;
display: block;
width: 100%;
font-family: arial;
line-height: 30px;
height: 30px;
white-space: nowrap;
overflow: hidden;
border: 1px solid #e8e8e8;
}
.popup-result-scroll {
font-size: 12px;
line-height: 24px;
height: 10em;
overflow-y: auto;
font-size: 12px;
line-height: 24px;
height: 10em;
overflow-y: auto;
}
</style>
</style>

View File

@ -1,128 +1,130 @@
<template>
<el-form size="small">
<el-form-item>
<el-radio v-model='radioValue' :label="1">
分钟允许的通配符[, - * /]
</el-radio>
</el-form-item>
<el-form size="small">
<el-form-item>
<el-radio v-model="radioValue" :label="1"> 分钟允许的通配符[, - * /] </el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="2">
周期从
<el-input-number v-model='cycle01' :min="0" :max="58" /> -
<el-input-number v-model='cycle02' :min="cycle01 + 1" :max="59" /> 分钟
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="2">
周期从
<el-input-number v-model="cycle01" :min="0" :max="58" /> - <el-input-number v-model="cycle02" :min="cycle01 + 1" :max="59" /> 分钟
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="3">
<el-input-number v-model='average01' :min="0" :max="58" /> 分钟开始
<el-input-number v-model='average02' :min="1" :max="59 - average01" /> 分钟执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="3">
<el-input-number v-model="average01" :min="0" :max="58" /> 分钟开始
<el-input-number v-model="average02" :min="1" :max="59 - average01" /> 分钟执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="4">
指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="10">
<el-option v-for="item in 60" :key="item" :label="item - 1" :value="item - 1" />
</el-select>
</el-radio>
</el-form-item>
</el-form>
<el-form-item>
<el-radio v-model="radioValue" :label="4">
指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="10">
<el-option v-for="item in 60" :key="item" :label="item - 1" :value="item - 1" />
</el-select>
</el-radio>
</el-form-item>
</el-form>
</template>
<script setup>
const emit = defineEmits(['update'])
const emit = defineEmits(['update']);
const props = defineProps({
cron: {
type: Object,
default: () => {
return {
second: "*",
min: "*",
hour: "*",
day: "*",
month: "*",
week: "?",
year: "",
}
}
},
check: {
type: Function,
default: () => {
}
}
})
const radioValue = ref(1)
const cycle01 = ref(0)
const cycle02 = ref(1)
const average01 = ref(0)
const average02 = ref(1)
const checkboxList = ref([])
const checkCopy = ref([0])
cron: {
type: Object,
default: () => {
return {
second: '*',
min: '*',
hour: '*',
day: '*',
month: '*',
week: '?',
year: '',
};
},
},
check: {
type: Function,
default: () => {},
},
});
const radioValue = ref(1);
const cycle01 = ref(0);
const cycle02 = ref(1);
const average01 = ref(0);
const average02 = ref(1);
const checkboxList = ref([]);
const checkCopy = ref([0]);
const cycleTotal = computed(() => {
cycle01.value = props.check(cycle01.value, 0, 58)
cycle02.value = props.check(cycle02.value, cycle01.value + 1, 59)
return cycle01.value + '-' + cycle02.value
})
cycle01.value = props.check(cycle01.value, 0, 58);
cycle02.value = props.check(cycle02.value, cycle01.value + 1, 59);
return cycle01.value + '-' + cycle02.value;
});
const averageTotal = computed(() => {
average01.value = props.check(average01.value, 0, 58)
average02.value = props.check(average02.value, 1, 59 - average01.value)
return average01.value + '/' + average02.value
})
average01.value = props.check(average01.value, 0, 58);
average02.value = props.check(average02.value, 1, 59 - average01.value);
return average01.value + '/' + average02.value;
});
const checkboxString = computed(() => {
return checkboxList.value.join(',')
})
watch(() => props.cron.min, value => changeRadioValue(value))
watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange())
return checkboxList.value.join(',');
});
watch(
() => props.cron.min,
(value) => changeRadioValue(value)
);
watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange());
function changeRadioValue(value) {
if (value === '*') {
radioValue.value = 1
} else if (value.indexOf('-') > -1) {
const indexArr = value.split('-')
cycle01.value = Number(indexArr[0])
cycle02.value = Number(indexArr[1])
radioValue.value = 2
} else if (value.indexOf('/') > -1) {
const indexArr = value.split('/')
average01.value = Number(indexArr[0])
average02.value = Number(indexArr[1])
radioValue.value = 3
} else {
checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))]
radioValue.value = 4
}
if (value === '*') {
radioValue.value = 1;
} else if (value.indexOf('-') > -1) {
const indexArr = value.split('-');
cycle01.value = Number(indexArr[0]);
cycle02.value = Number(indexArr[1]);
radioValue.value = 2;
} else if (value.indexOf('/') > -1) {
const indexArr = value.split('/');
average01.value = Number(indexArr[0]);
average02.value = Number(indexArr[1]);
radioValue.value = 3;
} else {
checkboxList.value = [...new Set(value.split(',').map((item) => Number(item)))];
radioValue.value = 4;
}
}
function onRadioChange() {
switch (radioValue.value) {
case 1:
emit('update', 'min', '*', 'min')
break
case 2:
emit('update', 'min', cycleTotal.value, 'min')
break
case 3:
emit('update', 'min', averageTotal.value, 'min')
break
case 4:
if (checkboxList.value.length === 0) {
checkboxList.value.push(checkCopy.value[0])
} else {
checkCopy.value = checkboxList.value
}
emit('update', 'min', checkboxString.value, 'min')
break
}
switch (radioValue.value) {
case 1:
emit('update', 'min', '*', 'min');
break;
case 2:
emit('update', 'min', cycleTotal.value, 'min');
break;
case 3:
emit('update', 'min', averageTotal.value, 'min');
break;
case 4:
if (checkboxList.value.length === 0) {
checkboxList.value.push(checkCopy.value[0]);
} else {
checkCopy.value = checkboxList.value;
}
emit('update', 'min', checkboxString.value, 'min');
break;
}
}
</script>
<style lang="scss" scoped>
.el-input-number--small, .el-select, .el-select--small {
margin: 0 0.2rem;
.el-input-number--small,
.el-select,
.el-select--small {
margin: 0 0.2rem;
}
.el-select, .el-select--small {
width: 19.8rem;
.el-select,
.el-select--small {
width: 19.8rem;
}
</style>

View File

@ -1,143 +1,145 @@
<template>
<el-form size='small'>
<el-form-item>
<el-radio v-model='radioValue' :label="1">
允许的通配符[, - * /]
</el-radio>
</el-form-item>
<el-form size="small">
<el-form-item>
<el-radio v-model="radioValue" :label="1"> 允许的通配符[, - * /] </el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="2">
周期从
<el-input-number v-model='cycle01' :min="1" :max="11" /> -
<el-input-number v-model='cycle02' :min="cycle01 + 1" :max="12" />
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="2">
周期从
<el-input-number v-model="cycle01" :min="1" :max="11" /> - <el-input-number v-model="cycle02" :min="cycle01 + 1" :max="12" />
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="3">
<el-input-number v-model='average01' :min="1" :max="11" /> 月开始
<el-input-number v-model='average02' :min="1" :max="12 - average01" /> 月月执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="3">
<el-input-number v-model="average01" :min="1" :max="11" /> 月开始
<el-input-number v-model="average02" :min="1" :max="12 - average01" /> 月月执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="4">
指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="8">
<el-option v-for="item in monthList" :key="item.key" :label="item.value" :value="item.key" />
</el-select>
</el-radio>
</el-form-item>
</el-form>
<el-form-item>
<el-radio v-model="radioValue" :label="4">
指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="8">
<el-option v-for="item in monthList" :key="item.key" :label="item.value" :value="item.key" />
</el-select>
</el-radio>
</el-form-item>
</el-form>
</template>
<script setup>
const emit = defineEmits(['update'])
const emit = defineEmits(['update']);
const props = defineProps({
cron: {
type: Object,
default: () => {
return {
second: "*",
min: "*",
hour: "*",
day: "*",
month: "*",
week: "?",
year: "",
}
}
},
check: {
type: Function,
default: () => {
}
}
})
const radioValue = ref(1)
const cycle01 = ref(1)
const cycle02 = ref(2)
const average01 = ref(1)
const average02 = ref(1)
const checkboxList = ref([])
const checkCopy = ref([1])
cron: {
type: Object,
default: () => {
return {
second: '*',
min: '*',
hour: '*',
day: '*',
month: '*',
week: '?',
year: '',
};
},
},
check: {
type: Function,
default: () => {},
},
});
const radioValue = ref(1);
const cycle01 = ref(1);
const cycle02 = ref(2);
const average01 = ref(1);
const average02 = ref(1);
const checkboxList = ref([]);
const checkCopy = ref([1]);
const monthList = ref([
{key: 1, value: '一月'},
{key: 2, value: '二月'},
{key: 3, value: '三月'},
{key: 4, value: '四月'},
{key: 5, value: '五月'},
{key: 6, value: '六月'},
{key: 7, value: '七月'},
{key: 8, value: '八月'},
{key: 9, value: '九月'},
{key: 10, value: '十月'},
{key: 11, value: '十一月'},
{key: 12, value: '十二月'}
])
{ key: 1, value: '一月' },
{ key: 2, value: '二月' },
{ key: 3, value: '三月' },
{ key: 4, value: '四月' },
{ key: 5, value: '五月' },
{ key: 6, value: '六月' },
{ key: 7, value: '七月' },
{ key: 8, value: '八月' },
{ key: 9, value: '九月' },
{ key: 10, value: '十月' },
{ key: 11, value: '十一月' },
{ key: 12, value: '十二月' },
]);
const cycleTotal = computed(() => {
cycle01.value = props.check(cycle01.value, 1, 11)
cycle02.value = props.check(cycle02.value, cycle01.value + 1, 12)
return cycle01.value + '-' + cycle02.value
})
cycle01.value = props.check(cycle01.value, 1, 11);
cycle02.value = props.check(cycle02.value, cycle01.value + 1, 12);
return cycle01.value + '-' + cycle02.value;
});
const averageTotal = computed(() => {
average01.value = props.check(average01.value, 1, 11)
average02.value = props.check(average02.value, 1, 12 - average01.value)
return average01.value + '/' + average02.value
})
average01.value = props.check(average01.value, 1, 11);
average02.value = props.check(average02.value, 1, 12 - average01.value);
return average01.value + '/' + average02.value;
});
const checkboxString = computed(() => {
return checkboxList.value.join(',')
})
watch(() => props.cron.month, value => changeRadioValue(value))
watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange())
return checkboxList.value.join(',');
});
watch(
() => props.cron.month,
(value) => changeRadioValue(value)
);
watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange());
function changeRadioValue(value) {
if (value === '*') {
radioValue.value = 1
} else if (value.indexOf('-') > -1) {
const indexArr = value.split('-')
cycle01.value = Number(indexArr[0])
cycle02.value = Number(indexArr[1])
radioValue.value = 2
} else if (value.indexOf('/') > -1) {
const indexArr = value.split('/')
average01.value = Number(indexArr[0])
average02.value = Number(indexArr[1])
radioValue.value = 3
} else {
checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))]
radioValue.value = 4
}
if (value === '*') {
radioValue.value = 1;
} else if (value.indexOf('-') > -1) {
const indexArr = value.split('-');
cycle01.value = Number(indexArr[0]);
cycle02.value = Number(indexArr[1]);
radioValue.value = 2;
} else if (value.indexOf('/') > -1) {
const indexArr = value.split('/');
average01.value = Number(indexArr[0]);
average02.value = Number(indexArr[1]);
radioValue.value = 3;
} else {
checkboxList.value = [...new Set(value.split(',').map((item) => Number(item)))];
radioValue.value = 4;
}
}
function onRadioChange() {
switch (radioValue.value) {
case 1:
emit('update', 'month', '*', 'month')
break
case 2:
emit('update', 'month', cycleTotal.value, 'month')
break
case 3:
emit('update', 'month', averageTotal.value, 'month')
break
case 4:
if (checkboxList.value.length === 0) {
checkboxList.value.push(checkCopy.value[0])
} else {
checkCopy.value = checkboxList.value
}
emit('update', 'month', checkboxString.value, 'month')
break
}
switch (radioValue.value) {
case 1:
emit('update', 'month', '*', 'month');
break;
case 2:
emit('update', 'month', cycleTotal.value, 'month');
break;
case 3:
emit('update', 'month', averageTotal.value, 'month');
break;
case 4:
if (checkboxList.value.length === 0) {
checkboxList.value.push(checkCopy.value[0]);
} else {
checkCopy.value = checkboxList.value;
}
emit('update', 'month', checkboxString.value, 'month');
break;
}
}
</script>
<style lang="scss" scoped>
.el-input-number--small, .el-select, .el-select--small {
margin: 0 0.2rem;
.el-input-number--small,
.el-select,
.el-select--small {
margin: 0 0.2rem;
}
.el-select, .el-select--small {
width: 18.8rem;
.el-select,
.el-select--small {
width: 18.8rem;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -1,130 +1,132 @@
<template>
<el-form size="small">
<el-form-item>
<el-radio v-model='radioValue' :label="1">
允许的通配符[, - * /]
</el-radio>
</el-form-item>
<el-form size="small">
<el-form-item>
<el-radio v-model="radioValue" :label="1"> 允许的通配符[, - * /] </el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="2">
周期从
<el-input-number v-model='cycle01' :min="0" :max="58" /> -
<el-input-number v-model='cycle02' :min="cycle01 + 1" :max="59" />
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="2">
周期从
<el-input-number v-model="cycle01" :min="0" :max="58" /> - <el-input-number v-model="cycle02" :min="cycle01 + 1" :max="59" />
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="3">
<el-input-number v-model='average01' :min="0" :max="58" /> 秒开始
<el-input-number v-model='average02' :min="1" :max="59 - average01" /> 秒执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="3">
<el-input-number v-model="average01" :min="0" :max="58" /> 秒开始
<el-input-number v-model="average02" :min="1" :max="59 - average01" /> 秒执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="4">
指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="10">
<el-option v-for="item in 60" :key="item" :label="item - 1" :value="item - 1" />
</el-select>
</el-radio>
</el-form-item>
</el-form>
<el-form-item>
<el-radio v-model="radioValue" :label="4">
指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="10">
<el-option v-for="item in 60" :key="item" :label="item - 1" :value="item - 1" />
</el-select>
</el-radio>
</el-form-item>
</el-form>
</template>
<script setup>
const emit = defineEmits(['update'])
const emit = defineEmits(['update']);
const props = defineProps({
cron: {
type: Object,
default: () => {
return {
second: "*",
min: "*",
hour: "*",
day: "*",
month: "*",
week: "?",
year: "",
}
}
},
check: {
type: Function,
default: () => {
}
}
})
const radioValue = ref(1)
const cycle01 = ref(0)
const cycle02 = ref(1)
const average01 = ref(0)
const average02 = ref(1)
const checkboxList = ref([])
const checkCopy = ref([0])
cron: {
type: Object,
default: () => {
return {
second: '*',
min: '*',
hour: '*',
day: '*',
month: '*',
week: '?',
year: '',
};
},
},
check: {
type: Function,
default: () => {},
},
});
const radioValue = ref(1);
const cycle01 = ref(0);
const cycle02 = ref(1);
const average01 = ref(0);
const average02 = ref(1);
const checkboxList = ref([]);
const checkCopy = ref([0]);
const cycleTotal = computed(() => {
cycle01.value = props.check(cycle01.value, 0, 58)
cycle02.value = props.check(cycle02.value, cycle01.value + 1, 59)
return cycle01.value + '-' + cycle02.value
})
cycle01.value = props.check(cycle01.value, 0, 58);
cycle02.value = props.check(cycle02.value, cycle01.value + 1, 59);
return cycle01.value + '-' + cycle02.value;
});
const averageTotal = computed(() => {
average01.value = props.check(average01.value, 0, 58)
average02.value = props.check(average02.value, 1, 59 - average01.value)
return average01.value + '/' + average02.value
})
average01.value = props.check(average01.value, 0, 58);
average02.value = props.check(average02.value, 1, 59 - average01.value);
return average01.value + '/' + average02.value;
});
const checkboxString = computed(() => {
return checkboxList.value.join(',')
})
watch(() => props.cron.second, value => changeRadioValue(value))
watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange())
return checkboxList.value.join(',');
});
watch(
() => props.cron.second,
(value) => changeRadioValue(value)
);
watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange());
function changeRadioValue(value) {
if (value === '*') {
radioValue.value = 1
} else if (value.indexOf('-') > -1) {
const indexArr = value.split('-')
cycle01.value = Number(indexArr[0])
cycle02.value = Number(indexArr[1])
radioValue.value = 2
} else if (value.indexOf('/') > -1) {
const indexArr = value.split('/')
average01.value = Number(indexArr[0])
average02.value = Number(indexArr[1])
radioValue.value = 3
} else {
checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))]
radioValue.value = 4
}
if (value === '*') {
radioValue.value = 1;
} else if (value.indexOf('-') > -1) {
const indexArr = value.split('-');
cycle01.value = Number(indexArr[0]);
cycle02.value = Number(indexArr[1]);
radioValue.value = 2;
} else if (value.indexOf('/') > -1) {
const indexArr = value.split('/');
average01.value = Number(indexArr[0]);
average02.value = Number(indexArr[1]);
radioValue.value = 3;
} else {
checkboxList.value = [...new Set(value.split(',').map((item) => Number(item)))];
radioValue.value = 4;
}
}
//
function onRadioChange() {
switch (radioValue.value) {
case 1:
emit('update', 'second', '*', 'second')
break
case 2:
emit('update', 'second', cycleTotal.value, 'second')
break
case 3:
emit('update', 'second', averageTotal.value, 'second')
break
case 4:
if (checkboxList.value.length === 0) {
checkboxList.value.push(checkCopy.value[0])
} else {
checkCopy.value = checkboxList.value
}
emit('update', 'second', checkboxString.value, 'second')
break
}
switch (radioValue.value) {
case 1:
emit('update', 'second', '*', 'second');
break;
case 2:
emit('update', 'second', cycleTotal.value, 'second');
break;
case 3:
emit('update', 'second', averageTotal.value, 'second');
break;
case 4:
if (checkboxList.value.length === 0) {
checkboxList.value.push(checkCopy.value[0]);
} else {
checkCopy.value = checkboxList.value;
}
emit('update', 'second', checkboxString.value, 'second');
break;
}
}
</script>
<style lang="scss" scoped>
.el-input-number--small, .el-select, .el-select--small {
margin: 0 0.2rem;
.el-input-number--small,
.el-select,
.el-select--small {
margin: 0 0.2rem;
}
.el-select, .el-select--small {
width: 18.8rem;
.el-select,
.el-select--small {
width: 18.8rem;
}
</style>

View File

@ -1,199 +1,192 @@
<template>
<el-form size='small'>
<el-form-item>
<el-radio v-model='radioValue' :label="1">
允许的通配符[, - * ? / L #]
</el-radio>
</el-form-item>
<el-form size="small">
<el-form-item>
<el-radio v-model="radioValue" :label="1"> 允许的通配符[, - * ? / L #] </el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="2">
不指定
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="2"> 不指定 </el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="3">
周期从
<el-select clearable v-model="cycle01">
<el-option
v-for="(item,index) of weekList"
:key="index"
:label="item.value"
:value="item.key"
:disabled="item.key === 7"
>{{item.value}}</el-option>
</el-select>
-
<el-select clearable v-model="cycle02">
<el-option
v-for="(item,index) of weekList"
:key="index"
:label="item.value"
:value="item.key"
:disabled="item.key <= cycle01"
>{{item.value}}</el-option>
</el-select>
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="3">
周期从
<el-select clearable v-model="cycle01">
<el-option v-for="(item, index) of weekList" :key="index" :label="item.value" :value="item.key" :disabled="item.key === 7">{{
item.value
}}</el-option>
</el-select>
-
<el-select clearable v-model="cycle02">
<el-option v-for="(item, index) of weekList" :key="index" :label="item.value" :value="item.key" :disabled="item.key <= cycle01">{{
item.value
}}</el-option>
</el-select>
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="4">
<el-input-number v-model='average01' :min="1" :max="4" /> 周的
<el-select clearable v-model="average02">
<el-option v-for="item in weekList" :key="item.key" :label="item.value" :value="item.key" />
</el-select>
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="4">
<el-input-number v-model="average01" :min="1" :max="4" /> 周的
<el-select clearable v-model="average02">
<el-option v-for="item in weekList" :key="item.key" :label="item.value" :value="item.key" />
</el-select>
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="5">
本月最后一个
<el-select clearable v-model="weekday">
<el-option v-for="item in weekList" :key="item.key" :label="item.value" :value="item.key" />
</el-select>
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="5">
本月最后一个
<el-select clearable v-model="weekday">
<el-option v-for="item in weekList" :key="item.key" :label="item.value" :value="item.key" />
</el-select>
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="6">
指定
<el-select class="multiselect" clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="6">
<el-option v-for="item in weekList" :key="item.key" :label="item.value" :value="item.key" />
</el-select>
</el-radio>
</el-form-item>
</el-form>
<el-form-item>
<el-radio v-model="radioValue" :label="6">
指定
<el-select class="multiselect" clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="6">
<el-option v-for="item in weekList" :key="item.key" :label="item.value" :value="item.key" />
</el-select>
</el-radio>
</el-form-item>
</el-form>
</template>
<script setup>
const emit = defineEmits(['update'])
const emit = defineEmits(['update']);
const props = defineProps({
cron: {
type: Object,
default: () => {
return {
second: "*",
min: "*",
hour: "*",
day: "*",
month: "*",
week: "?",
year: ""
}
}
},
check: {
type: Function,
default: () => {
}
}
})
const radioValue = ref(2)
const cycle01 = ref(2)
const cycle02 = ref(3)
const average01 = ref(1)
const average02 = ref(2)
const weekday = ref(2)
const checkboxList = ref([])
const checkCopy = ref([2])
cron: {
type: Object,
default: () => {
return {
second: '*',
min: '*',
hour: '*',
day: '*',
month: '*',
week: '?',
year: '',
};
},
},
check: {
type: Function,
default: () => {},
},
});
const radioValue = ref(2);
const cycle01 = ref(2);
const cycle02 = ref(3);
const average01 = ref(1);
const average02 = ref(2);
const weekday = ref(2);
const checkboxList = ref([]);
const checkCopy = ref([2]);
const weekList = ref([
{key: 1, value: '星期日'},
{key: 2, value: '星期一'},
{key: 3, value: '星期二'},
{key: 4, value: '星期三'},
{key: 5, value: '星期四'},
{key: 6, value: '星期五'},
{key: 7, value: '星期六'}
])
{ key: 1, value: '星期日' },
{ key: 2, value: '星期一' },
{ key: 3, value: '星期二' },
{ key: 4, value: '星期三' },
{ key: 5, value: '星期四' },
{ key: 6, value: '星期五' },
{ key: 7, value: '星期六' },
]);
const cycleTotal = computed(() => {
cycle01.value = props.check(cycle01.value, 1, 6)
cycle02.value = props.check(cycle02.value, cycle01.value + 1, 7)
return cycle01.value + '-' + cycle02.value
})
cycle01.value = props.check(cycle01.value, 1, 6);
cycle02.value = props.check(cycle02.value, cycle01.value + 1, 7);
return cycle01.value + '-' + cycle02.value;
});
const averageTotal = computed(() => {
average01.value = props.check(average01.value, 1, 4)
average02.value = props.check(average02.value, 1, 7)
return average02.value + '#' + average01.value
})
average01.value = props.check(average01.value, 1, 4);
average02.value = props.check(average02.value, 1, 7);
return average02.value + '#' + average01.value;
});
const weekdayTotal = computed(() => {
weekday.value = props.check(weekday.value, 1, 7)
return weekday.value + 'L'
})
weekday.value = props.check(weekday.value, 1, 7);
return weekday.value + 'L';
});
const checkboxString = computed(() => {
return checkboxList.value.join(',')
})
watch(() => props.cron.week, value => changeRadioValue(value))
watch([radioValue, cycleTotal, averageTotal, weekdayTotal, checkboxString], () => onRadioChange())
return checkboxList.value.join(',');
});
watch(
() => props.cron.week,
(value) => changeRadioValue(value)
);
watch([radioValue, cycleTotal, averageTotal, weekdayTotal, checkboxString], () => onRadioChange());
function changeRadioValue(value) {
if (value === "*") {
radioValue.value = 1
} else if (value === "?") {
radioValue.value = 2
} else if (value.indexOf("-") > -1) {
const indexArr = value.split('-')
cycle01.value = Number(indexArr[0])
cycle02.value = Number(indexArr[1])
radioValue.value = 3
} else if (value.indexOf("#") > -1) {
const indexArr = value.split('#')
average01.value = Number(indexArr[1])
average02.value = Number(indexArr[0])
radioValue.value = 4
} else if (value.indexOf("L") > -1) {
const indexArr = value.split("L")
weekday.value = Number(indexArr[0])
radioValue.value = 5
} else {
checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))]
radioValue.value = 6
}
if (value === '*') {
radioValue.value = 1;
} else if (value === '?') {
radioValue.value = 2;
} else if (value.indexOf('-') > -1) {
const indexArr = value.split('-');
cycle01.value = Number(indexArr[0]);
cycle02.value = Number(indexArr[1]);
radioValue.value = 3;
} else if (value.indexOf('#') > -1) {
const indexArr = value.split('#');
average01.value = Number(indexArr[1]);
average02.value = Number(indexArr[0]);
radioValue.value = 4;
} else if (value.indexOf('L') > -1) {
const indexArr = value.split('L');
weekday.value = Number(indexArr[0]);
radioValue.value = 5;
} else {
checkboxList.value = [...new Set(value.split(',').map((item) => Number(item)))];
radioValue.value = 6;
}
}
function onRadioChange() {
if (radioValue.value === 2 && props.cron.day === '?') {
emit('update', 'day', '*', 'week')
}
if (radioValue.value !== 2 && props.cron.day !== '?') {
emit('update', 'day', '?', 'week')
}
switch (radioValue.value) {
case 1:
emit('update', 'week', '*', 'week')
break
case 2:
emit('update', 'week', '?', 'week')
break
case 3:
emit('update', 'week', cycleTotal.value, 'week')
break
case 4:
emit('update', 'week', averageTotal.value, 'week')
break
case 5:
emit('update', 'week', weekdayTotal.value, 'week')
break
case 6:
if (checkboxList.value.length === 0) {
checkboxList.value.push(checkCopy.value[0])
} else {
checkCopy.value = checkboxList.value
}
emit('update', 'week', checkboxString.value, 'week')
break
}
if (radioValue.value === 2 && props.cron.day === '?') {
emit('update', 'day', '*', 'week');
}
if (radioValue.value !== 2 && props.cron.day !== '?') {
emit('update', 'day', '?', 'week');
}
switch (radioValue.value) {
case 1:
emit('update', 'week', '*', 'week');
break;
case 2:
emit('update', 'week', '?', 'week');
break;
case 3:
emit('update', 'week', cycleTotal.value, 'week');
break;
case 4:
emit('update', 'week', averageTotal.value, 'week');
break;
case 5:
emit('update', 'week', weekdayTotal.value, 'week');
break;
case 6:
if (checkboxList.value.length === 0) {
checkboxList.value.push(checkCopy.value[0]);
} else {
checkCopy.value = checkboxList.value;
}
emit('update', 'week', checkboxString.value, 'week');
break;
}
}
</script>
<style lang="scss" scoped>
.el-input-number--small, .el-select, .el-select--small {
margin: 0 0.5rem;
.el-input-number--small,
.el-select,
.el-select--small {
margin: 0 0.5rem;
}
.el-select, .el-select--small {
width: 8rem;
.el-select,
.el-select--small {
width: 8rem;
}
.el-select.multiselect, .el-select--small.multiselect {
width: 17.8rem;
.el-select.multiselect,
.el-select--small.multiselect {
width: 17.8rem;
}
</style>

View File

@ -1,156 +1,152 @@
<template>
<el-form size="small">
<el-form-item>
<el-radio :label="1" v-model='radioValue'>
不填允许的通配符[, - * /]
</el-radio>
</el-form-item>
<el-form size="small">
<el-form-item>
<el-radio :label="1" v-model="radioValue"> 不填允许的通配符[, - * /] </el-radio>
</el-form-item>
<el-form-item>
<el-radio :label="2" v-model='radioValue'>
每年
</el-radio>
</el-form-item>
<el-form-item>
<el-radio :label="2" v-model="radioValue"> 每年 </el-radio>
</el-form-item>
<el-form-item>
<el-radio :label="3" v-model='radioValue'>
周期从
<el-input-number v-model='cycle01' :min='fullYear' :max="maxFullYear - 1" /> -
<el-input-number v-model='cycle02' :min="cycle01 + 1" :max="maxFullYear" />
</el-radio>
</el-form-item>
<el-form-item>
<el-radio :label="3" v-model="radioValue">
周期从
<el-input-number v-model="cycle01" :min="fullYear" :max="maxFullYear - 1" /> -
<el-input-number v-model="cycle02" :min="cycle01 + 1" :max="maxFullYear" />
</el-radio>
</el-form-item>
<el-form-item>
<el-radio :label="4" v-model='radioValue'>
<el-input-number v-model='average01' :min='fullYear' :max="maxFullYear - 1" /> 年开始
<el-input-number v-model='average02' :min="1" :max="10" /> 年执行一次
</el-radio>
<el-form-item>
<el-radio :label="4" v-model="radioValue">
<el-input-number v-model="average01" :min="fullYear" :max="maxFullYear - 1" /> 年开始
<el-input-number v-model="average02" :min="1" :max="10" /> 年执行一次
</el-radio>
</el-form-item>
</el-form-item>
<el-form-item>
<el-radio :label="5" v-model='radioValue'>
指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="8">
<el-option v-for="item in 9" :key="item" :value="item - 1 + fullYear"
:label="item - 1 + fullYear" />
</el-select>
</el-radio>
</el-form-item>
</el-form>
<el-form-item>
<el-radio :label="5" v-model="radioValue">
指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="8">
<el-option v-for="item in 9" :key="item" :value="item - 1 + fullYear" :label="item - 1 + fullYear" />
</el-select>
</el-radio>
</el-form-item>
</el-form>
</template>
<script setup>
const emit = defineEmits(['update'])
const emit = defineEmits(['update']);
const props = defineProps({
cron: {
type: Object,
default: () => {
return {
second: "*",
min: "*",
hour: "*",
day: "*",
month: "*",
week: "?",
year: ""
}
}
},
check: {
type: Function,
default: () => {
}
}
})
const fullYear = ref(0)
const maxFullYear = ref(0)
const radioValue = ref(1)
const cycle01 = ref(0)
const cycle02 = ref(0)
const average01 = ref(0)
const average02 = ref(1)
const checkboxList = ref([])
const checkCopy = ref([])
cron: {
type: Object,
default: () => {
return {
second: '*',
min: '*',
hour: '*',
day: '*',
month: '*',
week: '?',
year: '',
};
},
},
check: {
type: Function,
default: () => {},
},
});
const fullYear = ref(0);
const maxFullYear = ref(0);
const radioValue = ref(1);
const cycle01 = ref(0);
const cycle02 = ref(0);
const average01 = ref(0);
const average02 = ref(1);
const checkboxList = ref([]);
const checkCopy = ref([]);
const cycleTotal = computed(() => {
cycle01.value = props.check(cycle01.value, fullYear.value, maxFullYear.value - 1)
cycle02.value = props.check(cycle02.value, cycle01.value + 1, maxFullYear.value)
return cycle01.value + '-' + cycle02.value
})
cycle01.value = props.check(cycle01.value, fullYear.value, maxFullYear.value - 1);
cycle02.value = props.check(cycle02.value, cycle01.value + 1, maxFullYear.value);
return cycle01.value + '-' + cycle02.value;
});
const averageTotal = computed(() => {
average01.value = props.check(average01.value, fullYear.value, maxFullYear.value - 1)
average02.value = props.check(average02.value, 1, 10)
return average01.value + '/' + average02.value
})
average01.value = props.check(average01.value, fullYear.value, maxFullYear.value - 1);
average02.value = props.check(average02.value, 1, 10);
return average01.value + '/' + average02.value;
});
const checkboxString = computed(() => {
return checkboxList.value.join(',')
})
watch(() => props.cron.year, value => changeRadioValue(value))
watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange())
return checkboxList.value.join(',');
});
watch(
() => props.cron.year,
(value) => changeRadioValue(value)
);
watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange());
function changeRadioValue(value) {
if (value === '') {
radioValue.value = 1
} else if (value === "*") {
radioValue.value = 2
} else if (value.indexOf("-") > -1) {
const indexArr = value.split('-')
cycle01.value = Number(indexArr[0])
cycle02.value = Number(indexArr[1])
radioValue.value = 3
} else if (value.indexOf("/") > -1) {
const indexArr = value.split('#')
average01.value = Number(indexArr[1])
average02.value = Number(indexArr[0])
radioValue.value = 4
} else {
checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))]
radioValue.value = 5
}
if (value === '') {
radioValue.value = 1;
} else if (value === '*') {
radioValue.value = 2;
} else if (value.indexOf('-') > -1) {
const indexArr = value.split('-');
cycle01.value = Number(indexArr[0]);
cycle02.value = Number(indexArr[1]);
radioValue.value = 3;
} else if (value.indexOf('/') > -1) {
const indexArr = value.split('#');
average01.value = Number(indexArr[1]);
average02.value = Number(indexArr[0]);
radioValue.value = 4;
} else {
checkboxList.value = [...new Set(value.split(',').map((item) => Number(item)))];
radioValue.value = 5;
}
}
function onRadioChange() {
switch (radioValue.value) {
case 1:
emit('update', 'year', '', 'year')
break
case 2:
emit('update', 'year', '*', 'year')
break
case 3:
emit('update', 'year', cycleTotal.value, 'year')
break
case 4:
emit('update', 'year', averageTotal.value, 'year')
break
case 5:
if (checkboxList.value.length === 0) {
checkboxList.value.push(checkCopy.value[0])
} else {
checkCopy.value = checkboxList.value
}
emit('update', 'year', checkboxString.value, 'year')
break
}
switch (radioValue.value) {
case 1:
emit('update', 'year', '', 'year');
break;
case 2:
emit('update', 'year', '*', 'year');
break;
case 3:
emit('update', 'year', cycleTotal.value, 'year');
break;
case 4:
emit('update', 'year', averageTotal.value, 'year');
break;
case 5:
if (checkboxList.value.length === 0) {
checkboxList.value.push(checkCopy.value[0]);
} else {
checkCopy.value = checkboxList.value;
}
emit('update', 'year', checkboxString.value, 'year');
break;
}
}
onMounted(() => {
fullYear.value = Number(new Date().getFullYear())
maxFullYear.value = fullYear.value + 10
cycle01.value = fullYear.value
cycle02.value = cycle01.value + 1
average01.value = fullYear.value
checkCopy.value = [fullYear.value]
})
fullYear.value = Number(new Date().getFullYear());
maxFullYear.value = fullYear.value + 10;
cycle01.value = fullYear.value;
cycle02.value = cycle01.value + 1;
average01.value = fullYear.value;
checkCopy.value = [fullYear.value];
});
</script>
<style lang="scss" scoped>
.el-input-number--small,
.el-select,
.el-select--small {
margin: 0 0.2rem;
margin: 0 0.2rem;
}
.el-select,
.el-select--small {
width: 18.8rem;
width: 18.8rem;
}
</style>

View File

@ -1,41 +1,48 @@
<template>
<div>
<template v-for="(item, index) in props.options">
<template v-if="values.includes(item.value)">
<span v-if="item.elTagType == 'default' || item.elTagType == ''" :key="item.value" :index="index"
:class="item.elTagClass">{{ item.label }}</span>
<el-tag v-else :disable-transitions="true" :key="item.value" :index="index"
:type="item.elTagType === 'primary' ? '' : item.elTagType" :class="item.elTagClass">{{ item.label }}</el-tag>
</template>
</template>
</div>
<div>
<template v-for="(item, index) in props.options">
<template v-if="values.includes(item.value)">
<span v-if="item.elTagType == 'default' || item.elTagType == ''" :key="item.value" :index="index" :class="item.elTagClass">{{
item.label
}}</span>
<el-tag
v-else
:disable-transitions="true"
:key="item.value"
:index="index"
:type="item.elTagType === 'primary' ? '' : item.elTagType"
:class="item.elTagClass"
>{{ item.label }}</el-tag
>
</template>
</template>
</div>
</template>
<script setup lang="ts" name="dict-tag">
import { computed } from "vue";
import { computed } from 'vue';
const props = defineProps({
//
options: {
type: Array,
default: null,
},
//
value: [Number, String, Array],
})
//
options: {
type: Array,
default: null,
},
//
value: [Number, String, Array],
});
const values = computed(() => {
if (props.value !== null && typeof props.value !== 'undefined') {
return Array.isArray(props.value) ? props.value : [String(props.value)];
} else {
return [];
}
})
if (props.value !== null && typeof props.value !== 'undefined') {
return Array.isArray(props.value) ? props.value : [String(props.value)];
} else {
return [];
}
});
</script>
<style scoped>
.el-tag+.el-tag {
margin-left: 10px;
.el-tag + .el-tag {
margin-left: 10px;
}
</style>

View File

@ -17,7 +17,7 @@
import '@wangeditor/editor/dist/css/style.css';
import { reactive, shallowRef, watch, onBeforeUnmount } from 'vue';
// @ts-ignore
import { IDomEditor } from "@wangeditor/editor";
import { IDomEditor } from '@wangeditor/editor';
import { Toolbar, Editor } from '@wangeditor/editor-for-vue';
//

View File

@ -1,129 +1,129 @@
$d-type: (
flex: flex,
block: block,
none: none,
flex: flex,
block: block,
none: none,
);
$flex-jc: (
start: flex-start,
end: flex-end,
center: center,
between: space-between,
around: space-around,
start: flex-start,
end: flex-end,
center: center,
between: space-between,
around: space-around,
);
$flex-ai: (
start: flex-start,
end: flex-end,
center: center,
stretch: stretch,
start: flex-start,
end: flex-end,
center: center,
stretch: stretch,
);
//spacing
$spacing-types: (
m: margin,
p: padding,
m: margin,
p: padding,
);
$spacing-directions: (
t: top,
r: right,
b: bottom,
l: left,
t: top,
r: right,
b: bottom,
l: left,
);
$spacing-base-size: 5px;
$spacing-sizes: (
0: 0,
1: 1,
2: 2,
3: 3,
4: 4,
5: 5,
0: 0,
1: 1,
2: 2,
3: 3,
4: 4,
5: 5,
);
@each $key, $value in $d-type {
.d-#{$key} {
display: $value;
}
.d-#{$key} {
display: $value;
}
}
.flex-column {
flex-direction: column;
flex-direction: column;
}
.text-ellipsis {
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.w-100 {
width: 100%;
width: 100%;
}
.h-100 {
height: 100%;
height: 100%;
}
.flex-wrap {
flex-wrap: wrap;
flex-wrap: wrap;
}
.flex-grow-1 {
flex: 1;
flex: 1;
}
@each $dir in(top, bottom, right, left) {
.border-#{$dir} {
border-#{$dir}: 1px solid;
}
.border-#{$dir} {
border-#{$dir}: 1px solid;
}
}
@each $key, $value in $flex-jc {
.jc-#{$key} {
justify-content: $value;
}
.jc-#{$key} {
justify-content: $value;
}
}
@each $key, $value in $flex-ai {
.ai-#{$key} {
align-items: $value;
}
.ai-#{$key} {
align-items: $value;
}
}
//text
@each $var in (left, center, right) {
.text-#{$var} {
text-align: $var !important;
}
.text-#{$var} {
text-align: $var !important;
}
}
@each $typeKey, $type in $spacing-types {
@each $sizeKey, $size in $spacing-sizes {
.#{$typeKey}-#{$sizeKey} {
#{$type}: $size * $spacing-base-size;
}
}
@each $sizeKey, $size in $spacing-sizes {
.#{$typeKey}-#{$sizeKey} {
#{$type}: $size * $spacing-base-size;
}
}
@each $sizeKey, $size in $spacing-sizes {
.#{$typeKey}x-#{$sizeKey} {
#{$type}-left: $size * $spacing-base-size;
#{$type}-right: $size * $spacing-base-size;
}
@each $sizeKey, $size in $spacing-sizes {
.#{$typeKey}x-#{$sizeKey} {
#{$type}-left: $size * $spacing-base-size;
#{$type}-right: $size * $spacing-base-size;
}
.#{$typeKey}y-#{$sizeKey} {
#{$type}-top: $size * $spacing-base-size;
#{$type}-bottom: $size * $spacing-base-size;
}
}
.#{$typeKey}y-#{$sizeKey} {
#{$type}-top: $size * $spacing-base-size;
#{$type}-bottom: $size * $spacing-base-size;
}
}
@each $directionKey, $direction in $spacing-directions {
@each $sizeKey, $size in $spacing-sizes {
.#{$typeKey}#{$directionKey}-#{$sizeKey} {
#{$type}-#{$direction}: $size * $spacing-base-size;
}
}
}
@each $directionKey, $direction in $spacing-directions {
@each $sizeKey, $size in $spacing-sizes {
.#{$typeKey}#{$directionKey}-#{$sizeKey} {
#{$type}-#{$direction}: $size * $spacing-base-size;
}
}
}
}

View File

@ -1,106 +1,105 @@
<template>
<div :class="mode=='square'?'chatface':'brround avatar cover-image'" :style="transform"
style="overflow:hidden;width:40px;height:40px;">
<img v-if="faceUrl&&!num" :src="faceUrl" class="w-100 h-100"/>
<div v-else :style="styles" class="w-100 h-100 d-flex ai-center jc-center">{{ text }}</div>
</div>
<div :class="mode == 'square' ? 'chatface' : 'brround avatar cover-image'" :style="transform" style="overflow: hidden; width: 40px; height: 40px">
<img v-if="faceUrl && !num" :src="faceUrl" class="w-100 h-100" />
<div v-else :style="styles" class="w-100 h-100 d-flex ai-center jc-center">{{ text }}</div>
</div>
</template>
<script>
export default {
name: "nameAvatar",
props: {
scale: {
type: String,
default: "1"
},
num: [Number, String],
name: String,
mode: {
type: String,
default: ""
},
fontColor: {
type: String,
default: "#fff"
},
backgroundColor: {
type: String,
default: "#3696F2"
},
faceUrl: {
type: String,
default: ""
}
},
data() {
return {};
},
watch: {},
computed: {
// eslint-disable-next-line vue/return-in-computed-property
text() {
if (this.num !== undefined) {
return `+${this.num}`;
} else {
if (this.name) {
return this.name.slice(-2);
}
}
},
transform() {
let style = {};
if (this.scale) {
style["transform"] = `scale(${this.scale}, ${this.scale})`;
}
return style;
},
styles() {
let style = {};
if (this.size) {
style["font-size"] = "12px";
}
if (this.fontColor) {
style.color = this.fontColor;
}
if (this.backgroundColor) {
style["background"] = this.backgroundColor;
}
return style;
}
},
methods: {}
name: 'nameAvatar',
props: {
scale: {
type: String,
default: '1',
},
num: [Number, String],
name: String,
mode: {
type: String,
default: '',
},
fontColor: {
type: String,
default: '#fff',
},
backgroundColor: {
type: String,
default: '#3696F2',
},
faceUrl: {
type: String,
default: '',
},
},
data() {
return {};
},
watch: {},
computed: {
// eslint-disable-next-line vue/return-in-computed-property
text() {
if (this.num !== undefined) {
return `+${this.num}`;
} else {
if (this.name) {
return this.name.slice(-2);
}
}
},
transform() {
let style = {};
if (this.scale) {
style['transform'] = `scale(${this.scale}, ${this.scale})`;
}
return style;
},
styles() {
let style = {};
if (this.size) {
style['font-size'] = '12px';
}
if (this.fontColor) {
style.color = this.fontColor;
}
if (this.backgroundColor) {
style['background'] = this.backgroundColor;
}
return style;
},
},
methods: {},
};
</script>
<style lang="scss" scoped>
@import "./base.scss";
@import './base.scss';
.avatar {
display: inline-block;
position: relative;
text-align: center;
vertical-align: bottom;
font-size: 8px;
user-select: none;
z-index: 10;
display: inline-block;
position: relative;
text-align: center;
vertical-align: bottom;
font-size: 8px;
user-select: none;
z-index: 10;
&:hover {
z-index: 100;
}
&:hover {
z-index: 100;
}
}
.brround {
border-radius: 50%;
border-radius: 50%;
}
.chatface {
display: block;
border-radius: 8px;
overflow: hidden;
display: block;
border-radius: 8px;
overflow: hidden;
img {
width: 100%;
height: 100%;
}
img {
width: 100%;
height: 100%;
}
}
</style>

View File

@ -1,49 +1,52 @@
<template>
<el-pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" class="mt15" :pager-count="5"
:page-sizes="props.pageSizes"
:current-page="props.current"
background
:page-size="props.size"
:layout="props.layout"
:total="props.total">
</el-pagination>
<el-pagination
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
class="mt15"
:pager-count="5"
:page-sizes="props.pageSizes"
:current-page="props.current"
background
:page-size="props.size"
:layout="props.layout"
:total="props.total"
>
</el-pagination>
</template>
<script setup lang="ts" name="pagination">
const emit = defineEmits(['sizeChange', 'currentChange'])
const emit = defineEmits(['sizeChange', 'currentChange']);
const props = defineProps({
current: {
type: Number,
default: 1,
},
size: {
type: Number,
default: 10,
},
total: {
type: Number,
default: 0,
},
pageSizes: {
type: Array,
default: () => {
return [1, 10, 20, 50, 100, 200]
}
},
layout: {
type: String,
default: "total, sizes, prev, pager, next, jumper",
}
})
current: {
type: Number,
default: 1,
},
size: {
type: Number,
default: 10,
},
total: {
type: Number,
default: 0,
},
pageSizes: {
type: Array,
default: () => {
return [1, 10, 20, 50, 100, 200];
},
},
layout: {
type: String,
default: 'total, sizes, prev, pager, next, jumper',
},
});
//
const sizeChangeHandle = (val: number) => {
emit('sizeChange', val)
emit('sizeChange', val);
};
//
const currentChangeHandle = (val: number) => {
emit('currentChange', val)
emit('currentChange', val);
};
</script>

View File

@ -1,75 +1,78 @@
<template>
<div class="head-container">
<el-input v-model="searchName" :placeholder="placeholder" clearable style="margin-bottom: 20px"
@change="getDeptTree" />
<el-tree :data="state.List" :props="props.props" :expand-on-click-node="false" ref="deptTreeRef"
:loading="state.localLoading" node-key="id" highlight-current default-expand-all @node-click="handleNodeClick" />
</div>
<div class="head-container">
<el-input v-model="searchName" :placeholder="placeholder" clearable style="margin-bottom: 20px" @change="getDeptTree" />
<el-tree
:data="state.List"
:props="props.props"
:expand-on-click-node="false"
ref="deptTreeRef"
:loading="state.localLoading"
node-key="id"
highlight-current
default-expand-all
@node-click="handleNodeClick"
/>
</div>
</template>
<script setup lang="ts" name="query-tree">
import { onMounted, reactive, ref, unref } from 'vue';
import { onMounted, reactive, ref, unref } from "vue";
const emit = defineEmits(['search', 'nodeClick'])
const emit = defineEmits(['search', 'nodeClick']);
const props = defineProps({
props: {
type: Object,
default: () => {
return {
label: 'name',
children: 'children',
value: 'id'
}
}
},
placeholder: {
type: String,
default: ''
},
loading: {
type: Boolean,
default: false
},
query: {
type: Function,
required: true
}
})
props: {
type: Object,
default: () => {
return {
label: 'name',
children: 'children',
value: 'id',
};
},
},
placeholder: {
type: String,
default: '',
},
loading: {
type: Boolean,
default: false,
},
query: {
type: Function,
required: true,
},
});
const state = reactive({
List: [],
localLoading: props.loading
})
List: [],
localLoading: props.loading,
});
const searchName = ref()
const searchName = ref();
const handleNodeClick = (item: any) => {
emit('nodeClick', item)
}
emit('nodeClick', item);
};
const getDeptTree = () => {
if (props.query instanceof Function) {
state.localLoading = true
const result = props.query(unref(searchName))
if ((typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function') {
result.then((r: any) => {
state.List = r.data
if(r.data.length > 0){
handleNodeClick(r.data[0])
}
})
}
}
}
if (props.query instanceof Function) {
state.localLoading = true;
const result = props.query(unref(searchName));
if ((typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function') {
result.then((r: any) => {
state.List = r.data;
if (r.data.length > 0) {
handleNodeClick(r.data[0]);
}
});
}
}
};
onMounted(() => {
getDeptTree()
})
getDeptTree();
});
</script>
<style scoped>
</style>
<style scoped></style>

View File

@ -1,66 +1,65 @@
<template>
<div class="top-right-btn" :style="style">
<el-row>
<el-tooltip class="item" effect="dark" :content="showSearch ? '隐藏搜索' : '显示搜索'" placement="top" v-if="search">
<el-button circle icon="Search" @click="toggleSearch()" />
</el-tooltip>
<el-tooltip class="item" effect="dark" content="刷新" placement="top">
<el-button circle icon="Refresh" @click="refresh()" />
</el-tooltip>
</el-row>
</div>
<div class="top-right-btn" :style="style">
<el-row>
<el-tooltip class="item" effect="dark" :content="showSearch ? '隐藏搜索' : '显示搜索'" placement="top" v-if="search">
<el-button circle icon="Search" @click="toggleSearch()" />
</el-tooltip>
<el-tooltip class="item" effect="dark" content="刷新" placement="top">
<el-button circle icon="Refresh" @click="refresh()" />
</el-tooltip>
</el-row>
</div>
</template>
<script setup name="right-toolbar">
const props = defineProps({
showSearch: {
type: Boolean,
default: true,
},
search: {
type: Boolean,
default: true,
},
gutter: {
type: Number,
default: 10,
},
})
showSearch: {
type: Boolean,
default: true,
},
search: {
type: Boolean,
default: true,
},
gutter: {
type: Number,
default: 10,
},
});
const emits = defineEmits(['update:showSearch', 'queryTable']);
const style = computed(() => {
const ret = {};
if (props.gutter) {
ret.marginRight = `${props.gutter / 2}px`;
}
return ret;
const ret = {};
if (props.gutter) {
ret.marginRight = `${props.gutter / 2}px`;
}
return ret;
});
//
function toggleSearch() {
emits("update:showSearch", !props.showSearch);
emits('update:showSearch', !props.showSearch);
}
//
function refresh() {
emits("queryTable");
emits('queryTable');
}
</script>
<style lang='scss' scoped>
<style lang="scss" scoped>
:deep(.el-transfer__button) {
border-radius: 50%;
display: block;
margin-left: 0px;
border-radius: 50%;
display: block;
margin-left: 0px;
}
:deep(.el-transfer__button:first-child) {
margin-bottom: 10px;
margin-bottom: 10px;
}
.my-el-transfer {
text-align: center;
text-align: center;
}
</style>

View File

@ -1,156 +1,155 @@
<template>
<div class="el-tree-select">
<el-select
style="width: 100%"
v-model="valueId"
ref="treeSelect"
:filterable="true"
:clearable="true"
@clear="clearHandle"
:filter-method="selectFilterData"
:placeholder="placeholder"
>
<el-option :value="valueId" :label="valueTitle">
<el-tree
id="tree-option"
ref="selectTree"
:accordion="accordion"
:data="options"
:props="objMap"
:node-key="objMap.value"
:expand-on-click-node="false"
:default-expanded-keys="defaultExpandedKey"
:filter-node-method="filterNode"
@node-click="handleNodeClick"
></el-tree>
</el-option>
</el-select>
</div>
<div class="el-tree-select">
<el-select
style="width: 100%"
v-model="valueId"
ref="treeSelect"
:filterable="true"
:clearable="true"
@clear="clearHandle"
:filter-method="selectFilterData"
:placeholder="placeholder"
>
<el-option :value="valueId" :label="valueTitle">
<el-tree
id="tree-option"
ref="selectTree"
:accordion="accordion"
:data="options"
:props="objMap"
:node-key="objMap.value"
:expand-on-click-node="false"
:default-expanded-keys="defaultExpandedKey"
:filter-node-method="filterNode"
@node-click="handleNodeClick"
></el-tree>
</el-option>
</el-select>
</div>
</template>
<script setup>
const { proxy } = getCurrentInstance();
const props = defineProps({
/* 配置项 */
objMap: {
type: Object,
default: () => {
return {
value: 'id', // ID
label: 'label', //
children: 'children' //
}
}
},
/* 自动收起 */
accordion: {
type: Boolean,
default: () => {
return false
}
},
/**当前双向数据绑定的值 */
value: {
type: [String, Number],
default: ''
},
/**当前的数据 */
options: {
type: Array,
default: () => []
},
/**输入框内部的文字 */
placeholder: {
type: String,
default: ''
}
})
/* 配置项 */
objMap: {
type: Object,
default: () => {
return {
value: 'id', // ID
label: 'label', //
children: 'children', //
};
},
},
/* 自动收起 */
accordion: {
type: Boolean,
default: () => {
return false;
},
},
/**当前双向数据绑定的值 */
value: {
type: [String, Number],
default: '',
},
/**当前的数据 */
options: {
type: Array,
default: () => [],
},
/**输入框内部的文字 */
placeholder: {
type: String,
default: '',
},
});
const emit = defineEmits(['update:value']);
const valueId = computed({
get: () => props.value,
set: (val) => {
emit('update:value', val)
}
get: () => props.value,
set: (val) => {
emit('update:value', val);
},
});
const valueTitle = ref('');
const defaultExpandedKey = ref([]);
function initHandle() {
nextTick(() => {
const selectedValue = valueId.value;
if(selectedValue !== null && typeof (selectedValue) !== 'undefined') {
const node = proxy.$refs.selectTree.getNode(selectedValue)
if (node) {
valueTitle.value = node.data[props.objMap.label]
proxy.$refs.selectTree.setCurrentKey(selectedValue) //
defaultExpandedKey.value = [selectedValue] //
}
} else {
clearHandle()
}
})
nextTick(() => {
const selectedValue = valueId.value;
if (selectedValue !== null && typeof selectedValue !== 'undefined') {
const node = proxy.$refs.selectTree.getNode(selectedValue);
if (node) {
valueTitle.value = node.data[props.objMap.label];
proxy.$refs.selectTree.setCurrentKey(selectedValue); //
defaultExpandedKey.value = [selectedValue]; //
}
} else {
clearHandle();
}
});
}
function handleNodeClick(node) {
valueTitle.value = node[props.objMap.label]
valueId.value = node[props.objMap.value];
defaultExpandedKey.value = [];
proxy.$refs.treeSelect.blur()
selectFilterData('')
valueTitle.value = node[props.objMap.label];
valueId.value = node[props.objMap.value];
defaultExpandedKey.value = [];
proxy.$refs.treeSelect.blur();
selectFilterData('');
}
function selectFilterData(val) {
proxy.$refs.selectTree.filter(val)
proxy.$refs.selectTree.filter(val);
}
function filterNode(value, data) {
if (!value) return true
return data[props.objMap['label']].indexOf(value) !== -1
if (!value) return true;
return data[props.objMap['label']].indexOf(value) !== -1;
}
function clearHandle() {
valueTitle.value = ''
valueId.value = ''
defaultExpandedKey.value = [];
clearSelected()
valueTitle.value = '';
valueId.value = '';
defaultExpandedKey.value = [];
clearSelected();
}
function clearSelected() {
const allNode = document.querySelectorAll('#tree-option .el-tree-node')
allNode.forEach((element) => element.classList.remove('is-current'))
const allNode = document.querySelectorAll('#tree-option .el-tree-node');
allNode.forEach((element) => element.classList.remove('is-current'));
}
onMounted(() => {
initHandle()
})
initHandle();
});
watch(valueId, () => {
initHandle();
})
initHandle();
});
</script>
<style lang='scss' scoped>
@import "/@/assets/styles/variables.module.scss";
<style lang="scss" scoped>
@import '/@/assets/styles/variables.module.scss';
.el-scrollbar .el-scrollbar__view .el-select-dropdown__item {
padding: 0;
background-color: #fff;
height: auto;
padding: 0;
background-color: #fff;
height: auto;
}
.el-select-dropdown__item.selected {
font-weight: normal;
font-weight: normal;
}
ul li .el-tree .el-tree-node__content {
height: auto;
padding: 0 20px;
box-sizing: border-box;
height: auto;
padding: 0 20px;
box-sizing: border-box;
}
:deep(.el-tree-node__content:hover),
:deep(.el-tree-node__content:active),
:deep(.is-current > div:first-child),
:deep(.el-tree-node__content:focus) {
background-color: mix(#fff, $--color-primary, 90%);
color: $--color-primary;
background-color: mix(#fff, $--color-primary, 90%);
color: $--color-primary;
}
</style>

View File

@ -1,134 +1,137 @@
<!-- excel 导入组件 -->
<template>
<el-dialog :title="prop.title" v-model="state.upload.open" :close-on-click-modal="false" draggable>
<el-upload ref="uploadRef" :limit="1" accept=".xlsx, .xls" :headers="headers" :action="url"
:disabled="state.upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess"
:on-error="handleFileError" :auto-upload="false" drag>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
将文件拖到此处
<em>点击上传</em>
</div>
<template #tip>
<div class="el-upload__tip text-center">
<span>仅允许导入xlsxlsx格式文件</span>
<el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;"
@click="downExcelTemp" v-if="tempUrl">下载模板
</el-link>
</div>
</template>
</el-upload>
<template #footer>
<el-button type="primary" @click="submitFileForm"> </el-button>
<el-button @click="state.upload.open = false"> </el-button>
</template>
</el-dialog>
<el-dialog :title="prop.title" v-model="state.upload.open" :close-on-click-modal="false" draggable>
<el-upload
ref="uploadRef"
:limit="1"
accept=".xlsx, .xls"
:headers="headers"
:action="url"
:disabled="state.upload.isUploading"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
:on-error="handleFileError"
:auto-upload="false"
drag
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
将文件拖到此处
<em>点击上传</em>
</div>
<template #tip>
<div class="el-upload__tip text-center">
<span>仅允许导入xlsxlsx格式文件</span>
<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="downExcelTemp" v-if="tempUrl"
>下载模板
</el-link>
</div>
</template>
</el-upload>
<template #footer>
<el-button type="primary" @click="submitFileForm"> </el-button>
<el-button @click="state.upload.open = false"> </el-button>
</template>
</el-dialog>
<!--校验失败错误数据-->
<el-dialog title="校验失败数据" v-model="state.errorVisible">
<el-table :data="state.errorData">
<el-table-column property="lineNum" label="行号" width="100"></el-table-column>
<el-table-column property="errors" label="错误描述" show-overflow-tooltip>
<template v-slot="scope">
<el-tag type="danger" v-for="error in scope.row.errors" :key="error">{{ error }}
</el-tag>
</template>
</el-table-column>
</el-table>
</el-dialog>
<!--校验失败错误数据-->
<el-dialog title="校验失败数据" v-model="state.errorVisible">
<el-table :data="state.errorData">
<el-table-column property="lineNum" label="行号" width="100"></el-table-column>
<el-table-column property="errors" label="错误描述" show-overflow-tooltip>
<template v-slot="scope">
<el-tag type="danger" v-for="error in scope.row.errors" :key="error">{{ error }} </el-tag>
</template>
</el-table-column>
</el-table>
</el-dialog>
</template>
<script setup lang="ts" name="upload-excel">
import { Local } from "/@/utils/storage";
import { useMessage } from "/@/hooks/message";
import other from '/@/utils/other'
import { Local } from '/@/utils/storage';
import { useMessage } from '/@/hooks/message';
import other from '/@/utils/other';
import { Session } from '/@/utils/storage';
const emit = defineEmits(['sizeChange', 'refreshDataList'])
const emit = defineEmits(['sizeChange', 'refreshDataList']);
const prop = defineProps({
url: {
type: String
},
title: {
type: String
},
tempUrl: {
type: String
}
})
const uploadRef = ref()
url: {
type: String,
},
title: {
type: String,
},
tempUrl: {
type: String,
},
});
const uploadRef = ref();
const state = reactive({
errorVisible: false,
errorData: [],
dialog: {
title: '',
isShowDialog: false
},
upload: {
open: false,
isUploading: false
}
})
errorVisible: false,
errorData: [],
dialog: {
title: '',
isShowDialog: false,
},
upload: {
open: false,
isUploading: false,
},
});
const downExcelTemp = () => {
other.downBlobFile(prop.tempUrl, {}, "temp.xlsx");
}
other.downBlobFile(prop.tempUrl, {}, 'temp.xlsx');
};
const handleFileUploadProgress = () => {
state.upload.isUploading = true;
}
state.upload.isUploading = true;
};
const handleFileError = () => {
useMessage().error('上传失败,数据格式不合法!')
state.upload.open = false;
}
useMessage().error('上传失败,数据格式不合法!');
state.upload.open = false;
};
const handleFileSuccess = (response: any) => {
state.upload.isUploading = false;
state.upload.open = false;
uploadRef.value.clearFiles();
state.upload.isUploading = false;
state.upload.open = false;
uploadRef.value.clearFiles();
//
if (response.code === 1) {
useMessage().error("导入失败,以下数据不合法");
state.errorVisible = true;
state.errorData = response.data;
uploadRef.value.clearFiles();
//
emit("refreshDataList");
} else {
useMessage().success(response.msg ? response.msg : "导入成功");
//
emit("refreshDataList");
}
}
//
if (response.code === 1) {
useMessage().error('导入失败,以下数据不合法');
state.errorVisible = true;
state.errorData = response.data;
uploadRef.value.clearFiles();
//
emit('refreshDataList');
} else {
useMessage().success(response.msg ? response.msg : '导入成功');
//
emit('refreshDataList');
}
};
const submitFileForm = () => {
uploadRef.value.submit();
}
uploadRef.value.submit();
};
const show = () => {
state.upload.isUploading = false;
state.upload.open = true;
}
state.upload.isUploading = false;
state.upload.open = true;
};
const headers = computed(() => {
const tenantId = Local.get("tenantId") ? Local.get("tenantId") : 1
return {
'Authorization': "Bearer " + Session.get("token"),
'TENANT-ID': tenantId
};
})
const tenantId = Local.get('tenantId') ? Local.get('tenantId') : 1;
return {
Authorization: 'Bearer ' + Session.get('token'),
'TENANT-ID': tenantId,
};
});
//
defineExpose({
show,
show,
});
</script>
<style scoped>
</style>
<style scoped></style>

View File

@ -1,113 +1,122 @@
<!--图片上传组件-->
<template>
<div>
<el-upload ref="fileUpload" class="avatar-uploader" :action="props.uploadFileUrl" :show-file-list="false"
:on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload" :headers="headers" :limit="props.limit">
<slot>
<img v-if="imageUrl" :src="imageUrl" class="avatar" />
<el-icon v-else class="avatar-uploader-icon">
<Plus />
</el-icon>
</slot>
</el-upload>
</div>
<div>
<el-upload
ref="fileUpload"
class="avatar-uploader"
:action="props.uploadFileUrl"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
:headers="headers"
:limit="props.limit"
>
<slot>
<img v-if="imageUrl" :src="imageUrl" class="avatar" />
<el-icon v-else class="avatar-uploader-icon">
<Plus />
</el-icon>
</slot>
</el-upload>
</div>
</template>
<script setup lang="ts" name="upload-image">
import { useMessage } from '/@/hooks/message';
import { Local, Session } from '/@/utils/storage';
import { watch } from 'vue';
import { useMessage } from "/@/hooks/message";
import { Local, Session } from "/@/utils/storage";
import { watch } from "vue";
const imageUrl = ref('')
const fileUpload = ref()
const imageUrl = ref('');
const fileUpload = ref();
const emit = defineEmits(['update:modelValue', 'change']);
const props = defineProps({
modelValue: [String, Array],
// (MB)
fileSize: {
type: Number,
default: 5,
},
limit: {
type: Number,
default: 1,
},
uploadFileUrl: {
type: String,
default: '/admin/sys-file/upload'
}
modelValue: [String, Array],
// (MB)
fileSize: {
type: Number,
default: 5,
},
limit: {
type: Number,
default: 1,
},
uploadFileUrl: {
type: String,
default: '/admin/sys-file/upload',
},
});
watch(() => props.modelValue, (val) => {
if (val) {
imageUrl.value = val
}
}, { deep: true, immediate: true })
watch(
() => props.modelValue,
(val) => {
if (val) {
imageUrl.value = val;
}
},
{ deep: true, immediate: true }
);
const handleAvatarSuccess = (res, file) => {
if (res.code === 0) {
imageUrl.value = res.data.url
emit("change", imageUrl.value);
emit("update:modelValue", imageUrl.value);
} else {
fileUpload.value.handleRemove(file);
}
}
if (res.code === 0) {
imageUrl.value = res.data.url;
emit('change', imageUrl.value);
emit('update:modelValue', imageUrl.value);
} else {
fileUpload.value.handleRemove(file);
}
};
const beforeAvatarUpload = (rawFile: any) => {
if (rawFile.type !== 'image/jpeg' && rawFile.type !== 'image/png') {
useMessage().error(`文件格式不正确, 请上传 jpeg/png格式文件!`)
return false
}
//
if (props.fileSize) {
const isLt = rawFile.size / 1024 / 1024 < props.fileSize;
if (!isLt) {
useMessage().error(`上传文件大小不能超过 ${props.fileSize} MB!`)
return false;
}
}
return true
}
if (rawFile.type !== 'image/jpeg' && rawFile.type !== 'image/png') {
useMessage().error(`文件格式不正确, 请上传 jpeg/png格式文件!`);
return false;
}
//
if (props.fileSize) {
const isLt = rawFile.size / 1024 / 1024 < props.fileSize;
if (!isLt) {
useMessage().error(`上传文件大小不能超过 ${props.fileSize} MB!`);
return false;
}
}
return true;
};
const headers = computed(() => {
const tenantId = Local.get("tenantId") ? Local.get("tenantId") : 1
return {
'Authorization': "Bearer " + Session.get("token"),
'TENANT-ID': tenantId
};
})
const tenantId = Local.get('tenantId') ? Local.get('tenantId') : 1;
return {
Authorization: 'Bearer ' + Session.get('token'),
'TENANT-ID': tenantId,
};
});
</script>
<style scoped>
.avatar-uploader .el-upload {
border: 1px dashed var(--el-border-color);
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
transition: var(--el-transition-duration-fast);
border: 1px dashed var(--el-border-color);
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
transition: var(--el-transition-duration-fast);
}
.avatar-uploader .el-upload:hover {
border-color: var(--el-color-primary);
border-color: var(--el-color-primary);
}
.el-icon.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
text-align: center;
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 100%;
width: 178px;
height: 100%;
}
</style>

View File

@ -1,208 +1,220 @@
<!--文件上传组件-->
<template>
<div class="upload-file">
<el-upload ref="fileUpload"
v-if="props.type === 'default'"
:action="props.uploadFileUrl"
:before-upload="handleBeforeUpload"
:file-list="fileList"
:headers="headers"
:limit="limit"
:on-error="handleUploadError"
:on-remove="handleRemove"
:data="data"
:auto-upload="autoUpload"
:on-success="handleUploadSuccess" class="upload-file-uploader" drag multiple>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
将文件拖到此处
<em>点击上传</em>
</div>
<template #tip>
<div class="el-upload__tip" v-if="props.isShowTip">
请上传
<template v-if="props.fileSize"> 大小不超过 <b style="color: #f56c6c">{{ props.fileSize }}MB</b></template>
<template v-if="props.fileType"> 格式为 <b style="color: #f56c6c">{{ props.fileType.join("/") }}</b>
</template>
的文件
</div>
</template>
</el-upload>
<el-upload ref="fileUpload"
v-if="props.type === 'simple'"
:action="props.uploadFileUrl"
:before-upload="handleBeforeUpload"
:file-list="fileList"
:headers="headers"
:limit="limit"
:auto-upload="autoUpload"
:on-error="handleUploadError"
:on-remove="handleRemove"
:data="data"
:on-success="handleUploadSuccess" class="upload-file-uploader" multiple>
<el-button type="primary" link>点击上传</el-button>
</el-upload>
</div>
<div class="upload-file">
<el-upload
ref="fileUpload"
v-if="props.type === 'default'"
:action="props.uploadFileUrl"
:before-upload="handleBeforeUpload"
:file-list="fileList"
:headers="headers"
:limit="limit"
:on-error="handleUploadError"
:on-remove="handleRemove"
:data="data"
:auto-upload="autoUpload"
:on-success="handleUploadSuccess"
class="upload-file-uploader"
drag
multiple
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
将文件拖到此处
<em>点击上传</em>
</div>
<template #tip>
<div class="el-upload__tip" v-if="props.isShowTip">
请上传
<template v-if="props.fileSize">
大小不超过 <b style="color: #f56c6c">{{ props.fileSize }}MB</b></template
>
<template v-if="props.fileType">
格式为 <b style="color: #f56c6c">{{ props.fileType.join('/') }}</b>
</template>
的文件
</div>
</template>
</el-upload>
<el-upload
ref="fileUpload"
v-if="props.type === 'simple'"
:action="props.uploadFileUrl"
:before-upload="handleBeforeUpload"
:file-list="fileList"
:headers="headers"
:limit="limit"
:auto-upload="autoUpload"
:on-error="handleUploadError"
:on-remove="handleRemove"
:data="data"
:on-success="handleUploadSuccess"
class="upload-file-uploader"
multiple
>
<el-button type="primary" link>点击上传</el-button>
</el-upload>
</div>
</template>
<script setup lang="ts" name="upload-file">
import {useMessage} from "/@/hooks/message";
import {Local, Session} from "/@/utils/storage";
import { useMessage } from '/@/hooks/message';
import { Local, Session } from '/@/utils/storage';
const props = defineProps({
modelValue: [String, Array],
//
limit: {
type: Number,
default: 5,
},
// (MB)
fileSize: {
type: Number,
default: 5,
},
fileType: {
type: Array,
default: () => ['png', 'jpg', 'jpeg', "doc", "xls", "ppt", "txt", "pdf", "docx", "xlsx", "pptx"],
},
//
isShowTip: {
type: Boolean,
default: true
},
uploadFileUrl: {
type: String,
default: '/admin/sys-file/upload'
},
type: {
type: String,
default: 'default',
validator:(value: string) => {
return ['default','simple'].includes(value)
}
},
data: {
type: Object
},
autoUpload: {
type: Boolean,
default: true
}
modelValue: [String, Array],
//
limit: {
type: Number,
default: 5,
},
// (MB)
fileSize: {
type: Number,
default: 5,
},
fileType: {
type: Array,
default: () => ['png', 'jpg', 'jpeg', 'doc', 'xls', 'ppt', 'txt', 'pdf', 'docx', 'xlsx', 'pptx'],
},
//
isShowTip: {
type: Boolean,
default: true,
},
uploadFileUrl: {
type: String,
default: '/admin/sys-file/upload',
},
type: {
type: String,
default: 'default',
validator: (value: string) => {
return ['default', 'simple'].includes(value);
},
},
data: {
type: Object,
},
autoUpload: {
type: Boolean,
default: true,
},
});
const emit = defineEmits(['update:modelValue', 'change']);
const number = ref(0)
const fileList = ref([]) as any
const uploadList = ref([]) as any
const fileUpload = ref()
const number = ref(0);
const fileList = ref([]) as any;
const uploadList = ref([]) as any;
const fileUpload = ref();
const headers = computed(() => {
const tenantId = Local.get("tenantId") ? Local.get("tenantId") : 1
return {
'Authorization': "Bearer " + Session.get("token"),
'TENANT-ID': tenantId
};
})
const tenantId = Local.get('tenantId') ? Local.get('tenantId') : 1;
return {
Authorization: 'Bearer ' + Session.get('token'),
'TENANT-ID': tenantId,
};
});
//
const handleBeforeUpload = (file: File) => {
//
if (props.fileType.length) {
const fileName = file.name.split('.');
const fileExt = fileName[fileName.length - 1];
const isTypeOk = props.fileType.indexOf(fileExt) >= 0;
if (!isTypeOk) {
useMessage().error(`文件格式不正确, 请上传${props.fileType.join("/")}格式文件!`)
return false;
}
}
//
if (props.fileSize) {
const isLt = file.size / 1024 / 1024 < props.fileSize;
if (!isLt) {
useMessage().error(`上传文件大小不能超过 ${props.fileSize} MB!`)
return false;
}
}
number.value++;
return true;
}
//
if (props.fileType.length) {
const fileName = file.name.split('.');
const fileExt = fileName[fileName.length - 1];
const isTypeOk = props.fileType.indexOf(fileExt) >= 0;
if (!isTypeOk) {
useMessage().error(`文件格式不正确, 请上传${props.fileType.join('/')}格式文件!`);
return false;
}
}
//
if (props.fileSize) {
const isLt = file.size / 1024 / 1024 < props.fileSize;
if (!isLt) {
useMessage().error(`上传文件大小不能超过 ${props.fileSize} MB!`);
return false;
}
}
number.value++;
return true;
};
//
function handleUploadSuccess(res: any, file: any) {
if (res.code === 0) {
uploadList.value.push({ name: res.data.fileName, url: res.data.url });
uploadedSuccessfully();
} else {
number.value--;
useMessage().error(res.msg);
fileUpload.value.handleRemove(file);
uploadedSuccessfully();
}
if (res.code === 0) {
uploadList.value.push({ name: res.data.fileName, url: res.data.url });
uploadedSuccessfully();
} else {
number.value--;
useMessage().error(res.msg);
fileUpload.value.handleRemove(file);
uploadedSuccessfully();
}
}
//
const uploadedSuccessfully = () => {
if (number.value > 0 && uploadList.value.length === number.value) {
fileList.value = fileList.value.filter(f => f.url !== undefined).concat(uploadList.value);
uploadList.value = [];
number.value = 0;
emit("change", listToString(fileList.value));
emit("update:modelValue", listToString(fileList.value));
}
}
if (number.value > 0 && uploadList.value.length === number.value) {
fileList.value = fileList.value.filter((f) => f.url !== undefined).concat(uploadList.value);
uploadList.value = [];
number.value = 0;
emit('change', listToString(fileList.value));
emit('update:modelValue', listToString(fileList.value));
}
};
const handleRemove = (file: any) => {
fileList.value = fileList.value.filter(f => !(f === file.url))
emit("change", listToString(fileList.value));
emit("update:modelValue", listToString(fileList.value));
}
fileList.value = fileList.value.filter((f) => !(f === file.url));
emit('change', listToString(fileList.value));
emit('update:modelValue', listToString(fileList.value));
};
//
const listToString = (list, separator = ',') => {
let strs = "";
separator = separator || ",";
for (let i in list) {
if (list[i].url) {
strs += list[i].url + separator;
}
}
return strs != '' ? strs.substr(0, strs.length - 1) : '';
}
let strs = '';
separator = separator || ',';
for (let i in list) {
if (list[i].url) {
strs += list[i].url + separator;
}
}
return strs != '' ? strs.substr(0, strs.length - 1) : '';
};
const handleUploadError = () => {
useMessage().error("上传文件失败")
}
watch(() => props.modelValue, val => {
if (val) {
let temp = 1;
//
const list = Array.isArray(val) ? val : props?.modelValue?.split(',');
//
fileList.value = list.map(item => {
if (typeof item === "string") {
item = { name: item, url: item };
}
item.uid = item.uid || new Date().getTime() + temp++;
return item;
});
} else {
fileList.value = [];
return [];
}
}, { deep: true, immediate: true });
useMessage().error('上传文件失败');
};
watch(
() => props.modelValue,
(val) => {
if (val) {
let temp = 1;
//
const list = Array.isArray(val) ? val : props?.modelValue?.split(',');
//
fileList.value = list.map((item) => {
if (typeof item === 'string') {
item = { name: item, url: item };
}
item.uid = item.uid || new Date().getTime() + temp++;
return item;
});
} else {
fileList.value = [];
return [];
}
},
{ deep: true, immediate: true }
);
const submit = () => {
fileUpload.value.submit()
}
fileUpload.value.submit();
};
defineExpose({
submit
})
submit,
});
</script>

View File

@ -1,159 +1,157 @@
<template>
<div></div>
<div></div>
</template>
<script setup lang="ts" name="global-websocket">
import { ElNotification } from 'element-plus'
import { Local, Session } from '/@/utils/storage'
import { ElNotification } from 'element-plus';
import { Local, Session } from '/@/utils/storage';
const emit = defineEmits(['rollback'])
const emit = defineEmits(['rollback']);
const props = defineProps({
uri: {
type: String
}
})
uri: {
type: String,
},
});
const state = reactive({
webSocket: ref(), // webSocket
lockReconnect: false, //
maxReconnect: 6, // -1
reconnectTime: 0, //
heartbeat: {
interval: 30 * 1000, //
timeout: 10 * 1000, //
pingTimeoutObj: ref(), //
pongTimeoutObj: ref(), //
pingMessage: JSON.stringify({ type: 'ping' }) //
}
})
webSocket: ref(), // webSocket
lockReconnect: false, //
maxReconnect: 6, // -1
reconnectTime: 0, //
heartbeat: {
interval: 30 * 1000, //
timeout: 10 * 1000, //
pingTimeoutObj: ref(), //
pongTimeoutObj: ref(), //
pingMessage: JSON.stringify({ type: 'ping' }), //
},
});
const token = computed(() => {
return Session.get("token")
})
return Session.get('token');
});
const tenant = computed(() => {
return Local.get("tenantId") ? Local.get("tenantId") : 1
})
return Local.get('tenantId') ? Local.get('tenantId') : 1;
});
onMounted(() => {
initWebSocket()
})
initWebSocket();
});
onUnmounted(() => {
state.webSocket.close()
clearTimeoutObj(state.heartbeat)
})
state.webSocket.close();
clearTimeoutObj(state.heartbeat);
});
const initWebSocket = () => {
// ws
let host = window.location.host;
let wsUri = `ws://${host}${props.uri}?access_token=${token.value}&TENANT-ID=${tenant}`
//
state.webSocket = new WebSocket(wsUri)
//
state.webSocket.onopen = onOpen
//
state.webSocket.onerror = onError
//
state.webSocket.onmessage = onMessage
//
state.webSocket.onclose = onClose
}
// ws
let host = window.location.host;
let wsUri = `ws://${host}${props.uri}?access_token=${token.value}&TENANT-ID=${tenant}`;
//
state.webSocket = new WebSocket(wsUri);
//
state.webSocket.onopen = onOpen;
//
state.webSocket.onerror = onError;
//
state.webSocket.onmessage = onMessage;
//
state.webSocket.onclose = onClose;
};
const reconnect = () => {
if (!token) {
return
}
if (state.lockReconnect || (state.maxReconnect !== -1 && state.reconnectTime > state.maxReconnect)) {
return
}
state.lockReconnect = true
setTimeout(() => {
state.reconnectTime++
//
initWebSocket()
state.lockReconnect = false
}, 5000)
}
if (!token) {
return;
}
if (state.lockReconnect || (state.maxReconnect !== -1 && state.reconnectTime > state.maxReconnect)) {
return;
}
state.lockReconnect = true;
setTimeout(() => {
state.reconnectTime++;
//
initWebSocket();
state.lockReconnect = false;
}, 5000);
};
/**
* 清空定时器
*/
const clearTimeoutObj = (heartbeat: any) => {
heartbeat.pingTimeoutObj && clearTimeout(heartbeat.pingTimeoutObj)
heartbeat.pongTimeoutObj && clearTimeout(heartbeat.pongTimeoutObj)
}
heartbeat.pingTimeoutObj && clearTimeout(heartbeat.pingTimeoutObj);
heartbeat.pongTimeoutObj && clearTimeout(heartbeat.pongTimeoutObj);
};
/**
* 开启心跳
*/
const startHeartbeat = () => {
const webSocket = state.webSocket
const heartbeat = state.heartbeat
//
clearTimeoutObj(heartbeat)
//
heartbeat.pingTimeoutObj = setTimeout(() => {
//
if (webSocket.readyState === 1) {
//
webSocket.send(heartbeat.pingMessage)
//
heartbeat.pongTimeoutObj = setTimeout(() => {
webSocket.close()
}, heartbeat.timeout)
} else {
//
reconnect()
}
}, heartbeat.interval)
}
const webSocket = state.webSocket;
const heartbeat = state.heartbeat;
//
clearTimeoutObj(heartbeat);
//
heartbeat.pingTimeoutObj = setTimeout(() => {
//
if (webSocket.readyState === 1) {
//
webSocket.send(heartbeat.pingMessage);
//
heartbeat.pongTimeoutObj = setTimeout(() => {
webSocket.close();
}, heartbeat.timeout);
} else {
//
reconnect();
}
}, heartbeat.interval);
};
/**
* 连接成功事件
*/
const onOpen = () => {
//
startHeartbeat()
state.reconnectTime = 0
}
//
startHeartbeat();
state.reconnectTime = 0;
};
/**
* 连接失败事件
* @param e
*/
const onError = () => {
//
reconnect()
}
//
reconnect();
};
/**
* 连接关闭事件
* @param e
*/
const onClose = () => {
//
reconnect()
}
//
reconnect();
};
/**
* 接收服务器推送的信息
* @param msgEvent
*/
const onMessage = (msgEvent: any) => {
//
startHeartbeat()
const text = msgEvent.data
//
startHeartbeat();
const text = msgEvent.data;
if (text.indexOf('pong') > 0) {
return
}
if (text.indexOf('pong') > 0) {
return;
}
ElNotification.warning({
title: '消息提醒',
dangerouslyUseHTMLString: true,
message: text + '请及时处理',
offset: 60
})
ElNotification.warning({
title: '消息提醒',
dangerouslyUseHTMLString: true,
message: text + '请及时处理',
offset: 60,
});
emit('rollback', text)
}
emit('rollback', text);
};
</script>

File diff suppressed because it is too large Load Diff

View File

@ -1,54 +1,54 @@
export default {
Seconds:{
name:'秒',
every:'每一秒钟',
interval:['每隔','秒执行 从','秒开始'],
specific:'具体秒数(可多选)',
cycle:['周期从','到','秒']
},
Minutes:{
name:'分',
every:'每一分钟',
interval:['每隔','分执行 从','分开始'],
specific:'具体分钟数(可多选)',
cycle:['周期从','到','分']
},
Hours:{
name:'时',
every:'每一小时',
interval:['每隔','小时执行 从','小时开始'],
specific:'具体小时数(可多选)',
cycle:['周期从','到','小时']
},
Day:{
name:'天',
every:'每一天',
intervalWeek:['每隔','周执行 从','开始'],
intervalDay:['每隔','天执行 从','天开始'],
specificWeek:'具体星期几(可多选)',
specificDay:'具体天数(可多选)',
lastDay:'在这个月的最后一天',
lastWeekday:'在这个月的最后一个工作日',
lastWeek:['在这个月的最后一个'],
beforeEndMonth:['在本月底前','天'],
nearestWeekday:['最近的工作日(周一至周五)至本月','日'],
someWeekday:['在这个月的第','个'],
},
Week:['天','一','二','三','四','五','六'].map(val=>'星期'+val),
Month:{
name:'月',
every:'每一月',
interval:['每隔','月执行 从','月开始'],
specific:'具体月数(可多选)',
cycle:['从','到','月之间的每个月']
},
Year:{
name:'年',
every:'每一年',
interval:['每隔','年执行 从','年开始'],
specific:'具体年份(可多选)',
cycle:['从','到','年之间的每一年']
},
Save:'保存',
Close:'关闭'
}
Seconds: {
name: '秒',
every: '每一秒钟',
interval: ['每隔', '秒执行 从', '秒开始'],
specific: '具体秒数(可多选)',
cycle: ['周期从', '到', '秒'],
},
Minutes: {
name: '分',
every: '每一分钟',
interval: ['每隔', '分执行 从', '分开始'],
specific: '具体分钟数(可多选)',
cycle: ['周期从', '到', '分'],
},
Hours: {
name: '时',
every: '每一小时',
interval: ['每隔', '小时执行 从', '小时开始'],
specific: '具体小时数(可多选)',
cycle: ['周期从', '到', '小时'],
},
Day: {
name: '天',
every: '每一天',
intervalWeek: ['每隔', '周执行 从', '开始'],
intervalDay: ['每隔', '天执行 从', '天开始'],
specificWeek: '具体星期几(可多选)',
specificDay: '具体天数(可多选)',
lastDay: '在这个月的最后一天',
lastWeekday: '在这个月的最后一个工作日',
lastWeek: ['在这个月的最后一个'],
beforeEndMonth: ['在本月底前', '天'],
nearestWeekday: ['最近的工作日(周一至周五)至本月', '日'],
someWeekday: ['在这个月的第', '个'],
},
Week: ['天', '一', '二', '三', '四', '五', '六'].map((val) => '星期' + val),
Month: {
name: '月',
every: '每一月',
interval: ['每隔', '月执行 从', '月开始'],
specific: '具体月数(可多选)',
cycle: ['从', '到', '月之间的每个月'],
},
Year: {
name: '年',
every: '每一年',
interval: ['每隔', '年执行 从', '年开始'],
specific: '具体年份(可多选)',
cycle: ['从', '到', '年之间的每一年'],
},
Save: '保存',
Close: '关闭',
};

View File

@ -1,54 +1,54 @@
export default {
Seconds:{
name:'Seconds',
every:'Every second',
interval:['Every','second(s) starting at second'],
specific:'Specific second (choose one or many)',
cycle:['Every second between second','and second']
},
Minutes:{
name:'Minutes',
every:'Every minute',
interval:['Every','minute(s) starting at minute'],
specific:'Specific minute (choose one or many)',
cycle:['Every minute between minute','and minute']
},
Hours:{
name:'Hours',
every:'Every hour',
interval:['Every','hour(s) starting at hour'],
specific:'Specific hour (choose one or many)',
cycle:['Every hour between hour','and hour']
},
Day:{
name:'Day',
every:'Every day',
intervalWeek:['Every','day(s) starting on'],
intervalDay:['Every','day(s) starting at the','of the month'],
specificWeek:'Specific day of week (choose one or many)',
specificDay:'Specific day of month (choose one or many)',
lastDay:'On the last day of the month',
lastWeekday:'On the last weekday of the month',
lastWeek:['On the last',' of the month'],
beforeEndMonth:['day(s) before the end of the month'],
nearestWeekday:['Nearest weekday (Monday to Friday) to the','of the month'],
someWeekday:['On the','of the month'],
},
Week:['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
Month:{
name:'Month',
every:'Every month',
interval:['Every','month(s) starting in'],
specific:'Specific month (choose one or many)',
cycle:['Every month between','and']
},
Year:{
name:'Year',
every:'Any year',
interval:['Every','year(s) starting in'],
specific:'Specific year (choose one or many)',
cycle:['Every year between','and']
},
Save:'Save',
Close:'Close'
}
Seconds: {
name: 'Seconds',
every: 'Every second',
interval: ['Every', 'second(s) starting at second'],
specific: 'Specific second (choose one or many)',
cycle: ['Every second between second', 'and second'],
},
Minutes: {
name: 'Minutes',
every: 'Every minute',
interval: ['Every', 'minute(s) starting at minute'],
specific: 'Specific minute (choose one or many)',
cycle: ['Every minute between minute', 'and minute'],
},
Hours: {
name: 'Hours',
every: 'Every hour',
interval: ['Every', 'hour(s) starting at hour'],
specific: 'Specific hour (choose one or many)',
cycle: ['Every hour between hour', 'and hour'],
},
Day: {
name: 'Day',
every: 'Every day',
intervalWeek: ['Every', 'day(s) starting on'],
intervalDay: ['Every', 'day(s) starting at the', 'of the month'],
specificWeek: 'Specific day of week (choose one or many)',
specificDay: 'Specific day of month (choose one or many)',
lastDay: 'On the last day of the month',
lastWeekday: 'On the last weekday of the month',
lastWeek: ['On the last', ' of the month'],
beforeEndMonth: ['day(s) before the end of the month'],
nearestWeekday: ['Nearest weekday (Monday to Friday) to the', 'of the month'],
someWeekday: ['On the', 'of the month'],
},
Week: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
Month: {
name: 'Month',
every: 'Every month',
interval: ['Every', 'month(s) starting in'],
specific: 'Specific month (choose one or many)',
cycle: ['Every month between', 'and'],
},
Year: {
name: 'Year',
every: 'Any year',
interval: ['Every', 'year(s) starting in'],
specific: 'Specific year (choose one or many)',
cycle: ['Every year between', 'and'],
},
Save: 'Save',
Close: 'Close',
};

View File

@ -1,9 +1,9 @@
import en from './en'
import cn from './cn'
import pt from './pt_br'
import en from './en';
import cn from './cn';
import pt from './pt_br';
export default {
en,
cn,
pt
}
en,
cn,
pt,
};

View File

@ -1,54 +1,54 @@
export default {
Seconds:{
name:'Segundos',
every:'A cada segundo',
interval:['A cada','segundo(s) começando no segundo'],
specific:'Segundo específico (escolha um ou muitos)',
cycle:['A Cada segundo entre segundos','e segundo']
},
Minutes:{
name:'Minutos',
every:'A cada minuto',
interval:['A cada','minuto(s) começando no minuto'],
specific:'Minuto específico (escolha um ou muitos)',
cycle:['A cada minuto entre minutos','e minutos']
},
Hours:{
name:'Horas',
every:'A cada hora',
interval:['A cada','hora(s) começando na hora'],
specific:'Hora específica (escolha uma ou muitas)',
cycle:['A cada hora entre horas','e horas']
},
Day:{
name:'Dia',
every:'A cada dia',
intervalWeek:['A cada','dia(s) começando em'],
intervalDay:['A cada','dia(s) começando no','do mês'],
specificWeek:'Dia específico da semana (escolha um ou vários)',
specificDay:'Dia específico do mês (escolha um ou vários)',
lastDay:'No último dia do mês',
lastWeekday:'No último dia da semana do mês',
lastWeek:['No último',' do mês'],
beforeEndMonth:['dia(s) antes do final do mês'],
nearestWeekday:['Dia da semana mais próximo (segunda a sexta) ao ','do mês'],
someWeekday:['No','do mês'],
},
Week:['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'],
Month:{
name:'Mês',
every:'A cada mês',
interval:['A cada','mês(es) começando em'],
specific:'Mês específico (escolha um ou muitos)',
cycle:['Todo mês entre','e']
},
Year:{
name:'Ano',
every:'Qualquer ano',
interval:['A cada','ano(s) começando em'],
specific:'Ano específico (escolha um ou muitos)',
cycle:['Todo ano entre','e']
},
Save:'Salvar',
Close:'Fechar'
}
Seconds: {
name: 'Segundos',
every: 'A cada segundo',
interval: ['A cada', 'segundo(s) começando no segundo'],
specific: 'Segundo específico (escolha um ou muitos)',
cycle: ['A Cada segundo entre segundos', 'e segundo'],
},
Minutes: {
name: 'Minutos',
every: 'A cada minuto',
interval: ['A cada', 'minuto(s) começando no minuto'],
specific: 'Minuto específico (escolha um ou muitos)',
cycle: ['A cada minuto entre minutos', 'e minutos'],
},
Hours: {
name: 'Horas',
every: 'A cada hora',
interval: ['A cada', 'hora(s) começando na hora'],
specific: 'Hora específica (escolha uma ou muitas)',
cycle: ['A cada hora entre horas', 'e horas'],
},
Day: {
name: 'Dia',
every: 'A cada dia',
intervalWeek: ['A cada', 'dia(s) começando em'],
intervalDay: ['A cada', 'dia(s) começando no', 'do mês'],
specificWeek: 'Dia específico da semana (escolha um ou vários)',
specificDay: 'Dia específico do mês (escolha um ou vários)',
lastDay: 'No último dia do mês',
lastWeekday: 'No último dia da semana do mês',
lastWeek: ['No último', ' do mês'],
beforeEndMonth: ['dia(s) antes do final do mês'],
nearestWeekday: ['Dia da semana mais próximo (segunda a sexta) ao ', 'do mês'],
someWeekday: ['No', 'do mês'],
},
Week: ['Domingo', 'Segunda-feira', 'Terça-feira', 'Quarta-feira', 'Quinta-feira', 'Sexta-feira', 'Sábado'],
Month: {
name: 'Mês',
every: 'A cada mês',
interval: ['A cada', 'mês(es) começando em'],
specific: 'Mês específico (escolha um ou muitos)',
cycle: ['Todo mês entre', 'e'],
},
Year: {
name: 'Ano',
every: 'Qualquer ano',
interval: ['A cada', 'ano(s) começando em'],
specific: 'Ano específico (escolha um ou muitos)',
cycle: ['Todo ano entre', 'e'],
},
Save: 'Salvar',
Close: 'Fechar',
};

View File

@ -23,8 +23,8 @@
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="onCancel" > </el-button>
<el-button type="primary" @click="onSubmit" > </el-button>
<el-button @click="onCancel"> </el-button>
<el-button type="primary" @click="onSubmit"> </el-button>
</span>
</template>
</el-dialog>

View File

@ -59,8 +59,8 @@ export const svgBuilder = (path: string, perfix = 'local') => {
`
<body>
<svg id="local-icon" data-icon-name="${iconNames.join(
','
)}" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0">
','
)}" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0">
${res.join('')}
</svg>
`

View File

@ -12,10 +12,7 @@
@blur="onIconBlur"
>
<template #prepend>
<SvgIcon
:name="state.fontIconPrefix === '' ? prepend : state.fontIconPrefix"
class="font14"
/>
<SvgIcon :name="state.fontIconPrefix === '' ? prepend : state.fontIconPrefix" class="font14" />
</template>
</el-input>
<el-popover
@ -40,9 +37,9 @@
<el-tab-pane lazy label="awe" name="awe">
<IconList :list="fontIconSheetsFilterList" :empty="emptyDescription" :prefix="state.fontIconPrefix" @get-icon="onColClick" />
</el-tab-pane>
<el-tab-pane lazy label="local" name="local">
<IconList :list="fontIconSheetsFilterList" :empty="emptyDescription" :prefix="state.fontIconPrefix" @get-icon="onColClick" />
</el-tab-pane>
<el-tab-pane lazy label="local" name="local">
<IconList :list="fontIconSheetsFilterList" :empty="emptyDescription" :prefix="state.fontIconPrefix" @get-icon="onColClick" />
</el-tab-pane>
</el-tabs>
</div>
</template>
@ -117,7 +114,7 @@ const state = reactive({
ali: [],
ele: [],
awe: [],
local: []
local: [],
},
});
@ -190,12 +187,12 @@ const initFontIconData = async (name: string) => {
await initIconfont.awe().then((res: any) => {
state.fontIconList.awe = res.map((i: string) => `fa ${i}`);
});
}else if(name === 'local'){
if (state.fontIconList.local.length > 0) return;
await initIconfont.local().then((res: any) => {
state.fontIconList.local = res.map((i: string) => `${i}`);
});
}
} else if (name === 'local') {
if (state.fontIconList.local.length > 0) return;
await initIconfont.local().then((res: any) => {
state.fontIconList.local = res.map((i: string) => `${i}`);
});
}
// input placeholder
// https://cn.vuejs.org/v2/guide/components-props.html?#%E5%8D%95%E5%90%91%E6%95%B0%E6%8D%AE%E6%B5%81
state.fontIconPlaceholder = props.placeholder;

View File

@ -1,18 +1,9 @@
import Pagination from '/@/components/Pagination/index.vue'
import RightToolbar from '/@/components/RightToolbar/index.vue'
import DictTag from '/@/components/DictTag/index.vue'
import UploadExcel from '/@/components/Upload/Excel.vue'
import UploadFile from '/@/components/Upload/index.vue'
import UploadImg from '/@/components/Upload/Image.vue'
import Editor from '/@/components/Editor/index.vue'
import Pagination from '/@/components/Pagination/index.vue';
import RightToolbar from '/@/components/RightToolbar/index.vue';
import DictTag from '/@/components/DictTag/index.vue';
import UploadExcel from '/@/components/Upload/Excel.vue';
import UploadFile from '/@/components/Upload/index.vue';
import UploadImg from '/@/components/Upload/Image.vue';
import Editor from '/@/components/Editor/index.vue';
export {
Pagination,
RightToolbar,
DictTag,
UploadExcel,
UploadFile,
UploadImg,
Editor
}
export { Pagination, RightToolbar, DictTag, UploadExcel, UploadFile, UploadImg, Editor };

View File

@ -5,11 +5,10 @@
<div v-else-if="isShowIconImg" :style="setIconImgOutStyle">
<img :src="getIconName" :style="setIconSvgInsStyle" />
</div>
<svg v-else-if="isShowLocalSvg" class="svg-icon icon" :style="setIconImgOutStyle">
<use :href="`#${getIconName}`" />
</svg>
<svg v-else-if="isShowLocalSvg" class="svg-icon icon" :style="setIconImgOutStyle">
<use :href="`#${getIconName}`" />
</svg>
<i v-else :class="getIconName" :style="setIconSvgStyle" />
</template>
<script setup lang="ts" name="svgIcon">
@ -49,8 +48,8 @@ const isShowIconImg = computed(() => {
});
const isShowLocalSvg = computed(() => {
return props?.name?.startsWith('local-');
})
return props?.name?.startsWith('local-');
});
//
const setIconSvgStyle = computed(() => {
return `font-size: ${props.size}px;color: ${props.color};`;

View File

@ -1,10 +1,10 @@
import * as components from '@element-plus/icons-vue'
import * as components from '@element-plus/icons-vue';
import type { App } from 'vue';
export default {
install: (app: App) => {
for (const key in components) {
const componentConfig = components[key];
app.component(componentConfig.name, componentConfig);
}
},
install: (app: App) => {
for (const key in components) {
const componentConfig = components[key];
app.component(componentConfig.name, componentConfig);
}
},
};

File diff suppressed because one or more lines are too long

View File

@ -1,262 +1,274 @@
<template>
<div style="position: relative"
>
<div class="verify-img-out">
<div class="verify-img-panel" :style="{'width': setSize.imgWidth,
'height': setSize.imgHeight,
'background-size' : setSize.imgWidth + ' '+ setSize.imgHeight,
'margin-bottom': vSpace + 'px'}"
>
<div class="verify-refresh" style="z-index:3" @click="refresh" v-show="showRefresh">
<i class="iconfont icon-refresh"></i>
</div>
<img :src="'data:image/png;base64,'+pointBackImgBase"
ref="canvas"
alt="" style="width:100%;height:100%;display:block"
@click="bindingClick?canvasClick($event):undefined">
<div style="position: relative">
<div class="verify-img-out">
<div
class="verify-img-panel"
:style="{
width: setSize.imgWidth,
height: setSize.imgHeight,
'background-size': setSize.imgWidth + ' ' + setSize.imgHeight,
'margin-bottom': vSpace + 'px',
}"
>
<div class="verify-refresh" style="z-index: 3" @click="refresh" v-show="showRefresh">
<i class="iconfont icon-refresh"></i>
</div>
<img
:src="'data:image/png;base64,' + pointBackImgBase"
ref="canvas"
alt=""
style="width: 100%; height: 100%; display: block"
@click="bindingClick ? canvasClick($event) : undefined"
/>
<div v-for="(tempPoint, index) in tempPoints" :key="index" class="point-area"
:style="{
'background-color':'#1abd6c',
color:'#fff',
'z-index':9999,
width:'20px',
height:'20px',
'text-align':'center',
'line-height':'20px',
'border-radius': '50%',
position:'absolute',
top:parseInt(tempPoint.y-10) + 'px',
left:parseInt(tempPoint.x-10) + 'px'
}">
{{index + 1}}
</div>
</div>
</div>
<!-- 'height': this.barSize.height, -->
<div class="verify-bar-area"
:style="{'width': setSize.imgWidth,
'color': this.barAreaColor,
'border-color': this.barAreaBorderColor,
'line-height':this.barSize.height}">
<span class="verify-msg">{{text}}</span>
</div>
</div>
<div
v-for="(tempPoint, index) in tempPoints"
:key="index"
class="point-area"
:style="{
'background-color': '#1abd6c',
color: '#fff',
'z-index': 9999,
width: '20px',
height: '20px',
'text-align': 'center',
'line-height': '20px',
'border-radius': '50%',
position: 'absolute',
top: parseInt(tempPoint.y - 10) + 'px',
left: parseInt(tempPoint.x - 10) + 'px',
}"
>
{{ index + 1 }}
</div>
</div>
</div>
<!-- 'height': this.barSize.height, -->
<div
class="verify-bar-area"
:style="{ width: setSize.imgWidth, color: this.barAreaColor, 'border-color': this.barAreaBorderColor, 'line-height': this.barSize.height }"
>
<span class="verify-msg">{{ text }}</span>
</div>
</div>
</template>
<script type="text/babel">
/**
* VerifyPoints
* @description 点选
* */
import {resetSize} from './../utils/util'
import {aesEncrypt} from "./../utils/ase"
import {reqGet,reqCheck} from "./../api/index"
import { onMounted, reactive, ref,nextTick,toRefs, getCurrentInstance} from 'vue';
export default {
name: 'VerifyPoints',
props: {
//popfixed
mode: {
type: String,
default: 'fixed'
},
captchaType:{
type:String,
},
//
vSpace: {
type: Number,
default: 5
},
imgSize: {
type: Object,
default() {
return {
width: '310px',
height: '155px'
}
}
},
barSize: {
type: Object,
default() {
return {
width: '310px',
height: '40px'
}
}
}
},
setup(props){
const {mode,captchaType} = toRefs(props)
const { proxy } = getCurrentInstance();
let secretKey = ref(''), //ase
checkNum = ref(3), //
fontPos = reactive([]), //
checkPosArr = reactive([]), //
num = ref(1), //
pointBackImgBase = ref(''), //
poinTextList = reactive([]), //
backToken = ref(''), //token
setSize = reactive({
imgHeight: 0,
imgWidth: 0,
barHeight: 0,
barWidth: 0
}),
tempPoints = reactive([]),
text = ref(''),
barAreaColor = ref(undefined),
barAreaBorderColor = ref(undefined),
showRefresh = ref(true),
bindingClick = ref(true)
/**
* VerifyPoints
* @description 点选
* */
import { resetSize } from './../utils/util';
import { aesEncrypt } from './../utils/ase';
import { reqGet, reqCheck } from './../api/index';
import { onMounted, reactive, ref, nextTick, toRefs, getCurrentInstance } from 'vue';
export default {
name: 'VerifyPoints',
props: {
//popfixed
mode: {
type: String,
default: 'fixed',
},
captchaType: {
type: String,
},
//
vSpace: {
type: Number,
default: 5,
},
imgSize: {
type: Object,
default() {
return {
width: '310px',
height: '155px',
};
},
},
barSize: {
type: Object,
default() {
return {
width: '310px',
height: '40px',
};
},
},
},
setup(props) {
const { mode, captchaType } = toRefs(props);
const { proxy } = getCurrentInstance();
let secretKey = ref(''), //ase
checkNum = ref(3), //
fontPos = reactive([]), //
checkPosArr = reactive([]), //
num = ref(1), //
pointBackImgBase = ref(''), //
poinTextList = reactive([]), //
backToken = ref(''), //token
setSize = reactive({
imgHeight: 0,
imgWidth: 0,
barHeight: 0,
barWidth: 0,
}),
tempPoints = reactive([]),
text = ref(''),
barAreaColor = ref(undefined),
barAreaBorderColor = ref(undefined),
showRefresh = ref(true),
bindingClick = ref(true);
const init = () => {
//
fontPos.splice(0, fontPos.length);
checkPosArr.splice(0, checkPosArr.length);
num.value = 1;
getPictrue();
nextTick(() => {
let { imgHeight, imgWidth, barHeight, barWidth } = resetSize(proxy);
setSize.imgHeight = imgHeight;
setSize.imgWidth = imgWidth;
setSize.barHeight = barHeight;
setSize.barWidth = barWidth;
proxy.$parent.$emit('ready', proxy);
});
};
onMounted(() => {
//
init();
proxy.$el.onselectstart = function () {
return false;
};
});
const canvas = ref(null);
const canvasClick = (e) => {
checkPosArr.push(getMousePos(canvas, e));
if (num.value == checkNum.value) {
num.value = createPoint(getMousePos(canvas, e));
//
let arr = pointTransfrom(checkPosArr, setSize);
checkPosArr.length = 0;
checkPosArr.push(...arr);
//
setTimeout(() => {
// var flag = this.comparePos(this.fontPos, this.checkPosArr);
//
var captchaVerification = secretKey.value
? aesEncrypt(backToken.value + '---' + JSON.stringify(checkPosArr), secretKey.value)
: backToken.value + '---' + JSON.stringify(checkPosArr);
let data = {
captchaType: captchaType.value,
pointJson: secretKey.value ? aesEncrypt(JSON.stringify(checkPosArr), secretKey.value) : JSON.stringify(checkPosArr),
token: backToken.value,
};
reqCheck(data).then((response) => {
let res = response.data;
if (res.repCode == '0000') {
barAreaColor.value = '#4cae4c';
barAreaBorderColor.value = '#5cb85c';
text.value = '验证成功';
bindingClick.value = false;
if (mode.value == 'pop') {
setTimeout(() => {
proxy.$parent.clickShow = false;
refresh();
}, 1500);
}
proxy.$parent.$emit('success', { captchaVerification });
} else {
proxy.$parent.$emit('error', proxy);
barAreaColor.value = '#d9534f';
barAreaBorderColor.value = '#d9534f';
text.value = '验证失败';
setTimeout(() => {
refresh();
}, 700);
}
});
}, 400);
}
if (num.value < checkNum.value) {
num.value = createPoint(getMousePos(canvas, e));
}
};
//
const getMousePos = function (obj, e) {
var x = e.offsetX;
var y = e.offsetY;
return { x, y };
};
//
const createPoint = function (pos) {
tempPoints.push(Object.assign({}, pos));
return num.value + 1;
};
const refresh = function () {
tempPoints.splice(0, tempPoints.length);
barAreaColor.value = '#000';
barAreaBorderColor.value = '#ddd';
bindingClick.value = true;
fontPos.splice(0, fontPos.length);
checkPosArr.splice(0, checkPosArr.length);
num.value = 1;
getPictrue();
text.value = '验证失败';
showRefresh.value = true;
};
const init = ()=>{
//
fontPos.splice(0, fontPos.length)
checkPosArr.splice(0, checkPosArr.length)
num.value = 1
getPictrue();
nextTick(() => {
let {imgHeight,imgWidth,barHeight,barWidth} = resetSize(proxy)
setSize.imgHeight = imgHeight
setSize.imgWidth = imgWidth
setSize.barHeight = barHeight
setSize.barWidth = barWidth
proxy.$parent.$emit('ready', proxy)
})
}
onMounted(()=>{
//
init()
proxy.$el.onselectstart = function () {
return false
}
})
const canvas = ref(null)
const canvasClick = (e)=>{
checkPosArr.push(getMousePos(canvas, e));
if (num.value == checkNum.value) {
num.value = createPoint(getMousePos(canvas, e));
//
let arr = pointTransfrom(checkPosArr,setSize)
checkPosArr.length = 0
checkPosArr.push(...arr);
//
setTimeout(() => {
// var flag = this.comparePos(this.fontPos, this.checkPosArr);
//
var captchaVerification = secretKey.value? aesEncrypt(backToken.value+'---'+JSON.stringify(checkPosArr),secretKey.value):backToken.value+'---'+JSON.stringify(checkPosArr)
let data = {
captchaType:captchaType.value,
"pointJson":secretKey.value? aesEncrypt(JSON.stringify(checkPosArr),secretKey.value):JSON.stringify(checkPosArr),
"token":backToken.value
}
reqCheck(data).then(response=>{
let res = response.data;
if (res.repCode == "0000") {
barAreaColor.value = '#4cae4c'
barAreaBorderColor.value = '#5cb85c'
text.value = '验证成功'
bindingClick.value = false
if (mode.value=='pop') {
setTimeout(()=>{
proxy.$parent.clickShow = false;
refresh();
},1500)
}
proxy.$parent.$emit('success', {captchaVerification})
}else{
proxy.$parent.$emit('error', proxy)
barAreaColor.value = '#d9534f'
barAreaBorderColor.value = '#d9534f'
text.value = '验证失败'
setTimeout(() => {
refresh();
}, 700);
}
})
}, 400);
}
if (num.value < checkNum.value) {
num.value = createPoint(getMousePos(canvas, e));
}
}
//
const getMousePos = function (obj, e) {
var x = e.offsetX
var y = e.offsetY
return {x, y}
}
//
const createPoint = function (pos) {
tempPoints.push(Object.assign({}, pos))
return num.value+1;
}
const refresh = function () {
tempPoints.splice(0, tempPoints.length)
barAreaColor.value = '#000'
barAreaBorderColor.value = '#ddd'
bindingClick.value = true
fontPos.splice(0, fontPos.length)
checkPosArr.splice(0, checkPosArr.length)
num.value = 1
getPictrue();
text.value = '验证失败'
showRefresh.value = true
}
//
function getPictrue() {
let data = {
captchaType:captchaType.value
}
reqGet(data).then(response=>{
let res = response.data;
if (res.repCode == "0000") {
pointBackImgBase.value = res.repData.originalImageBase64
backToken.value = res.repData.token
secretKey.value = res.repData.secretKey
poinTextList.value = res.repData.wordList
text.value = '请依次点击【' + poinTextList.value.join(",") + '】'
}else{
text.value = res.repMsg;
}
})
}
//
const pointTransfrom = function(pointArr,imgSize){
var newPointArr = pointArr.map(p=>{
let x = Math.round(310 * p.x/parseInt(imgSize.imgWidth))
let y =Math.round(155 * p.y/parseInt(imgSize.imgHeight))
return {x,y}
})
return newPointArr
}
return {
secretKey,
checkNum,
fontPos,
checkPosArr,
num,
pointBackImgBase,
poinTextList,
backToken,
setSize,
tempPoints,
text,
barAreaColor,
barAreaBorderColor,
showRefresh,
bindingClick,
init,
canvas,
canvasClick,
getMousePos,createPoint,refresh,getPictrue,pointTransfrom
}
},
}
//
function getPictrue() {
let data = {
captchaType: captchaType.value,
};
reqGet(data).then((response) => {
let res = response.data;
if (res.repCode == '0000') {
pointBackImgBase.value = res.repData.originalImageBase64;
backToken.value = res.repData.token;
secretKey.value = res.repData.secretKey;
poinTextList.value = res.repData.wordList;
text.value = '请依次点击【' + poinTextList.value.join(',') + '】';
} else {
text.value = res.repMsg;
}
});
}
//
const pointTransfrom = function (pointArr, imgSize) {
var newPointArr = pointArr.map((p) => {
let x = Math.round((310 * p.x) / parseInt(imgSize.imgWidth));
let y = Math.round((155 * p.y) / parseInt(imgSize.imgHeight));
return { x, y };
});
return newPointArr;
};
return {
secretKey,
checkNum,
fontPos,
checkPosArr,
num,
pointBackImgBase,
poinTextList,
backToken,
setSize,
tempPoints,
text,
barAreaColor,
barAreaBorderColor,
showRefresh,
bindingClick,
init,
canvas,
canvasClick,
getMousePos,
createPoint,
refresh,
getPictrue,
pointTransfrom,
};
},
};
</script>

View File

@ -1,380 +1,410 @@
<template>
<div style="position: relative;">
<div v-if="type === '2'" :style="{height: (parseInt(setSize.imgHeight) + vSpace) + 'px'}"
class="verify-img-out"
>
<div :style="{width: setSize.imgWidth,
height: setSize.imgHeight,}" class="verify-img-panel">
<img :src="'data:image/png;base64,'+backImgBase" alt="" style="width:100%;height:100%;display:block">
<div v-show="showRefresh" class="verify-refresh" @click="refresh"><i class="iconfont icon-refresh"></i>
</div>
<transition name="tips">
<span v-if="tipWords" :class="passFlag ?'suc-bg':'err-bg'" class="verify-tips">{{ tipWords }}</span>
</transition>
</div>
</div>
<!-- 公共部分 -->
<div :style="{width: setSize.imgWidth,
height: barSize.height,
'line-height':barSize.height}" class="verify-bar-area">
<span class="verify-msg" v-text="text"></span>
<div :style="{width: (leftBarWidth!==undefined)?leftBarWidth: barSize.height, height: barSize.height, 'border-color': leftBarBorderColor, transaction: transitionWidth}"
class="verify-left-bar">
<span class="verify-msg" v-text="finishText"></span>
<div :style="{width: barSize.height, height: barSize.height, 'background-color': moveBlockBackgroundColor, left: moveBlockLeft, transition: transitionLeft}"
class="verify-move-block"
@mousedown="start"
@touchstart="start">
<i :class="['verify-icon iconfont', iconClass]"
:style="{color: iconColor}"></i>
<div v-if="type === '2'" :style="{'width':Math.floor(parseInt(setSize.imgWidth)*47/310)+ 'px',
'height': setSize.imgHeight,
'top':'-' + (parseInt(setSize.imgHeight) + vSpace) + 'px',
'background-size': setSize.imgWidth + ' ' + setSize.imgHeight,
}"
class="verify-sub-block">
<img :src="'data:image/png;base64,'+blockBackImgBase" alt=""
style="width:100%;height:100%;display:block;-webkit-user-drag:none;">
</div>
</div>
</div>
</div>
</div>
<div style="position: relative">
<div v-if="type === '2'" :style="{ height: parseInt(setSize.imgHeight) + vSpace + 'px' }" class="verify-img-out">
<div :style="{ width: setSize.imgWidth, height: setSize.imgHeight }" class="verify-img-panel">
<img :src="'data:image/png;base64,' + backImgBase" alt="" style="width: 100%; height: 100%; display: block" />
<div v-show="showRefresh" class="verify-refresh" @click="refresh"><i class="iconfont icon-refresh"></i></div>
<transition name="tips">
<span v-if="tipWords" :class="passFlag ? 'suc-bg' : 'err-bg'" class="verify-tips">{{ tipWords }}</span>
</transition>
</div>
</div>
<!-- 公共部分 -->
<div :style="{ width: setSize.imgWidth, height: barSize.height, 'line-height': barSize.height }" class="verify-bar-area">
<span class="verify-msg" v-text="text"></span>
<div
:style="{
width: leftBarWidth !== undefined ? leftBarWidth : barSize.height,
height: barSize.height,
'border-color': leftBarBorderColor,
transaction: transitionWidth,
}"
class="verify-left-bar"
>
<span class="verify-msg" v-text="finishText"></span>
<div
:style="{
width: barSize.height,
height: barSize.height,
'background-color': moveBlockBackgroundColor,
left: moveBlockLeft,
transition: transitionLeft,
}"
class="verify-move-block"
@mousedown="start"
@touchstart="start"
>
<i :class="['verify-icon iconfont', iconClass]" :style="{ color: iconColor }"></i>
<div
v-if="type === '2'"
:style="{
width: Math.floor((parseInt(setSize.imgWidth) * 47) / 310) + 'px',
height: setSize.imgHeight,
top: '-' + (parseInt(setSize.imgHeight) + vSpace) + 'px',
'background-size': setSize.imgWidth + ' ' + setSize.imgHeight,
}"
class="verify-sub-block"
>
<img
:src="'data:image/png;base64,' + blockBackImgBase"
alt=""
style="width: 100%; height: 100%; display: block; -webkit-user-drag: none"
/>
</div>
</div>
</div>
</div>
</div>
</template>
<script type="text/babel">
/**
* VerifySlide
* @description 滑块
* */
import {aesEncrypt} from "./../utils/ase"
import {resetSize} from './../utils/util'
import {reqCheck, reqGet} from "./../api/index"
import {computed, getCurrentInstance, nextTick, onMounted, reactive, ref, toRefs, watch} from 'vue';
import { aesEncrypt } from './../utils/ase';
import { resetSize } from './../utils/util';
import { reqCheck, reqGet } from './../api/index';
import { computed, getCurrentInstance, nextTick, onMounted, reactive, ref, toRefs, watch } from 'vue';
export default {
name: 'VerifySlide',
props: {
captchaType: {
type: String,
},
type: {
type: String,
default: '1'
},
//popfixed
mode: {
type: String,
default: 'fixed'
},
vSpace: {
type: Number,
default: 5
},
explain: {
type: String,
default: '向右滑动完成验证'
},
imgSize: {
type: Object,
default() {
return {
width: '310px',
height: '155px'
}
}
},
blockSize: {
type: Object,
default() {
return {
width: '50px',
height: '50px'
}
}
},
barSize: {
type: Object,
default() {
return {
width: '310px',
height: '40px'
}
}
}
},
setup(props) {
const {mode, captchaType, type, blockSize, explain} = toRefs(props)
const { proxy } = getCurrentInstance();
let secretKey = ref(''), //ase
passFlag = ref(''), //
backImgBase = ref(''), //
blockBackImgBase = ref(''), //
backToken = ref(''), //token
startMoveTime = ref(''), //
endMovetime = ref(''), //
tipsBackColor = ref(''), //
tipWords = ref(''),
text = ref(''),
finishText = ref(''),
setSize = reactive({
imgHeight: 0,
imgWidth: 0,
barHeight: 0,
barWidth: 0
}),
top = ref(0),
left = ref(0),
moveBlockLeft = ref(undefined),
leftBarWidth = ref(undefined),
//
moveBlockBackgroundColor = ref(undefined),
leftBarBorderColor = ref('#ddd'),
iconColor = ref(undefined),
iconClass = ref('icon-right'),
status = ref(false), //
isEnd = ref(false), //
showRefresh = ref(true),
transitionLeft = ref(''),
transitionWidth = ref(''),
startLeft = ref(0)
name: 'VerifySlide',
props: {
captchaType: {
type: String,
},
type: {
type: String,
default: '1',
},
//popfixed
mode: {
type: String,
default: 'fixed',
},
vSpace: {
type: Number,
default: 5,
},
explain: {
type: String,
default: '向右滑动完成验证',
},
imgSize: {
type: Object,
default() {
return {
width: '310px',
height: '155px',
};
},
},
blockSize: {
type: Object,
default() {
return {
width: '50px',
height: '50px',
};
},
},
barSize: {
type: Object,
default() {
return {
width: '310px',
height: '40px',
};
},
},
},
setup(props) {
const { mode, captchaType, type, blockSize, explain } = toRefs(props);
const { proxy } = getCurrentInstance();
let secretKey = ref(''), //ase
passFlag = ref(''), //
backImgBase = ref(''), //
blockBackImgBase = ref(''), //
backToken = ref(''), //token
startMoveTime = ref(''), //
endMovetime = ref(''), //
tipsBackColor = ref(''), //
tipWords = ref(''),
text = ref(''),
finishText = ref(''),
setSize = reactive({
imgHeight: 0,
imgWidth: 0,
barHeight: 0,
barWidth: 0,
}),
top = ref(0),
left = ref(0),
moveBlockLeft = ref(undefined),
leftBarWidth = ref(undefined),
//
moveBlockBackgroundColor = ref(undefined),
leftBarBorderColor = ref('#ddd'),
iconColor = ref(undefined),
iconClass = ref('icon-right'),
status = ref(false), //
isEnd = ref(false), //
showRefresh = ref(true),
transitionLeft = ref(''),
transitionWidth = ref(''),
startLeft = ref(0);
const barArea = computed(() => {
return proxy.$el.querySelector('.verify-bar-area')
})
const barArea = computed(() => {
return proxy.$el.querySelector('.verify-bar-area');
});
function init() {
text.value = explain.value
getPictrue();
nextTick(() => {
let {imgHeight, imgWidth, barHeight, barWidth} = resetSize(proxy)
setSize.imgHeight = imgHeight
setSize.imgWidth = imgWidth
setSize.barHeight = barHeight
setSize.barWidth = barWidth
proxy.$parent.$emit('ready', proxy)
})
function init() {
text.value = explain.value;
getPictrue();
nextTick(() => {
let { imgHeight, imgWidth, barHeight, barWidth } = resetSize(proxy);
setSize.imgHeight = imgHeight;
setSize.imgWidth = imgWidth;
setSize.barHeight = barHeight;
setSize.barWidth = barWidth;
proxy.$parent.$emit('ready', proxy);
});
window.removeEventListener("touchmove", function (e) {
move(e);
});
window.removeEventListener("mousemove", function (e) {
move(e);
});
window.removeEventListener('touchmove', function (e) {
move(e);
});
window.removeEventListener('mousemove', function (e) {
move(e);
});
//
window.removeEventListener("touchend", function () {
end();
});
window.removeEventListener("mouseup", function () {
end();
});
//
window.removeEventListener('touchend', function () {
end();
});
window.removeEventListener('mouseup', function () {
end();
});
window.addEventListener("touchmove", function (e) {
move(e);
});
window.addEventListener("mousemove", function (e) {
move(e);
});
window.addEventListener('touchmove', function (e) {
move(e);
});
window.addEventListener('mousemove', function (e) {
move(e);
});
//
window.addEventListener("touchend", function () {
end();
});
window.addEventListener("mouseup", function () {
end();
});
}
//
window.addEventListener('touchend', function () {
end();
});
window.addEventListener('mouseup', function () {
end();
});
}
watch(type, () => {
init()
})
onMounted(() => {
//
init()
proxy.$el.onselectstart = function () {
return false
}
})
watch(type, () => {
init();
});
onMounted(() => {
//
init();
proxy.$el.onselectstart = function () {
return false;
};
});
//
function start(e) {
e = e || window.event
let x = null
if (!e.touches) { //PC
x = e.clientX;
} else { //
x = e.touches[0].pageX;
}
startLeft.value = Math.floor(x - barArea.value.getBoundingClientRect().left);
startMoveTime.value = +new Date(); //
if (isEnd.value == false) {
text.value = ''
moveBlockBackgroundColor.value = '#337ab7'
leftBarBorderColor.value = '#337AB7'
iconColor.value = '#fff'
e.stopPropagation();
status.value = true;
}
}
//
function start(e) {
e = e || window.event;
let x = null;
if (!e.touches) {
//PC
x = e.clientX;
} else {
//
x = e.touches[0].pageX;
}
startLeft.value = Math.floor(x - barArea.value.getBoundingClientRect().left);
startMoveTime.value = +new Date(); //
if (isEnd.value == false) {
text.value = '';
moveBlockBackgroundColor.value = '#337ab7';
leftBarBorderColor.value = '#337AB7';
iconColor.value = '#fff';
e.stopPropagation();
status.value = true;
}
}
//
function move(e) {
e = e || window.event
if (status.value && isEnd.value == false) {
let x = null;
if (!e.touches) { //PC
x = e.clientX;
} else { //
x = e.touches[0].pageX;
}
var bar_area_left = barArea.value.getBoundingClientRect().left;
var move_block_left = x - bar_area_left //left
if (move_block_left >= barArea.value.offsetWidth - parseInt(parseInt(blockSize.value.width) / 2) - 2) {
move_block_left = barArea.value.offsetWidth - parseInt(parseInt(blockSize.value.width) / 2) - 2;
}
if (move_block_left <= 0) {
move_block_left = parseInt(parseInt(blockSize.value.width) / 2);
}
//left
moveBlockLeft.value = (move_block_left - startLeft.value) + "px"
leftBarWidth.value = (move_block_left - startLeft.value) + "px"
}
}
//
function move(e) {
e = e || window.event;
if (status.value && isEnd.value == false) {
let x = null;
if (!e.touches) {
//PC
x = e.clientX;
} else {
//
x = e.touches[0].pageX;
}
var bar_area_left = barArea.value.getBoundingClientRect().left;
var move_block_left = x - bar_area_left; //left
if (move_block_left >= barArea.value.offsetWidth - parseInt(parseInt(blockSize.value.width) / 2) - 2) {
move_block_left = barArea.value.offsetWidth - parseInt(parseInt(blockSize.value.width) / 2) - 2;
}
if (move_block_left <= 0) {
move_block_left = parseInt(parseInt(blockSize.value.width) / 2);
}
//left
moveBlockLeft.value = move_block_left - startLeft.value + 'px';
leftBarWidth.value = move_block_left - startLeft.value + 'px';
}
}
//
function end() {
endMovetime.value = +new Date();
//
if (status.value && isEnd.value == false) {
var moveLeftDistance = parseInt((moveBlockLeft.value || '').replace('px', ''));
moveLeftDistance = moveLeftDistance * 310 / parseInt(setSize.imgWidth)
let data = {
captchaType: captchaType.value,
"pointJson": secretKey.value ? aesEncrypt(JSON.stringify({
x: moveLeftDistance,
y: 5.0
}), secretKey.value) : JSON.stringify({x: moveLeftDistance, y: 5.0}),
"token": backToken.value
}
reqCheck(data).then(response => {
let res = response.data;
if (res.repCode == "0000") {
moveBlockBackgroundColor.value = '#5cb85c'
leftBarBorderColor.value = '#5cb85c'
iconColor.value = '#fff'
iconClass.value = 'icon-check'
showRefresh.value = false
isEnd.value = true;
if (mode.value == 'pop') {
setTimeout(() => {
proxy.$parent.clickShow = false;
refresh();
}, 1500)
}
passFlag.value = true
tipWords.value = `${((endMovetime.value - startMoveTime.value) / 1000).toFixed(2)}s验证成功`
var captchaVerification = secretKey.value ? aesEncrypt(backToken.value + '---' + JSON.stringify({
x: moveLeftDistance,
y: 5.0
}), secretKey.value) : backToken.value + '---' + JSON.stringify({x: moveLeftDistance, y: 5.0})
setTimeout(() => {
tipWords.value = ""
proxy.$parent.$parent.closeBox();
proxy.$parent.$parent.$emit('success', {captchaVerification})
}, 1000)
} else {
moveBlockBackgroundColor.value = '#d9534f'
leftBarBorderColor.value = '#d9534f'
iconColor.value = '#fff'
iconClass.value = 'icon-close'
passFlag.value = false
setTimeout(function () {
refresh();
}, 1000);
proxy.$parent.$emit('error', proxy)
tipWords.value = "验证失败"
setTimeout(() => {
tipWords.value = ""
}, 1000)
}
})
status.value = false;
}
}
//
function end() {
endMovetime.value = +new Date();
//
if (status.value && isEnd.value == false) {
var moveLeftDistance = parseInt((moveBlockLeft.value || '').replace('px', ''));
moveLeftDistance = (moveLeftDistance * 310) / parseInt(setSize.imgWidth);
let data = {
captchaType: captchaType.value,
pointJson: secretKey.value
? aesEncrypt(
JSON.stringify({
x: moveLeftDistance,
y: 5.0,
}),
secretKey.value
)
: JSON.stringify({ x: moveLeftDistance, y: 5.0 }),
token: backToken.value,
};
reqCheck(data).then((response) => {
let res = response.data;
if (res.repCode == '0000') {
moveBlockBackgroundColor.value = '#5cb85c';
leftBarBorderColor.value = '#5cb85c';
iconColor.value = '#fff';
iconClass.value = 'icon-check';
showRefresh.value = false;
isEnd.value = true;
if (mode.value == 'pop') {
setTimeout(() => {
proxy.$parent.clickShow = false;
refresh();
}, 1500);
}
passFlag.value = true;
tipWords.value = `${((endMovetime.value - startMoveTime.value) / 1000).toFixed(2)}s验证成功`;
var captchaVerification = secretKey.value
? aesEncrypt(
backToken.value +
'---' +
JSON.stringify({
x: moveLeftDistance,
y: 5.0,
}),
secretKey.value
)
: backToken.value + '---' + JSON.stringify({ x: moveLeftDistance, y: 5.0 });
setTimeout(() => {
tipWords.value = '';
proxy.$parent.$parent.closeBox();
proxy.$parent.$parent.$emit('success', { captchaVerification });
}, 1000);
} else {
moveBlockBackgroundColor.value = '#d9534f';
leftBarBorderColor.value = '#d9534f';
iconColor.value = '#fff';
iconClass.value = 'icon-close';
passFlag.value = false;
setTimeout(function () {
refresh();
}, 1000);
proxy.$parent.$emit('error', proxy);
tipWords.value = '验证失败';
setTimeout(() => {
tipWords.value = '';
}, 1000);
}
});
status.value = false;
}
}
const refresh = () => {
showRefresh.value = true
finishText.value = ''
const refresh = () => {
showRefresh.value = true;
finishText.value = '';
transitionLeft.value = 'left .3s'
moveBlockLeft.value = 0
transitionLeft.value = 'left .3s';
moveBlockLeft.value = 0;
leftBarWidth.value = undefined
transitionWidth.value = 'width .3s'
leftBarWidth.value = undefined;
transitionWidth.value = 'width .3s';
leftBarBorderColor.value = '#ddd'
moveBlockBackgroundColor.value = '#fff'
iconColor.value = '#000'
iconClass.value = 'icon-right'
isEnd.value = false
leftBarBorderColor.value = '#ddd';
moveBlockBackgroundColor.value = '#fff';
iconColor.value = '#000';
iconClass.value = 'icon-right';
isEnd.value = false;
getPictrue()
setTimeout(() => {
transitionWidth.value = ''
transitionLeft.value = ''
text.value = explain.value
}, 300)
}
getPictrue();
setTimeout(() => {
transitionWidth.value = '';
transitionLeft.value = '';
text.value = explain.value;
}, 300);
};
//
function getPictrue() {
let data = {
captchaType: captchaType.value
}
reqGet(data).then(response => {
let res = response.data;
if (res.repCode == "0000") {
backImgBase.value = res.repData.originalImageBase64
blockBackImgBase.value = res.repData.jigsawImageBase64
backToken.value = res.repData.token
secretKey.value = res.repData.secretKey
} else {
tipWords.value = res.repMsg;
}
})
}
//
function getPictrue() {
let data = {
captchaType: captchaType.value,
};
reqGet(data).then((response) => {
let res = response.data;
if (res.repCode == '0000') {
backImgBase.value = res.repData.originalImageBase64;
blockBackImgBase.value = res.repData.jigsawImageBase64;
backToken.value = res.repData.token;
secretKey.value = res.repData.secretKey;
} else {
tipWords.value = res.repMsg;
}
});
}
return {
secretKey, //ase
passFlag, //
backImgBase, //
blockBackImgBase, //
backToken, //token
startMoveTime, //
endMovetime, //
tipsBackColor, //
tipWords,
text,
finishText,
setSize,
top,
left,
moveBlockLeft,
leftBarWidth,
//
moveBlockBackgroundColor,
leftBarBorderColor,
iconColor,
iconClass,
status, //
isEnd, //
showRefresh,
transitionLeft,
transitionWidth,
barArea,
refresh,
start
}
},
}
return {
secretKey, //ase
passFlag, //
backImgBase, //
blockBackImgBase, //
backToken, //token
startMoveTime, //
endMovetime, //
tipsBackColor, //
tipWords,
text,
finishText,
setSize,
top,
left,
moveBlockLeft,
leftBarWidth,
//
moveBlockBackgroundColor,
leftBarBorderColor,
iconColor,
iconClass,
status, //
isEnd, //
showRefresh,
transitionLeft,
transitionWidth,
barArea,
refresh,
start,
};
},
};
</script>

View File

@ -2,25 +2,22 @@
* axios
*/
import request from '/@/utils/request';
//获取验证图片 以及token
export function reqGet(data: Object) {
return request({
url: '/admin/code/create',
method: 'get',
data
})
return request({
url: '/admin/code/create',
method: 'get',
data,
});
}
//滑动或者点选验证
export function reqCheck(data: Object) {
return request({
url: '/admin/code/check',
method: 'post',
params: data
})
return request({
url: '/admin/code/check',
method: 'post',
params: data,
});
}

View File

@ -1,11 +1,11 @@
import CryptoJS from 'crypto-js'
import CryptoJS from 'crypto-js';
/**
* @word 要加密的内容
* @keyWord String 服务器随机返回的关键字
* */
export function aesEncrypt(word,keyWord="XwKsGlMcdPMEhR1B"){
var key = CryptoJS.enc.Utf8.parse(keyWord);
var srcs = CryptoJS.enc.Utf8.parse(word);
var encrypted = CryptoJS.AES.encrypt(srcs, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
return encrypted.toString();
export function aesEncrypt(word, keyWord = 'XwKsGlMcdPMEhR1B') {
var key = CryptoJS.enc.Utf8.parse(keyWord);
var srcs = CryptoJS.enc.Utf8.parse(word);
var encrypted = CryptoJS.AES.encrypt(srcs, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 });
return encrypted.toString();
}

View File

@ -1,35 +1,97 @@
export function resetSize(vm) {
var img_width, img_height, bar_width, bar_height; //图片的宽度、高度,移动条的宽度、高度
var img_width, img_height, bar_width, bar_height; //图片的宽度、高度,移动条的宽度、高度
var parentWidth = vm.$el.parentNode.offsetWidth || window.offsetWidth
var parentHeight = vm.$el.parentNode.offsetHeight || window.offsetHeight
if (vm.imgSize.width.indexOf('%') != -1) {
img_width = parseInt(vm.imgSize.width) / 100 * parentWidth + 'px'
} else {
img_width = vm.imgSize.width;
}
var parentWidth = vm.$el.parentNode.offsetWidth || window.offsetWidth;
var parentHeight = vm.$el.parentNode.offsetHeight || window.offsetHeight;
if (vm.imgSize.width.indexOf('%') != -1) {
img_width = (parseInt(vm.imgSize.width) / 100) * parentWidth + 'px';
} else {
img_width = vm.imgSize.width;
}
if (vm.imgSize.height.indexOf('%') != -1) {
img_height = parseInt(vm.imgSize.height) / 100 * parentHeight + 'px'
} else {
img_height = vm.imgSize.height
}
if (vm.imgSize.height.indexOf('%') != -1) {
img_height = (parseInt(vm.imgSize.height) / 100) * parentHeight + 'px';
} else {
img_height = vm.imgSize.height;
}
if (vm.barSize.width.indexOf('%') != -1) {
bar_width = parseInt(vm.barSize.width) / 100 * parentWidth + 'px'
} else {
bar_width = vm.barSize.width
}
if (vm.barSize.width.indexOf('%') != -1) {
bar_width = (parseInt(vm.barSize.width) / 100) * parentWidth + 'px';
} else {
bar_width = vm.barSize.width;
}
if (vm.barSize.height.indexOf('%') != -1) {
bar_height = parseInt(vm.barSize.height) / 100 * parentHeight + 'px'
} else {
bar_height = vm.barSize.height
}
if (vm.barSize.height.indexOf('%') != -1) {
bar_height = (parseInt(vm.barSize.height) / 100) * parentHeight + 'px';
} else {
bar_height = vm.barSize.height;
}
return {imgWidth: img_width, imgHeight: img_height, barWidth: bar_width, barHeight: bar_height}
return { imgWidth: img_width, imgHeight: img_height, barWidth: bar_width, barHeight: bar_height };
}
export const _code_chars = [1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
export const _code_color1 = ['#fffff0', '#f0ffff', '#f0fff0', '#fff0f0']
export const _code_color2 = ['#FF0033', '#006699', '#993366', '#FF9900', '#66CC66', '#FF33CC']
export const _code_chars = [
1,
2,
3,
4,
5,
6,
7,
8,
9,
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z',
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
];
export const _code_color1 = ['#fffff0', '#f0ffff', '#f0fff0', '#fff0f0'];
export const _code_color2 = ['#FF0033', '#006699', '#993366', '#FF9900', '#66CC66', '#FF33CC'];

View File

@ -1,97 +1,95 @@
<template>
<el-upload
ref="fileUpload"
:action="actionUrl"
:headers="headers"
multiple
:limit="1"
:on-success="handleUploadSuccess"
:file-list="fileList"
:before-upload="beforeThumbImageUpload"
:auto-upload="autoUpload"
:data="uploadData">
<template #tip>
<div class="el-upload__tip" v-if="props.type.length > 0">支持{{props.type.join("/")}}格式大小不超过2M</div>
</template>
<el-button type="primary">本地上传</el-button>
</el-upload>
<el-upload
ref="fileUpload"
:action="actionUrl"
:headers="headers"
multiple
:limit="1"
:on-success="handleUploadSuccess"
:file-list="fileList"
:before-upload="beforeThumbImageUpload"
:auto-upload="autoUpload"
:data="uploadData"
>
<template #tip>
<div class="el-upload__tip" v-if="props.type.length > 0">支持{{ props.type.join('/') }}格式大小不超过2M</div>
</template>
<el-button type="primary">本地上传</el-button>
</el-upload>
</template>
<script setup lang="ts" name="wx-file-upload">
import { Local, Session } from '/@/utils/storage';
import { useMessage } from '/@/hooks/message';
import {Local, Session} from "/@/utils/storage";
import {useMessage} from "/@/hooks/message";
const actionUrl = ref('/admin/wx-material/materialFileUpload');
const actionUrl = ref("/admin/wx-material/materialFileUpload")
const fileUpload = ref()
const fileUpload = ref();
const headers = computed(() => {
const tenantId = Local.get("tenantId") ? Local.get("tenantId") : 1
return {
'Authorization': "Bearer " + Session.get("token"),
'TENANT-ID': tenantId
};
})
const tenantId = Local.get('tenantId') ? Local.get('tenantId') : 1;
return {
Authorization: 'Bearer ' + Session.get('token'),
'TENANT-ID': tenantId,
};
});
// emit
const emit = defineEmits(['success']);
const fileList = ref([])
const fileList = ref([]);
const props = defineProps({
uploadData: {
type: Object,
default: () => {
return {
appId: '',
mediaType: 'image',
title: '',
introduction: '',
}
}
},
autoUpload: {
type: Boolean,
default: true
},
type: {
type: Array,
default: () => {
return []
}
}
})
uploadData: {
type: Object,
default: () => {
return {
appId: '',
mediaType: 'image',
title: '',
introduction: '',
};
},
},
autoUpload: {
type: Boolean,
default: true,
},
type: {
type: Array,
default: () => {
return [];
},
},
});
const beforeThumbImageUpload = (file: any) => {
let isType = true
if(props.type?.length > 0){
isType = props.type?.includes(file.type)
}
const isLt = file.size / 1024 / 1024 < 2
if (!isType) {
useMessage().error("上传文件格式不对!")
}
if (!isLt) {
useMessage().error("上传文件大小不能超过2M!!")
}
return isType && isLt
}
let isType = true;
if (props.type?.length > 0) {
isType = props.type?.includes(file.type);
}
const isLt = file.size / 1024 / 1024 < 2;
if (!isType) {
useMessage().error('上传文件格式不对!');
}
if (!isLt) {
useMessage().error('上传文件大小不能超过2M!!');
}
return isType && isLt;
};
const handleUploadSuccess = (response, file, fileList) => {
fileList.value = []
emit("success",response, file, fileList)
}
fileList.value = [];
emit('success', response, file, fileList);
};
const submit = () => {
return new Promise(resolve => {
fileUpload.value.submit()
resolve('')
})
}
return new Promise((resolve) => {
fileUpload.value.submit();
resolve('');
});
};
defineExpose({
submit
})
submit,
});
</script>
<style scoped>
</style>
<style scoped></style>

View File

@ -1,212 +1,167 @@
<template>
<el-dialog title="选择图文" v-model="visible"
:close-on-click-modal="false" draggable width="80%">
<div v-if="objData.type === 'image'">
<div class="waterfall" v-loading="state.loading">
<div class="waterfall-item" v-for="item in state.dataList" :key="item.mediaId">
<img class="material-img" :src="item.url" />
<p class="item-name">{{ item.name }}</p>
<el-row class="ope-row">
<el-button type="success" @click="selectMaterial(item)"
>选择
<el-icon class="el-icon--right"></el-icon>
</el-button>
</el-row>
</div>
</div>
<pagination v-bind="state.pagination"
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"/>
</div>
<div v-else-if="objData.type === 'voice'">
<!-- 列表 -->
<el-table v-loading="state.loading" :data="state.dataList">
<el-table-column label="编号" align="center" prop="mediaId" />
<el-table-column label="文件名" align="center" prop="name" />
<el-table-column label="语音" align="center" prop="url">
</el-table-column>
<el-table-column
label="上传时间"
align="center"
prop="createTime"
width="180"
>
<template v-slot="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
align="center"
fixed="right"
class-name="small-padding fixed-width"
>
<template v-slot="scope">
<el-button
icon="el-icon-circle-plus"
@click="selectMaterial(scope.row)"
>选择</el-button
>
</template>
</el-table-column>
</el-table>
<pagination v-bind="state.pagination"
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"/>
</div>
<div v-else-if="objData.type === 'video'">
<!-- 列表 -->
<el-table v-loading="state.loading" :data="state.dataList">
<el-table-column label="编号" align="center" prop="mediaId" />
<el-table-column label="文件名" align="center" prop="name" />
<el-table-column label="标题" align="center" prop="title" />
<el-table-column label="介绍" align="center" prop="introduction" />
<el-table-column label="视频" align="center" prop="url">
</el-table-column>
<el-table-column
label="上传时间"
align="center"
prop="createTime"
width="180"
>
<template v-slot="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
label="操作"
align="center"
fixed="right"
class-name="small-padding fixed-width"
>
<template v-slot="scope">
<el-button @click="selectMaterial(scope.row)">选择</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-bind="state.pagination"
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"/>
</div>
<div v-else-if="objData.type === 'news'">
<div class="waterfall" v-loading="state.loading">
<template v-for="item in state.dataList">
<div v-if="item.content && item.content.newsItem" class="waterfall-item" :key="item.id">
<wx-news :obj-data="item.content.newsItem"></wx-news>
<el-row class="ope-row">
<el-button type="success" @click="selectMaterial(item)">
选择<el-icon class="el-icon--right"/>
</el-button>
</el-row>
</div>
</template>
</div>
<pagination v-bind="state.pagination"
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"/>
</div>
</el-dialog>
<el-dialog title="选择图文" v-model="visible" :close-on-click-modal="false" draggable width="80%">
<div v-if="objData.type === 'image'">
<div class="waterfall" v-loading="state.loading">
<div class="waterfall-item" v-for="item in state.dataList" :key="item.mediaId">
<img class="material-img" :src="item.url" />
<p class="item-name">{{ item.name }}</p>
<el-row class="ope-row">
<el-button type="success" @click="selectMaterial(item)"
>选择
<el-icon class="el-icon--right"></el-icon>
</el-button>
</el-row>
</div>
</div>
<pagination v-bind="state.pagination" @size-change="sizeChangeHandle" @current-change="currentChangeHandle" />
</div>
<div v-else-if="objData.type === 'voice'">
<!-- 列表 -->
<el-table v-loading="state.loading" :data="state.dataList">
<el-table-column label="编号" align="center" prop="mediaId" />
<el-table-column label="文件名" align="center" prop="name" />
<el-table-column label="语音" align="center" prop="url"> </el-table-column>
<el-table-column label="上传时间" align="center" prop="createTime" width="180">
<template v-slot="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
<template v-slot="scope">
<el-button icon="el-icon-circle-plus" @click="selectMaterial(scope.row)">选择</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-bind="state.pagination" @size-change="sizeChangeHandle" @current-change="currentChangeHandle" />
</div>
<div v-else-if="objData.type === 'video'">
<!-- 列表 -->
<el-table v-loading="state.loading" :data="state.dataList">
<el-table-column label="编号" align="center" prop="mediaId" />
<el-table-column label="文件名" align="center" prop="name" />
<el-table-column label="标题" align="center" prop="title" />
<el-table-column label="介绍" align="center" prop="introduction" />
<el-table-column label="视频" align="center" prop="url"> </el-table-column>
<el-table-column label="上传时间" align="center" prop="createTime" width="180">
<template v-slot="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
<template v-slot="scope">
<el-button @click="selectMaterial(scope.row)">选择</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-bind="state.pagination" @size-change="sizeChangeHandle" @current-change="currentChangeHandle" />
</div>
<div v-else-if="objData.type === 'news'">
<div class="waterfall" v-loading="state.loading">
<template v-for="item in state.dataList">
<div v-if="item.content && item.content.newsItem" class="waterfall-item" :key="item.id">
<wx-news :obj-data="item.content.newsItem"></wx-news>
<el-row class="ope-row">
<el-button type="success" @click="selectMaterial(item)"> 选择<el-icon class="el-icon--right" /> </el-button>
</el-row>
</div>
</template>
</div>
<pagination v-bind="state.pagination" @size-change="sizeChangeHandle" @current-change="currentChangeHandle" />
</div>
</el-dialog>
</template>
<script setup lang="ts" name="wx-material-select">
import { defineEmits } from 'vue';
import { BasicTableProps, useTable } from '/@/hooks/table';
import { getPage } from '/@/api/mp/wx-material';
const WxNews = defineAsyncComponent(() => import('../wx-news/index.vue'));
import {defineEmits} from "vue";
import {BasicTableProps, useTable} from "/@/hooks/table";
import {getPage} from "/@/api/mp/wx-material";
const WxNews = defineAsyncComponent(() => import('../wx-news/index.vue'))
const emit = defineEmits(["selectMaterial"])
const emit = defineEmits(['selectMaterial']);
const objData = reactive({
repType: '',
accountId: '',
type: ''
})
repType: '',
accountId: '',
type: '',
});
const visible = ref(false)
const visible = ref(false);
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: {
type: "",
appId: ""
},
pageList: getPage,
createdIsNeed: false,
props: {
item: 'items',
totalCount: 'totalCount'
}
})
queryForm: {
type: '',
appId: '',
},
pageList: getPage,
createdIsNeed: false,
props: {
item: 'items',
totalCount: 'totalCount',
},
});
const {
getDataList,
currentChangeHandle,
sizeChangeHandle
} = useTable(state)
const { getDataList, currentChangeHandle, sizeChangeHandle } = useTable(state);
const selectMaterial = (item : any) => {
emit('selectMaterial', item,objData.accountId)
visible.value = false
}
const selectMaterial = (item: any) => {
emit('selectMaterial', item, objData.accountId);
visible.value = false;
};
const openDialog = (data: any) => {
state.queryForm.type = data.type
state.queryForm.appId = data.accountId
objData.type = data.type
objData.accountId = data.accountId
visible.value = true
getDataList()
}
state.queryForm.type = data.type;
state.queryForm.appId = data.accountId;
objData.type = data.type;
objData.accountId = data.accountId;
visible.value = true;
getDataList();
};
//
defineExpose({
openDialog,
openDialog,
});
</script>
<style lang="scss" scoped>
/*瀑布流样式*/
.waterfall {
width: 100%;
column-gap:10px;
column-count: 5;
margin: 0 auto;
width: 100%;
column-gap: 10px;
column-count: 5;
margin: 0 auto;
}
.waterfall-item {
padding: 10px;
margin-bottom: 10px;
break-inside: avoid;
border: 1px solid #eaeaea;
padding: 10px;
margin-bottom: 10px;
break-inside: avoid;
border: 1px solid #eaeaea;
}
.material-img {
width: 100%;
width: 100%;
}
p {
line-height: 30px;
line-height: 30px;
}
@media (min-width: 992px) and (max-width: 1300px) {
.waterfall {
column-count: 3;
}
p {
color:red;
}
.waterfall {
column-count: 3;
}
p {
color: red;
}
}
@media (min-width: 768px) and (max-width: 991px) {
.waterfall {
column-count: 2;
}
p {
color: orange;
}
.waterfall {
column-count: 2;
}
p {
color: orange;
}
}
@media (max-width: 767px) {
.waterfall {
column-count: 1;
}
.waterfall {
column-count: 1;
}
}
/*瀑布流样式*/
</style>

View File

@ -1,101 +1,101 @@
.avue-card{
&__item{
margin-bottom: 16px;
border: 1px solid #e8e8e8;
background-color: #fff;
box-sizing: border-box;
color: rgba(0,0,0,.65);
font-size: 14px;
font-variant: tabular-nums;
line-height: 1.5;
list-style: none;
font-feature-settings: "tnum";
cursor: pointer;
height:200px;
&:hover{
border-color: rgba(0,0,0,.09);
box-shadow: 0 2px 8px rgba(0,0,0,.09);
}
&--add{
border:1px dashed #000;
width: 100%;
color: rgba(0,0,0,.45);
background-color: #fff;
border-color: #d9d9d9;
border-radius: 2px;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
i{
margin-right: 10px;
}
&:hover{
color: #40a9ff;
background-color: #fff;
border-color: #40a9ff;
}
}
}
&__body{
display: flex;
padding: 24px;
}
&__detail{
flex:1
}
&__avatar{
width: 48px;
height: 48px;
border-radius: 48px;
overflow: hidden;
margin-right: 12px;
img{
width: 100%;
height: 100%;
}
}
&__title{
color: rgba(0,0,0,.85);
margin-bottom: 12px;
font-size: 16px;
&:hover{
color:#1890ff;
}
}
&__info{
color: rgba(0,0,0,.45);
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
height: 64px;
}
&__menu{
display: flex;
justify-content:space-around;
height: 50px;
background: #f7f9fa;
color: rgba(0,0,0,.45);
text-align: center;
line-height: 50px;
&:hover{
color:#1890ff;
}
}
.avue-card {
&__item {
margin-bottom: 16px;
border: 1px solid #e8e8e8;
background-color: #fff;
box-sizing: border-box;
color: rgba(0, 0, 0, 0.65);
font-size: 14px;
font-variant: tabular-nums;
line-height: 1.5;
list-style: none;
font-feature-settings: 'tnum';
cursor: pointer;
height: 200px;
&:hover {
border-color: rgba(0, 0, 0, 0.09);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.09);
}
&--add {
border: 1px dashed #000;
width: 100%;
color: rgba(0, 0, 0, 0.45);
background-color: #fff;
border-color: #d9d9d9;
border-radius: 2px;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
i {
margin-right: 10px;
}
&:hover {
color: #40a9ff;
background-color: #fff;
border-color: #40a9ff;
}
}
}
&__body {
display: flex;
padding: 24px;
}
&__detail {
flex: 1;
}
&__avatar {
width: 48px;
height: 48px;
border-radius: 48px;
overflow: hidden;
margin-right: 12px;
img {
width: 100%;
height: 100%;
}
}
&__title {
color: rgba(0, 0, 0, 0.85);
margin-bottom: 12px;
font-size: 16px;
&:hover {
color: #1890ff;
}
}
&__info {
color: rgba(0, 0, 0, 0.45);
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
height: 64px;
}
&__menu {
display: flex;
justify-content: space-around;
height: 50px;
background: #f7f9fa;
color: rgba(0, 0, 0, 0.45);
text-align: center;
line-height: 50px;
&:hover {
color: #1890ff;
}
}
}
/** joolun 额外加的 */
.avue-comment__main {
flex: unset!important;
border-radius: 5px!important;
margin: 0 8px!important;
flex: unset !important;
border-radius: 5px !important;
margin: 0 8px !important;
}
.avue-comment__header {
border-top-left-radius: 5px;
border-top-right-radius: 5px;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.avue-comment__body {
border-bottom-right-radius: 5px;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
border-bottom-left-radius: 5px;
}

View File

@ -1,88 +1,92 @@
/* 来自 https://github.com/nmxiaowei/avue/blob/master/styles/src/element-ui/comment.scss */
.avue-comment{
margin-bottom: 30px;
display: flex;
align-items: flex-start;
&--reverse{
flex-direction:row-reverse;
.avue-comment__main{
&:before,&:after{
left: auto;
right: -8px;
border-width: 8px 0 8px 8px;
}
&:before{
border-left-color: #dedede;
}
&:after{
border-left-color: #f8f8f8;
margin-right: 1px;
margin-left: auto;
}
}
}
&__avatar{
width: 48px;
height: 48px;
border-radius: 50%;
border: 1px solid transparent;
box-sizing: border-box;
vertical-align: middle;
}
&__header{
padding: 5px 15px;
background: #f8f8f8;
border-bottom: 1px solid #eee;
display: flex;
align-items: center;
justify-content: space-between;
}
&__author{
font-weight: 700;
font-size: 14px;
color: #999;
}
&__main{
flex:1;
margin: 0 20px;
position: relative;
border: 1px solid #dedede;
border-radius: 2px;
&:before,&:after{
position: absolute;
top: 10px;
left: -8px;
right: 100%;
width: 0;
height: 0;
display: block;
content: " ";
border-color: transparent;
border-style: solid solid outset;
border-width: 8px 8px 8px 0;
pointer-events: none;
}
&:before {
border-right-color: #dedede;
z-index: 1;
}
&:after{
border-right-color: #f8f8f8;
margin-left: 1px;
z-index: 2;
}
}
&__body{
padding: 15px;
overflow: hidden;
background: #fff;
font-family: Segoe UI,Lucida Grande,Helvetica,Arial,Microsoft YaHei,FreeSans,Arimo,Droid Sans,wenquanyi micro hei,Hiragino Sans GB,Hiragino Sans GB W3,FontAwesome,sans-serif;color: #333;
font-size: 14px;
}
blockquote{
margin:0;
font-family: Georgia,Times New Roman,Times,Kai,Kaiti SC,KaiTi,BiauKai,FontAwesome,serif;
padding: 1px 0 1px 15px;
border-left: 4px solid #ddd;
}
.avue-comment {
margin-bottom: 30px;
display: flex;
align-items: flex-start;
&--reverse {
flex-direction: row-reverse;
.avue-comment__main {
&:before,
&:after {
left: auto;
right: -8px;
border-width: 8px 0 8px 8px;
}
&:before {
border-left-color: #dedede;
}
&:after {
border-left-color: #f8f8f8;
margin-right: 1px;
margin-left: auto;
}
}
}
&__avatar {
width: 48px;
height: 48px;
border-radius: 50%;
border: 1px solid transparent;
box-sizing: border-box;
vertical-align: middle;
}
&__header {
padding: 5px 15px;
background: #f8f8f8;
border-bottom: 1px solid #eee;
display: flex;
align-items: center;
justify-content: space-between;
}
&__author {
font-weight: 700;
font-size: 14px;
color: #999;
}
&__main {
flex: 1;
margin: 0 20px;
position: relative;
border: 1px solid #dedede;
border-radius: 2px;
&:before,
&:after {
position: absolute;
top: 10px;
left: -8px;
right: 100%;
width: 0;
height: 0;
display: block;
content: ' ';
border-color: transparent;
border-style: solid solid outset;
border-width: 8px 8px 8px 0;
pointer-events: none;
}
&:before {
border-right-color: #dedede;
z-index: 1;
}
&:after {
border-right-color: #f8f8f8;
margin-left: 1px;
z-index: 2;
}
}
&__body {
padding: 15px;
overflow: hidden;
background: #fff;
font-family: Segoe UI, Lucida Grande, Helvetica, Arial, Microsoft YaHei, FreeSans, Arimo, Droid Sans, wenquanyi micro hei, Hiragino Sans GB,
Hiragino Sans GB W3, FontAwesome, sans-serif;
color: #333;
font-size: 14px;
}
blockquote {
margin: 0;
font-family: Georgia, Times New Roman, Times, Kai, Kaiti SC, KaiTi, BiauKai, FontAwesome, serif;
padding: 1px 0 1px 15px;
border-left: 4px solid #ddd;
}
}

View File

@ -1,233 +1,251 @@
<template>
<el-dialog title="用户消息" v-model="visible"
:close-on-click-modal="false" draggable>
<div v-loading="mainLoading" class="msg-main">
<div id="msg-div" class="msg-div">
<div v-if="!tableLoading">
<div v-if="loadMore" class="el-table__empty-block" @click="loadingMore"><span class="el-table__empty-text">点击加载更多</span>
</div>
<div v-if="!loadMore" class="el-table__empty-block"><span class="el-table__empty-text">没有更多了</span></div>
</div>
<div v-for="item in tableData" :key="item.id" class="execution">
<div class="avue-comment" :class="item.type === '2' ? 'avue-comment--reverse' : ''">
<div class="avatar-div">
<name-avatar v-if="item.type === '1'" scale="2" :name="item.nickName" />
<name-avatar v-if="item.type !== '1'" scale="2" :face-url="item.appLogo" />
</div>
<div class="avue-comment__main">
<div class="avue-comment__header">
<div class="avue-comment__create_time">{{ item.createTime }}</div>
</div>
<div class="avue-comment__body" :style="item.type === '2' ? 'background: #6BED72;' : ''">
<div v-if="item.repType === 'event' && item.repEvent === 'subscribe'">
<el-tag type="success" size="mini">关注</el-tag>
</div>
<div v-if="item.repType === 'event' && item.repEvent === 'unsubscribe'">
<el-tag type="danger" size="mini">取消关注</el-tag>
</div>
<div v-if="item.repType === 'event' && item.repEvent === 'CLICK'">
<el-tag size="mini">点击菜单</el-tag>
{{ item.repName }}
</div>
<div v-if="item.repType === 'event' && item.repEvent === 'VIEW'">
<el-tag size="mini">点击菜单链接</el-tag>
{{ item.repUrl }}
</div>
<div v-if="item.repType === 'event' && item.repEvent === 'scancode_waitmsg'">
<el-tag size="mini">扫码结果</el-tag>
{{ item.repContent }}
</div>
<div v-if="item.repType === 'text'">{{ item.repContent }}</div>
<div v-if="item.repType === 'image'">
<a target="_blank" :href="item.repUrl"><img :src="item.repUrl" style="width: 100px"></a>
</div>
<div v-if="item.repType === 'voice'">
<SvgIcon name="local-wx-voice" :size="80" @click="loadVideo(item)"></SvgIcon>
</div>
<div v-if="item.repType === 'video'" style="text-align: center">
<SvgIcon name="local-wx-video" :size="80" @click="loadVideo(item)"></SvgIcon>
</div>
<div v-if="item.repType === 'shortvideo'" style="text-align: center">
<svg-icon name="local-wx-video" :size="80" @click="loadVideo(item)"></svg-icon>
</div>
<div v-if="item.repType === 'location'">
<el-link
type="primary"
target="_blank"
:href="'https://map.qq.com/?type=marker&isopeninfowin=1&markertype=1&pointx='+item.repLocationY+'&pointy='+item.repLocationX+'&name='+item.repContent+'&ref=joolun'">
<img
:src="'https://apis.map.qq.com/ws/staticmap/v2/?zoom=10&markers=color:blue|label:A|'+item.repLocationX+','+item.repLocationY+'&key=PFFBZ-RBM3V-IEEPP-UH6KE-6QUQE-C4BVJ&size=250*180'">
<p /><i class="el-icon-map-location"></i>{{ item.repContent }}
</el-link>
</div>
<div v-if="item.repType === 'link'" class="avue-card__detail">
<el-link type="success" :underline="false" target="_blank" :href="item.repUrl">
<div class="avue-card__title"><i class="el-icon-link"></i>{{ item.repName }}</div>
</el-link>
<div class="avue-card__info" style="height: unset">{{ item.repDesc }}</div>
</div>
<div v-if="item.repType === 'news'" style="width: 300px">
<wx-news :obj-data="JSON.parse(item.content).articles"></wx-news>
</div>
<div v-if="item.repType === 'music'">
<el-link type="success" :underline="false" target="_blank" :href="item.repUrl">
<div class="avue-card__body" style="padding:10px;background-color: #fff;border-radius: 5px">
<div class="avue-card__avatar"><img :src="item.repThumbUrl" alt=""></div>
<div class="avue-card__detail">
<div class="avue-card__title" style="margin-bottom:unset">{{ item.repName }}</div>
<div class="avue-card__info" style="height: unset">{{ item.repDesc }}</div>
</div>
</div>
</el-link>
</div>
</div>
</div>
</div>
</div>
</div>
<div v-loading="sendLoading" class="msg-send">
<wx-reply :objData="objData"></wx-reply>
<el-button type="success" class="send-but" @click="sendMsg">发送(S)</el-button>
</div>
</div>
</el-dialog>
<el-dialog title="用户消息" v-model="visible" :close-on-click-modal="false" draggable>
<div v-loading="mainLoading" class="msg-main">
<div id="msg-div" class="msg-div">
<div v-if="!tableLoading">
<div v-if="loadMore" class="el-table__empty-block" @click="loadingMore"><span class="el-table__empty-text">点击加载更多</span></div>
<div v-if="!loadMore" class="el-table__empty-block"><span class="el-table__empty-text">没有更多了</span></div>
</div>
<div v-for="item in tableData" :key="item.id" class="execution">
<div class="avue-comment" :class="item.type === '2' ? 'avue-comment--reverse' : ''">
<div class="avatar-div">
<name-avatar v-if="item.type === '1'" scale="2" :name="item.nickName" />
<name-avatar v-if="item.type !== '1'" scale="2" :face-url="item.appLogo" />
</div>
<div class="avue-comment__main">
<div class="avue-comment__header">
<div class="avue-comment__create_time">{{ item.createTime }}</div>
</div>
<div class="avue-comment__body" :style="item.type === '2' ? 'background: #6BED72;' : ''">
<div v-if="item.repType === 'event' && item.repEvent === 'subscribe'">
<el-tag type="success" size="mini">关注</el-tag>
</div>
<div v-if="item.repType === 'event' && item.repEvent === 'unsubscribe'">
<el-tag type="danger" size="mini">取消关注</el-tag>
</div>
<div v-if="item.repType === 'event' && item.repEvent === 'CLICK'">
<el-tag size="mini">点击菜单</el-tag>
{{ item.repName }}
</div>
<div v-if="item.repType === 'event' && item.repEvent === 'VIEW'">
<el-tag size="mini">点击菜单链接</el-tag>
{{ item.repUrl }}
</div>
<div v-if="item.repType === 'event' && item.repEvent === 'scancode_waitmsg'">
<el-tag size="mini">扫码结果</el-tag>
{{ item.repContent }}
</div>
<div v-if="item.repType === 'text'">{{ item.repContent }}</div>
<div v-if="item.repType === 'image'">
<a target="_blank" :href="item.repUrl"><img :src="item.repUrl" style="width: 100px" /></a>
</div>
<div v-if="item.repType === 'voice'">
<SvgIcon name="local-wx-voice" :size="80" @click="loadVideo(item)"></SvgIcon>
</div>
<div v-if="item.repType === 'video'" style="text-align: center">
<SvgIcon name="local-wx-video" :size="80" @click="loadVideo(item)"></SvgIcon>
</div>
<div v-if="item.repType === 'shortvideo'" style="text-align: center">
<svg-icon name="local-wx-video" :size="80" @click="loadVideo(item)"></svg-icon>
</div>
<div v-if="item.repType === 'location'">
<el-link
type="primary"
target="_blank"
:href="
'https://map.qq.com/?type=marker&isopeninfowin=1&markertype=1&pointx=' +
item.repLocationY +
'&pointy=' +
item.repLocationX +
'&name=' +
item.repContent +
'&ref=joolun'
"
>
<img
:src="
'https://apis.map.qq.com/ws/staticmap/v2/?zoom=10&markers=color:blue|label:A|' +
item.repLocationX +
',' +
item.repLocationY +
'&key=PFFBZ-RBM3V-IEEPP-UH6KE-6QUQE-C4BVJ&size=250*180'
"
/>
<p />
<i class="el-icon-map-location"></i>{{ item.repContent }}
</el-link>
</div>
<div v-if="item.repType === 'link'" class="avue-card__detail">
<el-link type="success" :underline="false" target="_blank" :href="item.repUrl">
<div class="avue-card__title"><i class="el-icon-link"></i>{{ item.repName }}</div>
</el-link>
<div class="avue-card__info" style="height: unset">{{ item.repDesc }}</div>
</div>
<div v-if="item.repType === 'news'" style="width: 300px">
<wx-news :obj-data="JSON.parse(item.content).articles"></wx-news>
</div>
<div v-if="item.repType === 'music'">
<el-link type="success" :underline="false" target="_blank" :href="item.repUrl">
<div class="avue-card__body" style="padding: 10px; background-color: #fff; border-radius: 5px">
<div class="avue-card__avatar"><img :src="item.repThumbUrl" alt="" /></div>
<div class="avue-card__detail">
<div class="avue-card__title" style="margin-bottom: unset">{{ item.repName }}</div>
<div class="avue-card__info" style="height: unset">{{ item.repDesc }}</div>
</div>
</div>
</el-link>
</div>
</div>
</div>
</div>
</div>
</div>
<div v-loading="sendLoading" class="msg-send">
<wx-reply :objData="objData"></wx-reply>
<el-button type="success" class="send-but" @click="sendMsg">发送(S)</el-button>
</div>
</div>
</el-dialog>
</template>
<script setup lang="ts" name="wx-msg">
import { fetchList,addObj } from '/@/api/mp/wx-fans-msg'
import {useMessage} from "/@/hooks/message";
import {getMaterialVideo} from "/@/api/mp/wx-material";
import { fetchList, addObj } from '/@/api/mp/wx-fans-msg';
import { useMessage } from '/@/hooks/message';
import { getMaterialVideo } from '/@/api/mp/wx-material';
const WxReply = defineAsyncComponent(() => import("../wx-reply/index.vue"))
const WxNews = defineAsyncComponent(() => import("../wx-news/index.vue"))
const WxReply = defineAsyncComponent(() => import('../wx-reply/index.vue'));
const WxNews = defineAsyncComponent(() => import('../wx-news/index.vue'));
const NameAvatar = defineAsyncComponent(() => import("/@/components/NameAvatar/index.vue"))
const NameAvatar = defineAsyncComponent(() => import('/@/components/NameAvatar/index.vue'));
const visible = ref(false)
const visible = ref(false);
// loading
const mainLoading = ref(false)
const sendLoading = ref(false)
const mainLoading = ref(false);
const sendLoading = ref(false);
const loadMore = ref(false)
const loadMore = ref(false);
const objData = ref({
repType: 'text',
appId: ''
}) as any
repType: 'text',
appId: '',
}) as any;
const page = reactive({
total: 0, //
currentPage: 1, //
pageSize: 10, //
ascs: [], //
descs: 'create_time'//
})
total: 0, //
currentPage: 1, //
pageSize: 10, //
ascs: [], //
descs: 'create_time', //
});
const wxData = reactive({
appId: '',
wxUserId: ''
})
appId: '',
wxUserId: '',
});
const sendMsg = () => {
if (objData.value) {
if (objData.value.repType === 'news') {
if(objData.value.content.newsItem.length > 1){
useMessage().error("图文消息条数限制在1条以内已默认发送第一条")
}
objData.value.content.newsItem = [objData.value.content.newsItem[0]]
objData.value.content = JSON.stringify(objData.value.content)
}
sendLoading.value = true
addObj(Object.assign({
wxUserId: wxData.wxUserId,
appId: wxData.appId
}, objData.value)).then(() => {
tableData.value = []
getData()
}).finally(() => {
sendLoading.value = false
})
}
}
if (objData.value) {
if (objData.value.repType === 'news') {
if (objData.value.content.newsItem.length > 1) {
useMessage().error('图文消息条数限制在1条以内已默认发送第一条');
}
objData.value.content.newsItem = [objData.value.content.newsItem[0]];
objData.value.content = JSON.stringify(objData.value.content);
}
sendLoading.value = true;
addObj(
Object.assign(
{
wxUserId: wxData.wxUserId,
appId: wxData.appId,
},
objData.value
)
)
.then(() => {
tableData.value = [];
getData();
})
.finally(() => {
sendLoading.value = false;
});
}
};
const tableData = ref([] as any)
const tableData = ref([] as any);
const tableLoading = ref(false)
const tableLoading = ref(false);
const openDialog = (data: any) => {
wxData.wxUserId = data.wxUserId
wxData.appId = data.appId
objData.value.appId = data.appId
getData()
visible.value = true
}
wxData.wxUserId = data.wxUserId;
wxData.appId = data.appId;
objData.value.appId = data.appId;
getData();
visible.value = true;
};
const getData = () => {
tableLoading.value = true
fetchList({
...page,
...wxData
}).then(res=> {
const data = res.data.records.reverse()
tableData.value = [...data, ...tableData.value]
page.total = res.data.total
tableLoading.value = false
if (data.length < page.pageSize || data.length === 0) {
loadMore.value = false
}
})
}
tableLoading.value = true;
fetchList({
...page,
...wxData,
}).then((res) => {
const data = res.data.records.reverse();
tableData.value = [...data, ...tableData.value];
page.total = res.data.total;
tableLoading.value = false;
if (data.length < page.pageSize || data.length === 0) {
loadMore.value = false;
}
});
};
const loadVideo = (item) => {
getMaterialVideo({
mediaId: item.repMediaId,
appId: item.appId
}).then(response => {
const data = response.data
window.open(data.downUrl,'target','');
})
}
getMaterialVideo({
mediaId: item.repMediaId,
appId: item.appId,
}).then((response) => {
const data = response.data;
window.open(data.downUrl, 'target', '');
});
};
const loadingMore = () => {
page.currentPage = page.currentPage + 1
getData()
}
page.currentPage = page.currentPage + 1;
getData();
};
//
defineExpose({
openDialog
openDialog,
});
</script>
<style lang="scss" scoped>
@import './comment.scss';
@import './card.scss';
.msg-main {
margin-top: -30px;
padding: 10px;
margin-top: -30px;
padding: 10px;
}
.msg-div {
height: 50vh;
overflow: auto;
background-color: #eaeaea;
margin-left: 10px;
margin-right: 10px;
height: 50vh;
overflow: auto;
background-color: #eaeaea;
margin-left: 10px;
margin-right: 10px;
}
.msg-send {
padding: 10px;
padding: 10px;
}
.avatar-div {
text-align: center;
width: 80px;
text-align: center;
width: 80px;
}
.send-but {
float: right;
margin-top: 8px!important;
float: right;
margin-top: 8px !important;
}
</style>

View File

@ -1,92 +1,90 @@
<template>
<div class="news-home">
<div v-for="(news, index) in props.objData" :key="index" class="news-div">
<a v-if="index===0" target="_blank" :href="news.url">
<div class="news-main">
<div class="news-content">
<img class="material-img" :src="news.thumbUrl" width="280px" height="120px" />
<div class="news-content-title">
<span>{{ news.title }}</span>
</div>
</div>
</div>
</a>
<a v-if="index>0" target="_blank" :href="news.url">
<div class="news-main-item">
<div class="news-content-item">
<div class="news-content-item-title">{{ news.title }}</div>
<div class="news-content-item-img">
<img class="material-img" :src="news.thumbUrl" height="100%" />
</div>
</div>
</div>
</a>
</div>
</div>
<div class="news-home">
<div v-for="(news, index) in props.objData" :key="index" class="news-div">
<a v-if="index === 0" target="_blank" :href="news.url">
<div class="news-main">
<div class="news-content">
<img class="material-img" :src="news.thumbUrl" width="280px" height="120px" />
<div class="news-content-title">
<span>{{ news.title }}</span>
</div>
</div>
</div>
</a>
<a v-if="index > 0" target="_blank" :href="news.url">
<div class="news-main-item">
<div class="news-content-item">
<div class="news-content-item-title">{{ news.title }}</div>
<div class="news-content-item-img">
<img class="material-img" :src="news.thumbUrl" height="100%" />
</div>
</div>
</div>
</a>
</div>
</div>
</template>
<script setup lang="ts" name="wx-news">
const props = defineProps({
objData: {
type: Array,
default: () => []
}
})
objData: {
type: Array,
default: () => [],
},
});
</script>
<style lang="scss" scoped>
.news-home{
background-color: #FFFFFF;
width: 100%;
margin: auto;
.news-home {
background-color: #ffffff;
width: 100%;
margin: auto;
}
.news-main{
width: 100%;
margin: auto;
.news-main {
width: 100%;
margin: auto;
}
.news-content{
background-color: #acadae;
width: 100%;
position: relative;
.news-content {
background-color: #acadae;
width: 100%;
position: relative;
}
.news-content-title{
display: inline-block;
font-size: 12px;
color: #FFFFFF;
position: absolute;
left: 0px;
bottom: 0px;
background-color: black;
width: 98%;
padding: 1%;
opacity: 0.65;
white-space: normal;
box-sizing: unset!important
.news-content-title {
display: inline-block;
font-size: 12px;
color: #ffffff;
position: absolute;
left: 0px;
bottom: 0px;
background-color: black;
width: 98%;
padding: 1%;
opacity: 0.65;
white-space: normal;
box-sizing: unset !important;
}
.news-main-item{
background-color: #FFFFFF;
padding: 5px 0px;
border-top: 1px solid #eaeaea;
.news-main-item {
background-color: #ffffff;
padding: 5px 0px;
border-top: 1px solid #eaeaea;
}
.news-content-item{
position: relative;
.news-content-item {
position: relative;
}
.news-content-item-title{
display: inline-block;
font-size: 10px;
width: 70%;
margin-left: 1%;
white-space: normal
.news-content-item-title {
display: inline-block;
font-size: 10px;
width: 70%;
margin-left: 1%;
white-space: normal;
}
.news-content-item-img{
display: inline-block;
width: 25%;
background-color: #acadae;
margin-right: 1%;
.news-content-item-img {
display: inline-block;
width: 25%;
background-color: #acadae;
margin-right: 1%;
}
.material-img {
width: 100%;
width: 100%;
}
</style>

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