提交 bdcdf05f 作者: 毛细亚

Merge branch 'main'

---
description:
globs:
alwaysApply: false
---
# 项目结构说明
这是一个 H5的移动端页面 这是一个 H5的移动端页面 最大宽度是 380px 最小宽度是 360px 样所以需要用到 css 自适应 弹性伸缩
本项目为基于 Vue.js 的前端应用,主要目录结构如下:
- [src/](mdc:src):主源码目录,包括:
- [main.js](mdc:src/main.js):应用入口文件。
- [App.vue](mdc:src/App.vue):根组件,负责全局认证逻辑。
- [router/](mdc:src/router):路由配置,主文件为 [index.js](mdc:src/router/index.js)。
- [store/](mdc:src/store):Vuex 状态管理,主文件为 [index.js](mdc:src/store/index.js)。
- [api/](mdc:src/api):接口请求封装,示例:[user.js](mdc:src/api/user.js)。
- [utils/](mdc:src/utils):工具函数和请求封装,如 [request.js](mdc:src/utils/request.js)。
- [mixins/](mdc:src/mixins):Vue 混入逻辑,如 [external_userid.js](mdc:src/mixins/external_userid.js)。
- [views/](mdc:src/views):页面组件,如 [HomeView.vue](mdc:src/views/HomeView.vue)、[AboutView.vue](mdc:src/views/AboutView.vue)。
- [styles/](mdc:src/styles):全局和局部样式文件。
- [components/](mdc:src/components):可复用组件(当前为空)。
- [assets/](mdc:src/assets):静态资源(如图片等)。
- @docs: 文档内容
- [public/](mdc:public):静态资源目录,供打包时复制到最终输出。
- [package.json](mdc:package.json):项目依赖和脚本配置。
- [README.md](mdc:README.md):项目说明文档。
如需详细了解某一目录或文件,可参考上述路径。
# 技术库
- 前端框架 vue 2.6
- 脚手架 用 vue-cli 5.0.0 创建
- 路由 使用 vue-router 3.5.1 管理路由
- 状态管理 使用 vuex 3.6.2 管理状态
- 使用 element-ui 2.15.6 作为 UI 库
- axios 请求 api
- 基于企业微信 新版本 jssdk 来进行开发 企业微信的变量是 `ww`
# 开发规范
- 组件命名规范
- Props类型声明 Props 尽量用规范的写法 并且声明默认值
- 响应式最佳实践
- 生命周期规范
- 事件处理规范
- 样式作用域
- 使用 try/catch 块处理异步操作
- 使用组件化的概念 尽量按照功能切分成多个组件 一个组件的代码不要太多
工程化要求:
- ESLint + Prettier
- 性能优化
- 代码分割
- 懒加载实现
# UI 规范
因为 企业微信侧边栏 宽度有限 而且是一个 H5 移动端的页面 最大宽度是 380px 最小宽度 是 360px 所以尽量使用 自适应的样式来进行开发
---
description:
globs:
alwaysApply: false
---
...@@ -5,5 +5,7 @@ VUE_APP_BASE_API = '/dev-api' ...@@ -5,5 +5,7 @@ VUE_APP_BASE_API = '/dev-api'
VUE_APP_URL = 'http://localhost:9528' VUE_APP_URL = 'http://localhost:9528'
# 掌权登录跳转url # 掌权登录跳转url
NODE_ENV = 'development'
ENV = 'development'
VUE_APP_ZQLOGIN_URL = 'http://zq.zwwlkj03.top' isTestWx = true
\ No newline at end of file
# just a flag # just a flag
ENV = 'production' ENV = 'production'
NODE_ENV = 'production'
# base api # base api
VUE_APP_BASE_API = '/api/' VUE_APP_BASE_API = '/api/'
# 掌权登录跳转url
VUE_APP_ZQLOGIN_URL = 'http://zq.wozhangwan.com'
# build src
VUE_APP_BUILD_DIR = 'dist'
# just a flag
NODE_ENV = 'staging'
ENV = 'staging'
# base api
VUE_APP_BASE_API = '/api/'
module.exports = {
root: true,
env: {
node: true
},
'extends': [
'plugin:vue/essential',
'eslint:recommended'
],
parserOptions: {
parser: '@babel/eslint-parser'
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
}
}
.DS_Store .DS_Store
node_modules node_modules
/dist /dist
/company_app
# local env files # local env files
...@@ -21,3 +22,4 @@ pnpm-debug.log* ...@@ -21,3 +22,4 @@ pnpm-debug.log*
*.njsproj *.njsproj
*.sln *.sln
*.sw? *.sw?
# cebianlan # 基于企业微信客户端开发 企业微信侧边栏H5 网页应用
基于企业微信客户端 开发侧边栏功能 企业微信的文档 [企业微信文档]([链接地址](https://developer.work.weixin.qq.com/document/path/94352) )
## 项目介绍
这是一个 H5的移动端页面 这是一个 H5的移动端页面 最大宽度是 380px 最小宽度是 360px 样所以需要用到 css 自适应 弹性伸缩 企微微信中内嵌掌微第三方页面 来支持开发企业微信侧边栏功能
## 项目结构
## Project setup - @src/:主源码目录,包括:
``` - @main.js:应用入口文件。
pnpm install - @App.vue:根组件,负责全局认证逻辑。
``` - @router/:路由配置,主文件为 @index.js。
- @store/:Vuex 状态管理,主文件为 @index.js。
- @api/:接口请求封装,示例:@user.js。
- @utils/:工具函数和请求封装,如 @request.js。
- @mixins/:Vue 混入逻辑,如 @external_userid.js。
- @views/:页面组件,如 @HomeView.vue、@AboutView.vue。
- @styles/:全局和局部样式文件。
- @components/:可复用组件(当前为空)。
- @assets/:静态资源(如图片等)。
- @docs: 文档内容
- @public/:静态资源目录,供打包时复制到最终输出。
- @package.json:项目依赖和脚本配置。
- @README.md:项目说明文档。
### Compiles and hot-reloads for development
```
pnpm run serve
```
### Compiles and minifies for production 如需详细了解某一目录或文件,可参考上述路径。
```
pnpm run build
```
### Lints and fixes files ## 技术库
``` - 前端框架 vue 2.6
pnpm run lint - 脚手架 用 vue-cli 5.0.0 创建
``` - 路由 使用 vue-router 3.5.1 管理路由
- 状态管理 使用 vuex 3.6.2 管理状态
- 使用 element-ui 2.15.6 作为 UI 库
- axios 请求 api
- 基于企业微信 新版本 jssdk 来进行开发 企业微信的变量是 `ww`
## 开发规范
- 组件命名规范
- Props类型声明 Props 尽量用规范的写法 并且声明默认值
- 响应式最佳实践
- 生命周期规范
- 事件处理规范
- 样式作用域
- 使用 try/catch 块处理异步操作
- 使用组件化的概念 尽量按照功能切分成多个组件 一个组件的代码不要太多
工程化要求:
### Customize configuration - ESLint + Prettier
See [Configuration Reference](https://cli.vuejs.org/config/). - 性能优化
- 代码分割
- 懒加载实现
## UI 规范
因为当前页面是在企微的侧边栏中打开的 所以需要适配企微的侧边栏样式 企微侧边栏 最大的宽度是 320px 所有页面需要适配320px的宽度,必须要使用自适应的方法 来开发页面 不能写死超过 320px 的宽度 宽度的样式一切都是可伸缩的
\ No newline at end of file
<!DOCTYPE html>
<html lang="">
<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">
<link rel="icon" href="favicon.ico">
<title>company_app</title>
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0,shrink-to-fit=no,user-scalable=no"> -->
<script src="https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script>
<script defer src="static/js/chunk-vendors.js"></script><script defer src="static/js/app.js"></script></head>
<body>
<noscript>
<strong>We're sorry but company_app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
</body>
</html>
{ {
"name": "cebianlan", "name": "company_app",
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "serve": "vue-cli-service serve",
"build": "vue-cli-service build", "build:prod": "vue-cli-service build --mode prod",
"build:stage": "vue-cli-service build --mode staging",
"lint": "vue-cli-service lint" "lint": "vue-cli-service lint"
}, },
"dependencies": { "dependencies": {
"@wecom/jssdk": "^2.3.1",
"axios": "^1.9.0", "axios": "^1.9.0",
"babel-plugin-component": "^1.1.1", "babel-plugin-component": "^1.1.1",
"bi-eleme": "^2.4.4", "bi-eleme": "^2.4.4",
"bi-element-ui": "^1.5.2", "bi-element-ui": "^1.5.2",
"clipboard": "^2.0.11",
"core-js": "^3.8.3", "core-js": "^3.8.3",
"cos-js-sdk-v5": "^1.10.1",
"dingtalk-jsapi": "^3.1.0",
"element-ui": "^2.15.14", "element-ui": "^2.15.14",
"js-cookie": "^3.0.5",
"lib-flexible": "^0.3.2",
"lodash": "^4.17.21",
"moment": "^2.29.1", "moment": "^2.29.1",
"postcss-plugin-px2rem": "^0.8.1",
"sass": "^1.89.0", "sass": "^1.89.0",
"sass-loader": "^16.0.5", "sass-loader": "^16.0.5",
"vconsole": "^3.15.1",
"vue": "^2.6.14", "vue": "^2.6.14",
"vue-router": "^3.5.1", "vue-router": "^3.5.1",
"vuex": "^3.6.2" "vuex": "^3.6.2"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.12.16", "@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@vue/cli-plugin-babel": "~5.0.0", "@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-plugin-router": "~5.0.0", "@vue/cli-plugin-router": "~5.0.0",
"@vue/cli-plugin-vuex": "~5.0.0", "@vue/cli-plugin-vuex": "~5.0.0",
"@vue/cli-service": "~5.0.0", "@vue/cli-service": "~5.0.0",
"eslint": "^7.32.0", "element-theme-chalk": "^2.15.14",
"eslint-plugin-vue": "^8.0.3",
"vue-template-compiler": "^2.6.14" "vue-template-compiler": "^2.6.14"
} }
} }
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -6,12 +6,13 @@ ...@@ -6,12 +6,13 @@
<meta name="viewport" content="width=device-width,initial-scale=1.0"> <meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> <link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title> <title><%= htmlWebpackPlugin.options.title %></title>
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0,shrink-to-fit=no,user-scalable=no"> -->
<script src="https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script>
</head> </head>
<body> <body>
<noscript> <noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript> </noscript>
<div id="app"></div> <div id="app"></div>
<!-- built files will be auto injected -->
</body> </body>
</html> </html>
<template> <template>
<div id="app"> <div id="app" class="mobile-app-wrapper">
<router-view/>
<div class="mobile-menu-bar" v-if="token && external_userid && showMemberId">
<!-- 临时调试信息 -->
<el-menu
:default-active="selectedPath"
mode="horizontal"
class="mobile-el-menu"
background-color="#fff"
router
@select="handleSelect"
>
<el-menu-item v-for="item in menuList" :key="item.path" :index="item.path" class="mobile-menu-item">
{{ item.label }}
</el-menu-item>
</el-menu>
<!-- 绑定的 w 账号 -->
<bindUserList />
</div>
<div class="mobile-content">
<router-view></router-view>
</div>
</div> </div>
</template> </template>
<script>
<style> import bindUserList from '@/views/components/bindGameAccount/bindUserList.vue'
#app { import { getToken } from '@/utils/auth'
font-family: Avenir, Helvetica, Arial, sans-serif; import { mapState } from 'vuex'
-webkit-font-smoothing: antialiased; import Cookies from 'js-cookie'
-moz-osx-font-smoothing: grayscale; export default {
text-align: center; name: 'App',
color: #2c3e50; components: {
bindUserList
},
data() {
return {
menuList: [
{
label: '客户信息',
path: '/userInfo'
},
// {
// label: '快捷回复',
// path: '/quickReply'
// },
// {
// label: '礼包记录',
// path: '/giftRecord'
// },
// {
// label: '申请记录',
// path: '/applyRecord'
// },
// {
// label: '快捷发送',
// path: '/quickSend'
// },
// {
// label: '通讯录',
// path: '/addressBook'
// },
],
selectedPath: '/userInfo',
showMemberId: false,
}
},
computed:{
...mapState('user',['external_userid','token']),
},
watch: {
'$route.path'(val) {
// 处理各种可能的路径情况
if (val === '/' || val === '/index.html') {
this.selectedPath = '/userInfo'
} else {
this.selectedPath = val
}
console.log('路由变化:', val, '选中路径:', this.selectedPath)
},
// 监听 external_userid 的变化,确保界面及时更新
external_userid: {
handler(newVal) {
if (newVal) {
this.$nextTick(() => {
this.showMemberId = true
console.log('external_userid 已设置:', newVal, window.location.href, this.token,Cookies.get('token'))
// 强制更新组件
this.$forceUpdate()
})
}
},
immediate: true
}
},
mounted() {
// 初始化时处理路径
const currentPath = this.$route.path
if (currentPath === '/' || currentPath === '' || currentPath === '/index.html') {
this.selectedPath = '/userInfo'
} else {
this.selectedPath = currentPath
}
console.log('创建时路径:', currentPath, '选中路径:', this.selectedPath)
},
methods:{
handleSelect(key, keyPath) {
console.log('菜单选择:', key, keyPath, window.location.href)
}
}
} }
</script>
nav { <style scoped>
padding: 30px; #app{
width: 100%;
height: 100%;
background: #fff;
} }
.mobile-app-wrapper {
nav a { width: 100%;
margin: 0 auto;
background: #f0f2f5;
min-height: 100vh;
display: flex;
flex-direction: column;
box-shadow: 0 0 12px rgba(0,0,0,0.04);
}
.mobile-menu-bar {
background: #fff;
border-bottom: 1px solid #f0f0f0;
box-shadow: 0 2px 8px #f0f1f2;
z-index: 10;
}
.mobile-el-menu {
border: none;
background: #fff;
display: flex;
justify-content: flex-start;
padding-left: 16px;
}
.mobile-menu-item {
font-size: 14px ;
padding: 0 16px !important;
min-width: 0;
flex: none;
width: auto;
max-width: 120px;
text-align: center;
margin-right: 8px;
transition: all 0.3s ease;
}
.mobile-el-menu .el-menu-item.is-active {
font-weight: bold; font-weight: bold;
color: #2c3e50;
} }
.mobile-content {
nav a.router-link-exact-active { flex: 1;
color: #42b983; overflow-y: auto;
}
.mobile-content > div {
background: #fff;
border-radius: 8px;
min-height: 60vh;
padding: 10px;
}
.el-menu--horizontal>.el-menu-item{
height: 50px;
line-height: 50px;
}
body {
background: #f0f2f5;
} }
</style> </style>
import request from '@/utils/request'
import store from '@/store/index'
// 游戏业务所属的接口信息
// 所属分组下拉
function returnApi(api){
return '/sidebar' + api
}
export function cross_systemRequest(data) {
!data.noApi ? data.api = '/api' + data.api : ''
return request({
url: '/sidebar/cross_system/request',
method: 'post',
data
})
}
// 请求角色详情
export function memberView(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/member/view',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 修改手机号
export function bindMobile(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/member/bindMobile',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 角色列表
export function roleList(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/role/getList',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 绑定掌游账号
export function zyouBind(data) {
return request({
url: returnApi('/external_user/zyouBind'),
method: 'post',
data
})
}
// 订单列表
export function orderList(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/order/list',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 订单金额
export function todayOrder(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/member/todayOrder',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 补单和补回调
export function completionOrder(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/order/completionOrder',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 退款提交申请
export function refundRequest(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/order/addRefundRequest',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 退款申请记录
export function refundRecord(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/order/getRefundRequestList',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 退款详情
export function refundRequestLog(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/order/refundRequestProcess',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 下拉请求
export function selectSearch(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/searchcondition/search',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 账号维度推广游戏列表
export function memberExtensionGameList(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/member/memberExtensionGameList',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 充值
// 账号维度推广游戏列表
export function getAmountByTime(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/member/getAmountByTime',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 违规记录
export function violationList(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/member/violationList',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 重置密码
export function autoResetPassword(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/member/autoResetPassword',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 重置密码加密
export function passwardEncryption(data) {
return request({
url: '/game/session/zyouAutoResetPassword',
method: 'post',
data
})
}
// VIP自助工具
export function createVipUrl(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/member/createVipUrl',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 活动类型
export function giftTypeList(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/searchcondition/search',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 充值活动列表
export function activeList(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/member/getVipBagCodeRuleListByRole',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 活动详情
export function giftDetailsData(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/member/getRoleConditionByRuleAndRole',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 申请礼包
export function giftBagApply(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/member/giftBagApply',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 礼包检测
export function checkRoleReceivedBag(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/role_gift_bag/checkRoleReceivedBag',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 礼包列表
export function emailGiftList(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/member/giftBagApplyIndex',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 易主标签查询
export function getMemberLabel(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/member/getMemberLabel',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 修改易主标签
export function editMemberLabel(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/member/editMemberLabel',
params: data
}).then((res) => {
resovle(res)
})
})
}
// // 转端接口
// export function getMemberLink(data) {
// return new Promise((resovle, reject) => {
// cross_systemRequest({
// system: 'zhangyou',
// api: '/member/getMemberLink',
// params: data
// }).then(res => {
// resovle(res)
// })
// })
// }
// 转端接口
export function getMemberLink(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/member/getMemberLink',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 转游接口
export function getLandingPageMemberLink(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/member/getLandingPageMemberLink',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 转游接口
export function getLandingPageConfig(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/member/getLandingPageConfig',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 渠道列表单独渠道KEY
export function channelList(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/channel/channelList',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 工单
// 任务列表
export function taskIndex(data) {
return new Promise((resovle, reject) => {
data.zw_user_id = store.state.user.userInfo.id
cross_systemRequest({
system: 'zhangyou',
api: '/operator_task/index',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 任务详情
export function taskDetails(data) {
return new Promise((resovle, reject) => {
data.zw_user_id = store.state.user.userInfo.id
cross_systemRequest({
system: 'zhangyou',
api: '/operator_task/info',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 分配
export function taskAssign(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/operator_task/assign',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 完成任务
export function taskTrack(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/operator_task/track',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 结果列表
export function taskRecord(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/operator_task/logs',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 备注
export function logsSave(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/operator_task_log/save',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 角色累充
export function RoleTodayOrder(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/role/todayOrder',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 用户充值
export function memberOrder(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/member/memberOrder',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 下拉加载
export function searchcondition(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/searchcondition/search',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 误操作列表
export function misoperationIndex(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/mistake_operation_request/list',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 添加误操作
export function addErrorHandle(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/mistake_operation_request/add',
params: data
}).then((res) => {
resovle(res)
})
})
}
export function updateErrorHandle(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/misoperation/update',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 操作数量
export function numErrorHandle(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/misoperation/num',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 操作数量新
export function operationCount(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/mistake_operation_request/operationCount',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 任务消息读取
export function taskRead(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/operator_task/read',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 任务消息状态
export function taskReadStatus(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/operator_task/readStatus',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 撤回消息
export function cancelRefundRequest(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/order/cancelRefundRequest',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 举报列表
export function reportIndex(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/admin/report_request/list',
params: data,
noApi: true
}).then((res) => {
resovle(res)
})
})
}
// 玩家举报
export function playerReport(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/report_request/waitList',
params: data,
noApi: true
}).then((res) => {
resovle(res)
})
})
}
// 审批记录
export function reportProcess(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/report_request/process',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 撤销举报
export function reportCancel(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/report_request/cancel',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 新增举报
export function reportAdd(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/report_request/add',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 申诉列表
export function appealList(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/appeal_request/list',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 新增申诉
export function appealAdd(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/appeal_request/add',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 撤销申诉
export function appealCancel(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/appeal_request/cancel',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 申诉记录
export function appealProcess(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/appeal_request/process',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 玩家举报审批记录
export function gamerReportProcess(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/report_request/process',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 角色列表Holo 实时性较高
export function getRoleHoLo(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/role/getListHoLo',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 角色列表 待请求
export function memberTaskStatus(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/operator_task/memberTaskStatus',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 举报申请列表
export function report_request_list(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/report_request/list',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 举报申请驳回或者通过
export function report_request_approval(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/report_request/approval',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 游戏类型下的游戏列表 游戏类型:安卓 h5 ios
export function getTransferRecallGameList(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/member/getTransferRecallGameList',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 转端和召回 游戏类型列表
export function getGameConfig(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/game/getGameConfig',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 召回的时候染色
export function recallChannelSeq(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/channel/recallChannelSeq',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 获取游戏信息
export function getGameInfo(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/game/info',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 新增渠道
export function addChannel(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/channel/addDistributorChannelByZm',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 一键发送召回渠道链接
export function quickRecallChannelLink(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/channel/quickRecallChannelLink',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 转端发送落地页
export function getLandingPageTransfer(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/member/getLandingPageTransfer',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 工作台关联客服
export function bindUserSelfAdd(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/member_bind_cser/selfAdd',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 关联客服列表
export function bindUserList(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/member_bind_cser/list',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 新增关联客服
export function bindUserAdd(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/member_bind_cser/add',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 删除关联客服
export function bindUserDelete(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/member_bind_cser/delete',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 调用掌游的日志中心
export function getSystemModelLog(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/member_bind_cser/getSystemModelLog',
params: data
}).then((res) => {
resovle(res)
})
})
}
export function getMemberTransStatus(data) {
// 转端文档 获取W账号的转端状态 如果状态是 false 表示不允许转端 在工作台 发送游戏 里面转端里 点开发送的时候 提示 当前w账号不满足转端要求,请联系组长处理
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/member/getMemberTransStatus',
params: data
}).then((res) => {
resovle(res)
})
})
}
export function getTaskTracer(data) {
// 获取运营任务的跟进人 参数 member_id
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/operator_task/getTaskTracer',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 用户触达 发送客服号添加消息的日志
export function getTaskTracerTouch(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/operator_task_log/touch',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 添加一条任务跟进记录
export function getTaskTracerTouchAdd(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/operator_task_log/add',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 审批组流程下拉
export function approval_group_flow_list(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/approval_group_flow/options',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 审批人员表格
export function approval_group_flow_user(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/approval_group_flow/users',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 保存转端提交
export function approval_group_flow_add(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/member_trans_request/add',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 转端申请列表
export function member_trans_request_list(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/member_trans_request/list',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 转端申请审批记录
export function member_trans_request_process(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/member_trans_request/process',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 转区列表
export function transfer_server_request_list(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/transfer_server_request/list',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 转区申请
export function transfer_server_request_add(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/transfer_server_request/add',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 转区申请节点
export function transfer_server_request_process(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/transfer_server_request/process',
params: data
}).then((res) => {
resovle(res)
})
})
}
export function getMainGameInfo(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/api/service_wechat/getMainGameInfo',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 掌游标签搜索
export function roleLabelSearch(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/role/labelSearch',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 掌游标签列表
export function roleGetRoleLabel(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/role/getRoleLabel',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 编辑角色标签
export function editRoleLabel(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/role/editRoleLabel',
params: data
}).then((res) => {
resovle(res)
})
})
}
// 编辑角色标签
export function getRoleLabelCreate(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/role/getRoleLabelCreate',
params: data
}).then((res) => {
resovle(res)
})
})
}
export function ruleList(data) {
data.zw_user_id = store.state.user.userInfo.id
return new Promise((resovle, reject) => {
cross_systemRequest({
system: 'zhangyou',
api: '/member_trans_request/ruleList',
params: data
}).then((res) => {
resovle(res)
})
})
}
import request from "@/utils/request";
// 游戏业务所属的接口信息
// 所属分组下拉
export function cross_systemRequest(data) {
data.api = "/api" + data.api;
data.params
? (data.params.corp_id = window.localStorage.getItem("corp_id") || "")
: "";
return request({
url: "/admin/cross_system/request",
method: "post",
data,
});
}
// 搜索下拉
export function searchcondition(data) {
return new Promise((resovle, reject) => {
cross_systemRequest({
system: "pigeon",
api: "/api/searchcondition/index",
params: data,
}).then((res) => {
resovle(res);
});
});
}
\ No newline at end of file
import request from '@/utils/request' import request from '@/utils/request'
import axios from 'axios'
// import { getSignatureData } from '@wecom/jssdk'
export function cross_systemRequest(data) {
!data.noApi ? data.api = '/api' + data.api : ''
return request({
url: '/api/cross_system/request',
method: 'post',
headers:{
"Corp-Id":"wweaefe716636df3d1"
},
data
})
}
// 获取 企微登录的信息
export function getAuthUser(data) { export function getAuthUser(data) {
return request({ return request({
url: '/api/agent/getAuthUser', url: '/api/sidebar_login/workWeiXin',
method: 'post',
data
})
}
// 获取组织列表
export function getOrganization(data) {
return axios.post('https://zq.zwwlkj03.top/api/login/organization',data)
}
// 获取签名信息
export function getSignature(data) {
return request({
url: '/sidebar/work_wei_xin/signature',
method: 'post',
data
})
}
// 上传接口
export function uploadCos(params) {
return request({
url: '/api/common/getCosSts',
method: 'get',
params
})
}
// 请求企业配置
export function companyviewConfig(data) {
return request({
url: '/api/corp/viewConfig',
method: 'post', method: 'post',
data data
}) })
} }
// 下线
export function logout(data) {
return request({
url: '/sidebar/work_wei_xin/logout',
method: 'post',
data
})
}
// 客户绑定掌游账号列表
import request from '@/utils/request'
function returnApi(api) {
return '/sidebar' + api
}
// w 账号绑定列表
export function zyouBindMember(data) {
return request({
url: returnApi('/external_user/zyouBindMember'),
method: 'post',
data
})
}
// 检查账号绑定
export function checkZyouBind(data) {
return request({
url: returnApi('/external_user/checkZyouBind'),
method: 'post',
data
})
}
// 绑定掌游账号
// 绑定掌游账号
export function zyouBind(data) {
return request({
url: returnApi('/external_user/zyouBind'),
method: 'post',
data
})
}
export function detailsInfoRequest(data) {
return request({
url: returnApi('/external_user/info'),
method: 'post',
data
})
}
// 是否转端
export function toTransfer(data) {
return request({
url: returnApi('/external_user/toTransfer'),
method: 'post',
data
})
}
// 同步智能标签
export function syncSessionIntelTag(data) {
return request({
url: '/sidebar/group_tag_detail/syncSessionIntelTag',
method: 'post',
data
})
}
// 关联客服
export function memberBindCser(data) {
return request({
url: returnApi('/external_user/memberBindCser'),
method: 'post',
data
})
}
// 修改用户信息
export function editUser(data) {
return request({
url: returnApi('/external_user/edit'),
method: 'post',
data
})
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="50px" height="50px" viewBox="0 0 50 50" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>待审批</title>
<g id="游戏" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="我的任务-撤销页" transform="translate(-404, -461)" fill-rule="nonzero">
<g id="编组-4备份-2" transform="translate(132, 411.96)">
<g id="待审批" transform="translate(272, 49.04)">
<rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="50" height="50"></rect>
<path d="M48.9604167,18.1563095 L41.587381,6.53083335 C40.9435714,5.51708335 39.5982143,5.21714287 38.5814286,5.85535713 L1.78476191,29.1335714 C0.770773828,29.777381 0.471071436,31.1227381 1.10791665,32.1336905 L8.48095239,43.7606548 C9.12482144,44.7718453 10.470119,45.0715477 11.4841667,44.4333929 L48.2822024,21.1567857 C49.2989881,20.512619 49.6044643,19.1689286 48.9604167,18.1563095 Z M47.4918452,19.907381 L10.6938095,43.1870238 C10.3683333,43.3920833 9.94232144,43.2960714 9.73726191,42.9719643 L2.36422617,31.3450595 C2.15910713,31.0195238 2.25517856,30.5949405 2.58065479,30.3870833 L39.380119,7.10886904 C39.7058929,6.90517856 40.1332143,7.00142856 40.3352976,7.32553569 L47.711369,18.9522619 C47.9092262,19.2707738 47.8117857,19.6981548 47.4918452,19.907381 Z M15.7707738,12.5301786 L16.3818452,13.9957143 L17.1735714,12.6204167 L18.7553571,12.4927381 L17.6897619,11.313869 L18.0526786,9.77208335 L16.6069048,10.4219643 L15.2488095,9.6 L15.4208333,11.1790476 L14.2161905,12.2060714 L15.7707738,12.5301786 L15.7707738,12.5301786 Z M25.1401786,8.16726191 L24.3800595,6.77196431 L23.73625,8.22470239 L22.1730357,8.52303569 L23.3532738,9.58142856 L23.1495833,11.1546429 L24.5263095,10.3586905 L25.9620833,11.04 L25.6307738,9.48541665 L26.7191667,8.33232144 L25.1401786,8.16726191 Z M39.4247619,31.540119 L38.1668452,30.5733333 L38.16125,32.1581548 L36.8475595,33.0489286 L38.3605357,33.5479762 L38.8064881,35.0695238 L39.7444643,33.7888095 L41.3320833,33.8332738 L40.3999405,32.5455357 L40.9377381,31.0581548 L39.4247619,31.540119 L39.4247619,31.540119 Z M34.2903571,37.8589286 L33.6909524,36.3889881 L32.8861905,37.75875 L31.3057738,37.8734524 L32.361369,39.0580357 L31.9855952,40.5982143 L33.4397619,39.9629762 L34.7923214,40.8032738 L34.6330357,39.2228571 L35.8376786,38.1974405 L34.2903571,37.8589286 L34.2903571,37.8589286 Z M24.884881,42.1558333 L25.6380357,43.5569643 L26.294881,42.1083929 L27.8580952,41.8289286 L26.6848214,40.758869 L26.900119,39.1870833 L25.5175595,39.9688095 L24.0889881,39.2775595 L24.4073214,40.8291071 L23.3030952,41.9780357 L24.884881,42.1558333 L24.884881,42.1558333 Z M10.7956548,18.6727381 L12.046369,19.655119 L12.0649405,18.0689286 L13.3844643,17.1825595 L11.879881,16.6733333 L11.4452976,15.1445833 L10.4959524,16.4166667 L8.90833335,16.3592262 L9.82767856,17.6529167 L9.27964287,19.1445238 L10.7956548,18.6727381 L10.7956548,18.6727381 Z M5.20952383,25.5207738 C5.04327383,18.8059524 8.30892861,12.1672024 14.3926786,8.31934521 C20.4777976,4.47142856 27.8752976,4.36238091 33.8844048,7.37720239 L35.3357738,6.45922617 C33.5575,5.46541665 31.6443453,4.73815474 29.6294048,4.28636904 C26.9373214,3.68113096 24.1952977,3.60529761 21.4845833,4.05130952 C18.6779167,4.51583335 16.0247024,5.52845239 13.6009524,7.06446431 C11.178631,8.6004167 9.12482144,10.562381 7.50416665,12.900119 C5.93517856,15.1545833 4.83238096,17.6659524 4.22571431,20.3535714 C3.77392861,22.3655357 3.61327383,24.4049405 3.75392856,26.437381 L5.20952383,25.5207738 Z M44.7254167,24.4939881 C44.898869,31.2088095 41.6332143,37.8475595 35.5494643,41.6940476 C29.4657143,45.546131 22.0669048,45.652381 16.0591071,42.637619 L14.6049405,43.5569643 C16.3832143,44.5479167 18.2977381,45.2767262 20.3129762,45.7283929 C23.0047619,46.333631 25.7468452,46.4125 28.4575,45.9634524 C31.2641667,45.498869 33.9174405,44.4876786 36.3397619,42.9516667 C38.7620833,41.4156547 40.8158929,39.4536905 42.4379167,37.117381 C44.001131,34.860119 45.1039286,32.3503571 45.7091667,29.6641071 C46.1623214,27.6505357 46.3202381,25.6097619 46.1795238,23.577381 L44.7254167,24.4939881 Z M18.781131,15.243631 C20.485,14.1680357 22.3593453,13.5941667 24.2410714,13.4795238 L26.4869048,12.0595833 C23.5195238,11.7096429 20.5480357,12.3780953 17.9838095,13.9973214 C15.4266071,15.6149405 13.5520833,18.0172619 12.6013095,20.8453571 L14.8457738,19.4256548 C15.7579762,17.7675596 17.0789286,16.3220238 18.781131,15.243631 Z M31.1595238,34.7697619 C29.4556548,35.8483929 27.5827381,36.4220238 25.7010119,36.5366667 L23.4564881,37.9566071 C26.4225,38.3065476 29.392619,37.6366667 31.9582143,36.0174405 C34.5154167,34.40125 36.3899405,31.9975 37.3392857,29.1694048 L35.0961905,30.5921429 C34.1841071,32.2427977 32.8617857,33.6941667 31.1595238,34.7697619 Z" id="形状" fill="#FFA81D"></path>
<path d="M11.9912389,25.7519943 C12.3592389,25.9279943 12.7072389,26.1059943 13.0352389,26.2859943 C13.3632389,26.4659943 13.5432389,26.5779943 13.5752389,26.6219943 C13.6072389,26.6659943 13.6232389,26.7079943 13.6232389,26.7479943 C13.6232389,26.8519943 13.5592389,26.9079943 13.4312389,26.9159943 C13.3032389,26.9239943 13.1652389,26.9759943 13.0172389,27.0719943 C12.8692389,27.1679943 12.6632389,27.3199943 12.3992389,27.5279943 C11.8072389,28.0159943 11.1852389,28.4319943 10.5332389,28.7759943 C9.88123888,29.1199943 9.50323888,29.2919943 9.39923888,29.2919943 C9.37523888,29.2919943 9.36323888,29.2779943 9.36323888,29.2499943 C9.36323888,29.2219943 9.40723888,29.1719943 9.49523888,29.0999943 C10.1432389,28.5639943 10.6472389,28.0379943 11.0072389,27.5219943 C11.3672389,27.0059943 11.6952389,26.4159943 11.9912389,25.7519943 Z M15.5312389,28.2599943 L14.1872389,28.2599943 C14.0272389,28.2599943 13.8832389,28.3039943 13.7552389,28.3919943 L13.4432389,27.8279943 C13.6352389,27.8519943 13.8352389,27.8639943 14.0432389,27.8639943 L15.5312389,27.8639943 L15.5312389,26.8559943 C15.5312389,26.4559943 15.5232389,26.0999943 15.5072389,25.7879943 C15.7632389,25.7879943 16.0892389,25.8039943 16.4852389,25.8359943 C16.8812389,25.8679943 17.1172389,25.9039943 17.1932389,25.9439943 C17.2692389,25.9839943 17.3072389,26.0319943 17.3072389,26.0879943 C17.3072389,26.1839943 17.2072389,26.2679943 17.0072389,26.3399943 L17.0072389,27.8639943 L17.9312389,27.8639943 C18.0032389,27.7199943 18.1012389,27.5439943 18.2252389,27.3359943 C18.3492389,27.1279943 18.4272389,27.0119943 18.4592389,26.9879943 C18.4912389,26.9639943 18.5272389,26.9519943 18.5672389,26.9519943 C18.6792389,26.9519943 18.9472389,27.1179943 19.3712389,27.4499943 C19.7952389,27.7819943 20.0072389,28.0119943 20.0072389,28.1399943 C20.0072389,28.2199943 19.9392389,28.2599943 19.8032389,28.2599943 L17.0072389,28.2599943 L17.0072389,30.1079943 L18.5312389,30.1079943 C18.5632389,30.0439943 18.6652389,29.8779943 18.8372389,29.6099943 C19.0092389,29.3419943 19.1112389,29.1939943 19.1432389,29.1659943 C19.1752389,29.1379943 19.2072389,29.1239943 19.2392389,29.1239943 C19.3432389,29.1239943 19.6272389,29.3159943 20.0912389,29.6999943 C20.5552389,30.0839943 20.7872389,30.3239943 20.7872389,30.4199943 C20.7872389,30.4759943 20.7192389,30.5039943 20.5832389,30.5039943 L18.8432389,30.5039943 C18.8192389,30.5759943 18.7512389,30.6319943 18.6392389,30.6719943 L18.6392389,32.0519943 L18.7592389,32.0519943 C18.8552389,31.8759943 18.9612389,31.6999943 19.0772389,31.5239943 C19.1932389,31.3479943 19.2632389,31.2479943 19.2872389,31.2239943 C19.3112389,31.1999943 19.3472389,31.1879943 19.3952389,31.1879943 C19.4912389,31.1879943 19.7332389,31.3559943 20.1212389,31.6919943 C20.5092389,32.0279943 20.7032389,32.2379943 20.7032389,32.3219943 C20.7032389,32.4059943 20.6232389,32.4479943 20.4632389,32.4479943 L18.6392389,32.4479943 L18.6392389,35.5319943 C18.6392389,35.8279943 18.6212389,36.0579943 18.5852389,36.2219943 C18.5492389,36.3859943 18.4712389,36.5219943 18.3512389,36.6299943 C18.2312389,36.7379943 18.0252389,36.8299943 17.7332389,36.9059943 C17.4412389,36.9819943 17.2052389,37.0199943 17.0252389,37.0199943 C16.8452389,37.0199943 16.7152389,36.9919943 16.6352389,36.9359943 C16.5552389,36.8799943 16.5112389,36.8159943 16.5032389,36.7439943 C16.4872389,36.4159943 16.3752389,36.1819943 16.1672389,36.0419943 C15.9592389,35.9019943 15.6832389,35.7959943 15.3392389,35.7239943 C15.2432389,35.7079943 15.1952389,35.6819943 15.1952389,35.6459943 C15.1952389,35.6099943 15.2692389,35.5959943 15.4172389,35.6039943 C15.5652389,35.6119943 15.7952389,35.6159943 16.1072389,35.6159943 C16.4192389,35.6159943 16.6712389,35.5839943 16.8632389,35.5199943 C17.0552389,35.4559943 17.1512389,35.2719943 17.1512389,34.9679943 L17.1512389,32.4479943 L13.6712389,32.4479943 C13.5112389,32.4479943 13.3672389,32.4919943 13.2392389,32.5799943 L12.9272389,32.0159943 C13.1192389,32.0399943 13.3192389,32.0519943 13.5272389,32.0519943 L17.1512389,32.0519943 L17.1512389,30.5039943 L13.5752389,30.5039943 C13.4152389,30.5039943 13.2712389,30.5479943 13.1432389,30.6359943 L12.8312389,30.0719943 C13.0232389,30.0959943 13.2232389,30.1079943 13.4312389,30.1079943 L15.5312389,30.1079943 L15.5312389,28.2599943 Z M11.0432389,31.4279943 C10.6352389,31.6839943 10.2592389,31.8999943 9.91523888,32.0759943 C9.57123888,32.2519943 9.38323888,32.3399943 9.35123888,32.3399943 C9.31923888,32.3399943 9.30323888,32.3259943 9.30323888,32.2979943 C9.30323888,32.2699943 9.35123888,32.2159943 9.44723888,32.1359943 C10.6232389,31.1439943 11.5872389,29.7559943 12.3392389,27.9719943 C12.8512389,28.2359943 13.2232389,28.4499943 13.4552389,28.6139943 C13.6872389,28.7779943 13.8192389,28.8799943 13.8512389,28.9199943 C13.8832389,28.9599943 13.8992389,28.9999943 13.8992389,29.0399943 C13.8992389,29.1199943 13.8292389,29.1639943 13.6892389,29.1719943 C13.5492389,29.1799943 13.3752389,29.2959943 13.1672389,29.5199943 L12.1952389,30.5159943 C12.4592389,30.5479943 12.5912389,30.6279943 12.5912389,30.7559943 C12.5912389,30.8279943 12.5272389,30.8959943 12.3992389,30.9599943 L12.3992389,36.4439943 C12.3992389,36.6039943 12.2952389,36.7239943 12.0872389,36.8039943 C11.8792389,36.8839943 11.6652389,36.9239943 11.4452389,36.9239943 C11.2252389,36.9239943 11.0952389,36.9019943 11.0552389,36.8579943 C11.0152389,36.8139943 10.9952389,36.7319943 10.9952389,36.6119943 L11.0312389,35.4839943 C11.0392389,35.1319943 11.0432389,34.7999943 11.0432389,34.4879943 L11.0432389,31.4279943 Z M13.8392389,32.7119943 C14.0312389,32.7119943 14.3472389,32.7739943 14.7872389,32.8979943 C15.2272389,33.0219943 15.5572389,33.1859943 15.7772389,33.3899943 C15.9972389,33.5939943 16.1072389,33.8339943 16.1072389,34.1099943 C16.1072389,34.3859943 16.0152389,34.6159943 15.8312389,34.7999943 C15.6472389,34.9839943 15.4472389,35.0759943 15.2312389,35.0759943 C15.0152389,35.0759943 14.8432389,34.9979943 14.7152389,34.8419943 C14.5872389,34.6859943 14.5312389,34.5079943 14.5472389,34.3079943 C14.5552389,34.2279943 14.5592389,34.1519943 14.5592389,34.0799943 C14.5592389,33.5119943 14.3232389,33.0999943 13.8512389,32.8439943 C13.7792389,32.8119943 13.7432389,32.7819943 13.7432389,32.7539943 C13.7432389,32.7259943 13.7752389,32.7119943 13.8392389,32.7119943 Z" id="形状" fill="#FFA81D" transform="translate(15.0452, 31.386) rotate(-32) translate(-15.0452, -31.386)"></path>
<path d="M24.4018449,21.0864916 C24.2658449,20.9504916 24.1978449,20.7664916 24.1978449,20.5344916 C24.1978449,20.3024916 24.1398449,20.1084916 24.0238449,19.9524916 C23.9078449,19.7964916 23.7138449,19.6504916 23.4418449,19.5144916 C23.3538449,19.4664916 23.3098449,19.4284916 23.3098449,19.4004916 C23.3098449,19.3724916 23.4298449,19.3584916 23.6698449,19.3584916 C24.4378449,19.3584916 24.9918449,19.4384916 25.3318449,19.5984916 C25.6718449,19.7584916 25.8418449,20.0024916 25.8418449,20.3304916 C25.8418449,20.6584916 25.7218449,20.9104916 25.4818449,21.0864916 L27.9898449,21.0864916 C28.1898449,20.7504916 28.3358449,20.5204916 28.4278449,20.3964916 C28.5198449,20.2724916 28.5978449,20.2104916 28.6618449,20.2104916 C28.7818449,20.2104916 29.1178449,20.4104916 29.6698449,20.8104916 C30.2218449,21.2104916 30.4978449,21.4744916 30.4978449,21.6024916 C30.4978449,21.7304916 30.3978449,21.7944916 30.1978449,21.7944916 C29.6938449,21.7944916 29.2738449,21.8664916 28.9378449,22.0104916 C28.6018449,22.1544916 28.2978449,22.3944916 28.0258449,22.7304916 C27.9698449,22.8024916 27.9298449,22.8384916 27.9058449,22.8384916 C27.8818449,22.8384916 27.8698449,22.8184916 27.8698449,22.7784916 C27.8698449,22.7384916 27.8818449,22.6864916 27.9058449,22.6224916 C28.0098449,22.3344916 28.1178449,21.9544916 28.2298449,21.4824916 L21.2578449,21.4824916 C21.2898449,21.6504916 21.3058449,21.8144916 21.3058449,21.9744916 C21.3058449,22.4064916 21.1978449,22.7224916 20.9818449,22.9224916 C20.7658449,23.1224916 20.5138449,23.2224916 20.2258449,23.2224916 C20.0258449,23.2224916 19.8598449,23.1644916 19.7278449,23.0484916 C19.5958449,22.9324916 19.5298449,22.7704916 19.5298449,22.5624916 C19.5298449,22.2584916 19.6858449,22.0104916 19.9978449,21.8184916 C20.1578449,21.7144916 20.2978449,21.5604916 20.4178449,21.3564916 C20.5378449,21.1524916 20.5978449,20.9304916 20.5978449,20.6904916 C20.5978449,20.6024916 20.5918449,20.5224916 20.5798449,20.4504916 C20.5678449,20.3784916 20.5618449,20.3244916 20.5618449,20.2884916 C20.5618449,20.2524916 20.5698449,20.2344916 20.5858449,20.2344916 C20.6258449,20.2344916 20.7058449,20.3164916 20.8258449,20.4804916 C20.9458449,20.6444916 21.0498449,20.8464916 21.1378449,21.0864916 L24.4018449,21.0864916 Z M22.5538449,23.4504916 L24.1618449,23.4504916 L24.1618449,22.7184916 C24.1618449,22.3504916 24.1538449,21.9704916 24.1378449,21.5784916 C25.3138449,21.6984916 25.9018449,21.8624916 25.9018449,22.0704916 C25.9018449,22.1504916 25.8218449,22.2304916 25.6618449,22.3104916 L25.6618449,23.4504916 L27.0778449,23.4504916 C27.2938449,23.0984916 27.4278449,22.8984916 27.4798449,22.8504916 C27.5318449,22.8024916 27.5978449,22.7784916 27.6778449,22.7784916 C27.7498449,22.7784916 27.8818449,22.8324916 28.0738449,22.9404916 C28.2658449,23.0484916 28.4758449,23.1764916 28.7038449,23.3244916 C28.9318449,23.4724916 29.0878449,23.5864916 29.1718449,23.6664916 C29.2558449,23.7464916 29.2978449,23.8064916 29.2978449,23.8464916 C29.2978449,23.9424916 29.1578449,24.0304916 28.8778449,24.1104916 L28.8778449,26.9784916 L28.9018449,28.0824916 C28.9018449,28.1464916 28.8898449,28.1964916 28.8658449,28.2324916 C28.8418449,28.2684916 28.7658449,28.3124916 28.6378449,28.3644916 C28.5098449,28.4164916 28.3538449,28.4584916 28.1698449,28.4904916 C27.9858449,28.5224916 27.8018449,28.5384916 27.6178449,28.5384916 C27.4818449,28.5384916 27.3898449,28.5124916 27.3418449,28.4604916 C27.2938449,28.4084916 27.2698449,28.3224916 27.2698449,28.2024916 L27.2698449,27.6504916 L25.6618449,27.6504916 L25.6618449,28.9704916 C25.6618449,29.2344916 25.6698449,29.5144916 25.6858449,29.8104916 L25.6978449,30.2184916 C25.6978449,30.2984916 25.6698449,30.3684916 25.6138449,30.4284916 C25.5578449,30.4884916 25.4158449,30.5464916 25.1878449,30.6024916 C24.9598449,30.6584916 24.7258449,30.6864916 24.4858449,30.6864916 C24.2458449,30.6864916 24.1258449,30.5864916 24.1258449,30.3864916 L24.1498449,29.9184916 C24.1578449,29.5984916 24.1618449,29.2384916 24.1618449,28.8384916 L24.1618449,27.6504916 L22.5058449,27.6504916 L22.5058449,28.1784916 C22.5058449,28.2584916 22.4818449,28.3284916 22.4338449,28.3884916 C22.3858449,28.4484916 22.2738449,28.5044916 22.0978449,28.5564916 C21.9218449,28.6084916 21.7278449,28.6344916 21.5158449,28.6344916 C21.3038449,28.6344916 21.1678449,28.6164916 21.1078449,28.5804916 C21.0478449,28.5444916 21.0178449,28.4944916 21.0178449,28.4304916 C21.0178449,28.4224916 21.0258449,28.2784916 21.0418449,27.9984916 C21.0578449,27.7184916 21.0658449,27.4704916 21.0658449,27.2544916 L21.0658449,24.0264916 C21.0658449,23.6744916 21.0538449,23.3264916 21.0298449,22.9824916 C21.7018449,23.1664916 22.2098449,23.3224916 22.5538449,23.4504916 Z M22.5058449,25.2984916 L24.1618449,25.2984916 L24.1618449,23.8464916 L22.6978449,23.8464916 C22.6818449,23.9424916 22.6178449,24.0104916 22.5058449,24.0504916 L22.5058449,25.2984916 Z M25.6618449,25.2984916 L27.2698449,25.2984916 L27.2698449,23.8464916 L25.6618449,23.8464916 L25.6618449,25.2984916 Z M24.1618449,25.6944916 L22.5058449,25.6944916 L22.5058449,27.2544916 L24.1618449,27.2544916 L24.1618449,25.6944916 Z M27.2698449,25.6944916 L25.6618449,25.6944916 L25.6618449,27.2544916 L27.2698449,27.2544916 L27.2698449,25.6944916 Z" id="形状" fill="#FFA81D" transform="translate(25.0138, 25.0225) rotate(-32) translate(-25.0138, -25.0225)"></path>
<path d="M31.3840865,16.4168624 L30.2200865,16.4168624 C30.0280865,16.4168624 29.8560865,16.4408624 29.7040865,16.4888624 L29.5000865,15.9728624 C29.6840865,16.0048624 29.8840865,16.0208624 30.1000865,16.0208624 L31.3840865,16.0208624 L31.3840865,14.6168624 C31.3840865,14.1288624 31.3680865,13.6968624 31.3360865,13.3208624 C32.4640865,13.3928624 33.0280865,13.5128624 33.0280865,13.6808624 C33.0280865,13.7688624 32.9280865,13.8528624 32.7280865,13.9328624 L32.7280865,15.9968624 C32.8000865,15.8528624 32.8860865,15.6928624 32.9860865,15.5168624 C33.0860865,15.3408624 33.1460865,15.2408624 33.1660865,15.2168624 C33.1860865,15.1928624 33.2160865,15.1808624 33.2560865,15.1808624 C33.2960865,15.1808624 33.4060865,15.2528624 33.5860865,15.3968624 C33.7660865,15.5408624 33.9840865,15.7488624 34.2400865,16.0208624 L34.2400865,14.6408624 C34.2400865,14.2328624 34.2280865,13.8568624 34.2040865,13.5128624 C35.2920865,13.6408624 35.8360865,13.7768624 35.8360865,13.9208624 C35.8360865,13.9848624 35.7440865,14.0648624 35.5600865,14.1608624 L35.5600865,17.4368624 L35.7160865,17.4368624 C35.8280865,17.2208624 35.9160865,17.0648624 35.9800865,16.9688624 C36.0440865,16.8728624 36.1040865,16.8248624 36.1600865,16.8248624 C36.2160865,16.8248624 36.3500865,16.9188624 36.5620865,17.1068624 C36.7740865,17.2948624 36.9200865,17.4408624 37.0000865,17.5448624 L37.0000865,14.5808624 C37.0000865,14.0368624 36.9880865,13.5888624 36.9640865,13.2368624 C37.6040865,13.3168624 38.0400865,13.3848624 38.2720865,13.4408624 C38.5040865,13.4968624 38.6200865,13.5668624 38.6200865,13.6508624 C38.6200865,13.7348624 38.5360865,13.8128624 38.3680865,13.8848624 L38.3680865,18.0608624 C38.5520865,17.7968624 38.9120865,17.0328624 39.4480865,15.7688624 C39.7680865,16.0008624 40.0560865,16.2368624 40.3120865,16.4768624 C40.5680865,16.7168624 40.7200865,16.8668624 40.7680865,16.9268624 C40.8160865,16.9868624 40.8400865,17.0408624 40.8400865,17.0888624 C40.8400865,17.1688624 40.7580865,17.2128624 40.5940865,17.2208624 C40.4300865,17.2288624 40.2220865,17.3028624 39.9700865,17.4428624 C39.7180865,17.5828624 39.1840865,17.9328624 38.3680865,18.4928624 L38.3680865,22.2728624 C38.3680865,22.4648624 38.3900865,22.5808624 38.4340865,22.6208624 C38.4780865,22.6608624 38.5880865,22.6808624 38.7640865,22.6808624 C38.9400865,22.6808624 39.0820865,22.6348624 39.1900865,22.5428624 C39.2980865,22.4508624 39.4100865,22.2628624 39.5260865,21.9788624 C39.6420865,21.6948624 39.7800865,21.2608624 39.9400865,20.6768624 C39.9640865,20.5888624 40.0000865,20.5448624 40.0480865,20.5448624 C40.0960865,20.5448624 40.1120865,20.6008624 40.0960865,20.7128624 C40.0640865,21.0008624 40.0480865,21.2708624 40.0480865,21.5228624 C40.0480865,21.7748624 40.0880865,21.9908624 40.1680865,22.1708624 C40.2480865,22.3508624 40.4200865,22.5168624 40.6840865,22.6688624 C40.8200865,22.7488624 40.8880865,22.8428624 40.8880865,22.9508624 C40.8880865,23.0588624 40.8400865,23.2048624 40.7440865,23.3888624 C40.6480865,23.5728624 40.4380865,23.7248624 40.1140865,23.8448624 C39.7900865,23.9648624 39.3500865,24.0248624 38.7940865,24.0248624 C38.2380865,24.0248624 37.8360865,23.9928624 37.5880865,23.9288624 C37.3400865,23.8648624 37.1800865,23.7248624 37.1080865,23.5088624 C37.0360865,23.2928624 37.0000865,22.8968624 37.0000865,22.3208624 L37.0000865,21.8168624 C35.8480865,22.9128624 35.0960865,23.6608624 34.7440865,24.0608624 C34.6320865,24.1888624 34.5420865,24.2528624 34.4740865,24.2528624 C34.4060865,24.2528624 34.3480865,24.2188624 34.3000865,24.1508624 C34.2520865,24.0828624 34.1360865,23.8448624 33.9520865,23.4368624 C33.7680865,23.0288624 33.6760865,22.7848624 33.6760865,22.7048624 C33.6760865,22.6248624 33.7480865,22.5428624 33.8920865,22.4588624 C34.0360865,22.3748624 34.1300865,22.2988624 34.1740865,22.2308624 C34.2180865,22.1628624 34.2400865,22.0328624 34.2400865,21.8408624 L34.2400865,17.6648624 L32.7280865,18.6128624 L32.7280865,22.7288624 C32.7280865,23.0408624 32.7080865,23.2768624 32.6680865,23.4368624 C32.6280865,23.5968624 32.5460865,23.7268624 32.4220865,23.8268624 C32.2980865,23.9268624 32.0820865,24.0168624 31.7740865,24.0968624 C31.4660865,24.1768624 31.2400865,24.2168624 31.0960865,24.2168624 C30.9520865,24.2168624 30.8680865,24.1368624 30.8440865,23.9768624 C30.7320865,23.4328624 30.3720865,23.0968624 29.7640865,22.9688624 C29.6440865,22.9448624 29.5840865,22.9148624 29.5840865,22.8788624 C29.5840865,22.8428624 29.6520865,22.8248624 29.7880865,22.8248624 C30.3000865,22.8248624 30.6660865,22.8108624 30.8860865,22.7828624 C31.1060865,22.7548624 31.2440865,22.7048624 31.3000865,22.6328624 C31.3560865,22.5608624 31.3840865,22.4448624 31.3840865,22.2848624 L31.3840865,19.4888624 C31.0800865,19.6888624 30.7000865,19.9608624 30.2440865,20.3048624 C30.1720865,20.3608624 30.1220865,20.3888624 30.0940865,20.3888624 C30.0660865,20.3888624 30.0400865,20.3708624 30.0160865,20.3348624 C29.9920865,20.2988624 29.9120865,20.1288624 29.7760865,19.8248624 C29.6400865,19.5208624 29.5040865,19.1688624 29.3680865,18.7688624 C29.8000865,18.6968624 30.4720865,18.5488624 31.3840865,18.3248624 L31.3840865,16.4168624 Z M34.2400865,16.4168624 L32.7280865,16.4168624 L32.7280865,17.9528624 L34.2400865,17.4968624 L34.2400865,16.4168624 Z M35.5600865,17.8328624 L35.5600865,22.0328624 C36.1120865,21.8648624 36.5920865,21.7128624 37.0000865,21.5768624 L37.0000865,17.8328624 L35.5600865,17.8328624 Z" id="形状" fill="#FFA81D" transform="translate(35.1281, 18.7449) rotate(-32) translate(-35.1281, -18.7449)"></path>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="50px" height="50px" viewBox="0 0 50 50" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>审批中</title>
<g id="游戏" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="我的任务-撤销页" transform="translate(-404, -619)" fill-rule="nonzero">
<g id="编组-4备份-3" transform="translate(132, 569.96)">
<g id="审批中" transform="translate(272, 49.04)">
<rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="50" height="50"></rect>
<path d="M48.9604167,18.1563095 L41.587381,6.53083335 C40.9435714,5.51708335 39.5982143,5.21714287 38.5814286,5.85535713 L1.78476191,29.1335714 C0.770773828,29.777381 0.471071436,31.1227381 1.10791665,32.1336905 L8.48095239,43.7606548 C9.12482144,44.7718453 10.470119,45.0715477 11.4841667,44.4333929 L48.2822024,21.1567857 C49.2989881,20.512619 49.6044643,19.1689286 48.9604167,18.1563095 Z M47.4918452,19.907381 L10.6938095,43.1870238 C10.3683333,43.3920833 9.94232144,43.2960714 9.73726191,42.9719643 L2.36422617,31.3450595 C2.15910713,31.0195238 2.25517856,30.5949405 2.58065479,30.3870833 L39.380119,7.10886904 C39.7058929,6.90517856 40.1332143,7.00142856 40.3352976,7.32553569 L47.711369,18.9522619 C47.9092262,19.2707738 47.8117857,19.6981548 47.4918452,19.907381 Z M15.7707738,12.5301786 L16.3818452,13.9957143 L17.1735714,12.6204167 L18.7553571,12.4927381 L17.6897619,11.313869 L18.0526786,9.77208335 L16.6069048,10.4219643 L15.2488095,9.6 L15.4208333,11.1790476 L14.2161905,12.2060714 L15.7707738,12.5301786 L15.7707738,12.5301786 Z M25.1401786,8.16726191 L24.3800595,6.77196431 L23.73625,8.22470239 L22.1730357,8.52303569 L23.3532738,9.58142856 L23.1495833,11.1546429 L24.5263095,10.3586905 L25.9620833,11.04 L25.6307738,9.48541665 L26.7191667,8.33232144 L25.1401786,8.16726191 Z M39.4247619,31.540119 L38.1668452,30.5733333 L38.16125,32.1581548 L36.8475595,33.0489286 L38.3605357,33.5479762 L38.8064881,35.0695238 L39.7444643,33.7888095 L41.3320833,33.8332738 L40.3999405,32.5455357 L40.9377381,31.0581548 L39.4247619,31.540119 L39.4247619,31.540119 Z M34.2903571,37.8589286 L33.6909524,36.3889881 L32.8861905,37.75875 L31.3057738,37.8734524 L32.361369,39.0580357 L31.9855952,40.5982143 L33.4397619,39.9629762 L34.7923214,40.8032738 L34.6330357,39.2228571 L35.8376786,38.1974405 L34.2903571,37.8589286 L34.2903571,37.8589286 Z M24.884881,42.1558333 L25.6380357,43.5569643 L26.294881,42.1083929 L27.8580952,41.8289286 L26.6848214,40.758869 L26.900119,39.1870833 L25.5175595,39.9688095 L24.0889881,39.2775595 L24.4073214,40.8291071 L23.3030952,41.9780357 L24.884881,42.1558333 L24.884881,42.1558333 Z M10.7956548,18.6727381 L12.046369,19.655119 L12.0649405,18.0689286 L13.3844643,17.1825595 L11.879881,16.6733333 L11.4452976,15.1445833 L10.4959524,16.4166667 L8.90833335,16.3592262 L9.82767856,17.6529167 L9.27964287,19.1445238 L10.7956548,18.6727381 L10.7956548,18.6727381 Z M5.20952383,25.5207738 C5.04327383,18.8059524 8.30892861,12.1672024 14.3926786,8.31934521 C20.4777976,4.47142856 27.8752976,4.36238091 33.8844048,7.37720239 L35.3357738,6.45922617 C33.5575,5.46541665 31.6443453,4.73815474 29.6294048,4.28636904 C26.9373214,3.68113096 24.1952977,3.60529761 21.4845833,4.05130952 C18.6779167,4.51583335 16.0247024,5.52845239 13.6009524,7.06446431 C11.178631,8.6004167 9.12482144,10.562381 7.50416665,12.900119 C5.93517856,15.1545833 4.83238096,17.6659524 4.22571431,20.3535714 C3.77392861,22.3655357 3.61327383,24.4049405 3.75392856,26.437381 L5.20952383,25.5207738 Z M44.7254167,24.4939881 C44.898869,31.2088095 41.6332143,37.8475595 35.5494643,41.6940476 C29.4657143,45.546131 22.0669048,45.652381 16.0591071,42.637619 L14.6049405,43.5569643 C16.3832143,44.5479167 18.2977381,45.2767262 20.3129762,45.7283929 C23.0047619,46.333631 25.7468452,46.4125 28.4575,45.9634524 C31.2641667,45.498869 33.9174405,44.4876786 36.3397619,42.9516667 C38.7620833,41.4156547 40.8158929,39.4536905 42.4379167,37.117381 C44.001131,34.860119 45.1039286,32.3503571 45.7091667,29.6641071 C46.1623214,27.6505357 46.3202381,25.6097619 46.1795238,23.577381 L44.7254167,24.4939881 Z M18.781131,15.243631 C20.485,14.1680357 22.3593453,13.5941667 24.2410714,13.4795238 L26.4869048,12.0595833 C23.5195238,11.7096429 20.5480357,12.3780953 17.9838095,13.9973214 C15.4266071,15.6149405 13.5520833,18.0172619 12.6013095,20.8453571 L14.8457738,19.4256548 C15.7579762,17.7675596 17.0789286,16.3220238 18.781131,15.243631 Z M31.1595238,34.7697619 C29.4556548,35.8483929 27.5827381,36.4220238 25.7010119,36.5366667 L23.4564881,37.9566071 C26.4225,38.3065476 29.392619,37.6366667 31.9582143,36.0174405 C34.5154167,34.40125 36.3899405,31.9975 37.3392857,29.1694048 L35.0961905,30.5921429 C34.1841071,32.2427977 32.8617857,33.6941667 31.1595238,34.7697619 Z" id="形状" fill="#3491FA"></path>
<g transform="translate(24.8657, 25.0797) rotate(-32) translate(-24.8657, -25.0797)translate(7.5377, 19.3857)" fill="#3491FA" id="形状">
<path d="M4.872,1.788 C4.736,1.652 4.668,1.468 4.668,1.236 C4.668,1.004 4.61,0.81 4.494,0.654 C4.378,0.498 4.184,0.352 3.912,0.216 C3.824,0.168 3.78,0.13 3.78,0.102 C3.78,0.074 3.9,0.06 4.14,0.06 C4.908,0.06 5.462,0.14 5.802,0.3 C6.142,0.46 6.312,0.704 6.312,1.032 C6.312,1.36 6.192,1.612 5.952,1.788 L8.46,1.788 C8.66,1.452 8.806,1.222 8.898,1.098 C8.99,0.974 9.068,0.912 9.132,0.912 C9.252,0.912 9.588,1.112 10.14,1.512 C10.692,1.912 10.968,2.176 10.968,2.304 C10.968,2.432 10.868,2.496 10.668,2.496 C10.164,2.496 9.744,2.568 9.408,2.712 C9.072,2.856 8.768,3.096 8.496,3.432 C8.44,3.504 8.4,3.54 8.376,3.54 C8.352,3.54 8.34,3.52 8.34,3.48 C8.34,3.44 8.352,3.388 8.376,3.324 C8.48,3.036 8.588,2.656 8.7,2.184 L1.728,2.184 C1.76,2.352 1.776,2.516 1.776,2.676 C1.776,3.108 1.668,3.424 1.452,3.624 C1.236,3.824 0.984,3.924 0.696,3.924 C0.496,3.924 0.33,3.866 0.198,3.75 C0.066,3.634 0,3.472 0,3.264 C0,2.96 0.156,2.712 0.468,2.52 C0.628,2.416 0.768,2.262 0.888,2.058 C1.008,1.854 1.068,1.632 1.068,1.392 C1.068,1.304 1.062,1.224 1.05,1.152 C1.038,1.08 1.032,1.026 1.032,0.99 C1.032,0.954 1.04,0.936 1.056,0.936 C1.096,0.936 1.176,1.018 1.296,1.182 C1.416,1.346 1.52,1.548 1.608,1.788 L4.872,1.788 Z M3.024,4.152 L4.632,4.152 L4.632,3.42 C4.632,3.052 4.624,2.672 4.608,2.28 C5.784,2.4 6.372,2.564 6.372,2.772 C6.372,2.852 6.292,2.932 6.132,3.012 L6.132,4.152 L7.548,4.152 C7.764,3.8 7.898,3.6 7.95,3.552 C8.002,3.504 8.068,3.48 8.148,3.48 C8.22,3.48 8.352,3.534 8.544,3.642 C8.736,3.75 8.946,3.878 9.174,4.026 C9.402,4.174 9.558,4.288 9.642,4.368 C9.726,4.448 9.768,4.508 9.768,4.548 C9.768,4.644 9.628,4.732 9.348,4.812 L9.348,7.68 L9.372,8.784 C9.372,8.848 9.36,8.898 9.336,8.934 C9.312,8.97 9.236,9.014 9.108,9.066 C8.98,9.118 8.824,9.16 8.64,9.192 C8.456,9.224 8.272,9.24 8.088,9.24 C7.952,9.24 7.86,9.214 7.812,9.162 C7.764,9.11 7.74,9.024 7.74,8.904 L7.74,8.352 L6.132,8.352 L6.132,9.672 C6.132,9.936 6.14,10.216 6.156,10.512 L6.168,10.92 C6.168,11 6.14,11.07 6.084,11.13 C6.028,11.19 5.886,11.248 5.658,11.304 C5.43,11.36 5.196,11.388 4.956,11.388 C4.716,11.388 4.596,11.288 4.596,11.088 L4.62,10.62 C4.628,10.3 4.632,9.94 4.632,9.54 L4.632,8.352 L2.976,8.352 L2.976,8.88 C2.976,8.96 2.952,9.03 2.904,9.09 C2.856,9.15 2.744,9.206 2.568,9.258 C2.392,9.31 2.198,9.336 1.986,9.336 C1.774,9.336 1.638,9.318 1.578,9.282 C1.518,9.246 1.488,9.196 1.488,9.132 C1.488,9.124 1.496,8.98 1.512,8.7 C1.528,8.42 1.536,8.172 1.536,7.956 L1.536,4.728 C1.536,4.376 1.524,4.028 1.5,3.684 C2.172,3.868 2.68,4.024 3.024,4.152 Z M2.976,6 L4.632,6 L4.632,4.548 L3.168,4.548 C3.152,4.644 3.088,4.712 2.976,4.752 L2.976,6 Z M6.132,6 L7.74,6 L7.74,4.548 L6.132,4.548 L6.132,6 Z M4.632,6.396 L2.976,6.396 L2.976,7.956 L4.632,7.956 L4.632,6.396 Z M7.74,6.396 L6.132,6.396 L6.132,7.956 L7.74,7.956 L7.74,6.396 Z"></path>
<path d="M13.644,3.432 L12.48,3.432 C12.288,3.432 12.116,3.456 11.964,3.504 L11.76,2.988 C11.944,3.02 12.144,3.036 12.36,3.036 L13.644,3.036 L13.644,1.632 C13.644,1.144 13.628,0.712 13.596,0.336 C14.724,0.408 15.288,0.528 15.288,0.696 C15.288,0.784 15.188,0.868 14.988,0.948 L14.988,3.012 C15.06,2.868 15.146,2.708 15.246,2.532 C15.346,2.356 15.406,2.256 15.426,2.232 C15.446,2.208 15.476,2.196 15.516,2.196 C15.556,2.196 15.666,2.268 15.846,2.412 C16.026,2.556 16.244,2.764 16.5,3.036 L16.5,1.656 C16.5,1.248 16.488,0.872 16.464,0.528 C17.552,0.656 18.096,0.792 18.096,0.936 C18.096,1 18.004,1.08 17.82,1.176 L17.82,4.452 L17.976,4.452 C18.088,4.236 18.176,4.08 18.24,3.984 C18.304,3.888 18.364,3.84 18.42,3.84 C18.476,3.84 18.61,3.934 18.822,4.122 C19.034,4.31 19.18,4.456 19.26,4.56 L19.26,1.596 C19.26,1.052 19.248,0.604 19.224,0.252 C19.864,0.332 20.3,0.4 20.532,0.456 C20.764,0.512 20.88,0.582 20.88,0.666 C20.88,0.75 20.796,0.828 20.628,0.9 L20.628,5.076 C20.812,4.812 21.172,4.048 21.708,2.784 C22.028,3.016 22.316,3.252 22.572,3.492 C22.828,3.732 22.98,3.882 23.028,3.942 C23.076,4.002 23.1,4.056 23.1,4.104 C23.1,4.184 23.018,4.228 22.854,4.236 C22.69,4.244 22.482,4.318 22.23,4.458 C21.978,4.598 21.444,4.948 20.628,5.508 L20.628,9.288 C20.628,9.48 20.65,9.596 20.694,9.636 C20.738,9.676 20.848,9.696 21.024,9.696 C21.2,9.696 21.342,9.65 21.45,9.558 C21.558,9.466 21.67,9.278 21.786,8.994 C21.902,8.71 22.04,8.276 22.2,7.692 C22.224,7.604 22.26,7.56 22.308,7.56 C22.356,7.56 22.372,7.616 22.356,7.728 C22.324,8.016 22.308,8.286 22.308,8.538 C22.308,8.79 22.348,9.006 22.428,9.186 C22.508,9.366 22.68,9.532 22.944,9.684 C23.08,9.764 23.148,9.858 23.148,9.966 C23.148,10.074 23.1,10.22 23.004,10.404 C22.908,10.588 22.698,10.74 22.374,10.86 C22.05,10.98 21.61,11.04 21.054,11.04 C20.498,11.04 20.096,11.008 19.848,10.944 C19.6,10.88 19.44,10.74 19.368,10.524 C19.296,10.308 19.26,9.912 19.26,9.336 L19.26,8.832 C18.108,9.928 17.356,10.676 17.004,11.076 C16.892,11.204 16.802,11.268 16.734,11.268 C16.666,11.268 16.608,11.234 16.56,11.166 C16.512,11.098 16.396,10.86 16.212,10.452 C16.028,10.044 15.936,9.8 15.936,9.72 C15.936,9.64 16.008,9.558 16.152,9.474 C16.296,9.39 16.39,9.314 16.434,9.246 C16.478,9.178 16.5,9.048 16.5,8.856 L16.5,4.68 L14.988,5.628 L14.988,9.744 C14.988,10.056 14.968,10.292 14.928,10.452 C14.888,10.612 14.806,10.742 14.682,10.842 C14.558,10.942 14.342,11.032 14.034,11.112 C13.726,11.192 13.5,11.232 13.356,11.232 C13.212,11.232 13.128,11.152 13.104,10.992 C12.992,10.448 12.632,10.112 12.024,9.984 C11.904,9.96 11.844,9.93 11.844,9.894 C11.844,9.858 11.912,9.84 12.048,9.84 C12.56,9.84 12.926,9.826 13.146,9.798 C13.366,9.77 13.504,9.72 13.56,9.648 C13.616,9.576 13.644,9.46 13.644,9.3 L13.644,6.504 C13.34,6.704 12.96,6.976 12.504,7.32 C12.432,7.376 12.382,7.404 12.354,7.404 C12.326,7.404 12.3,7.386 12.276,7.35 C12.252,7.314 12.172,7.144 12.036,6.84 C11.9,6.536 11.764,6.184 11.628,5.784 C12.06,5.712 12.732,5.564 13.644,5.34 L13.644,3.432 Z M16.5,3.432 L14.988,3.432 L14.988,4.968 L16.5,4.512 L16.5,3.432 Z M17.82,4.848 L17.82,9.048 C18.372,8.88 18.852,8.728 19.26,8.592 L19.26,4.848 L17.82,4.848 Z"></path>
<path d="M26.736,2.76 L28.752,2.76 L28.752,1.068 C28.752,0.668 28.744,0.312 28.728,4.54747351e-13 C29.416,0.024 29.902,0.062 30.186,0.114 C30.47,0.166 30.612,0.244 30.612,0.348 C30.612,0.452 30.5,0.56 30.276,0.672 L30.276,2.76 L32.22,2.76 C32.42,2.376 32.556,2.144 32.628,2.064 C32.7,1.984 32.788,1.944 32.892,1.944 C32.996,1.944 33.22,2.044 33.564,2.244 C33.908,2.444 34.176,2.61 34.368,2.742 C34.56,2.874 34.656,3 34.656,3.12 C34.656,3.24 34.504,3.336 34.2,3.408 L34.2,6.36 C34.2,6.496 34.204,6.616 34.212,6.72 L34.236,6.984 C34.236,7.04 34.202,7.088 34.134,7.128 C34.066,7.168 33.874,7.22 33.558,7.284 C33.242,7.348 32.956,7.38 32.7,7.38 C32.636,7.38 32.594,7.368 32.574,7.344 C32.554,7.32 32.544,7.272 32.544,7.2 L32.544,6.504 L30.276,6.504 L30.276,9.588 C30.276,9.852 30.28,10.132 30.288,10.428 L30.312,10.836 C30.312,10.892 30.302,10.932 30.282,10.956 C30.262,10.98 30.17,11.02 30.006,11.076 C29.842,11.132 29.622,11.186 29.346,11.238 C29.07,11.29 28.888,11.316 28.8,11.316 C28.744,11.316 28.716,11.256 28.716,11.136 L28.74,10.668 C28.748,10.348 28.752,9.988 28.752,9.588 L28.752,6.504 L26.52,6.504 L26.52,7.08 C26.52,7.128 26.508,7.166 26.484,7.194 C26.46,7.222 26.374,7.258 26.226,7.302 C26.078,7.346 25.878,7.386 25.626,7.422 C25.374,7.458 25.172,7.476 25.02,7.476 C24.964,7.476 24.94,7.436 24.948,7.356 C24.964,7.172 24.972,6.876 24.972,6.468 L24.972,3.156 C24.972,2.82 24.96,2.48 24.936,2.136 C25.656,2.32 26.256,2.528 26.736,2.76 Z M28.752,3.156 L26.808,3.156 C26.752,3.244 26.656,3.304 26.52,3.336 L26.52,6.108 L28.752,6.108 L28.752,3.156 Z M32.544,6.108 L32.544,3.156 L30.276,3.156 L30.276,6.108 L32.544,6.108 Z"></path>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="50px" height="50px" viewBox="0 0 50 50" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>已通过</title>
<g id="游戏" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="我的任务-撤销页" transform="translate(-404, -935)" fill-rule="nonzero">
<g id="编组-4备份-5" transform="translate(132, 885.96)">
<g id="已通过" transform="translate(272, 49.04)">
<rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="50" height="50"></rect>
<path d="M48.9604167,18.1563095 L41.587381,6.53083335 C40.9435714,5.51708335 39.5982143,5.21714287 38.5814286,5.85535713 L1.78476191,29.1335714 C0.770773828,29.777381 0.471071436,31.1227381 1.10791665,32.1336905 L8.48095239,43.7606548 C9.12482144,44.7718453 10.470119,45.0715477 11.4841667,44.4333929 L48.2822024,21.1567857 C49.2989881,20.512619 49.6044643,19.1689286 48.9604167,18.1563095 Z M47.4918452,19.907381 L10.6938095,43.1870238 C10.3683333,43.3920833 9.94232144,43.2960714 9.73726191,42.9719643 L2.36422617,31.3450595 C2.15910713,31.0195238 2.25517856,30.5949405 2.58065479,30.3870833 L39.380119,7.10886904 C39.7058929,6.90517856 40.1332143,7.00142856 40.3352976,7.32553569 L47.711369,18.9522619 C47.9092262,19.2707738 47.8117857,19.6981548 47.4918452,19.907381 Z M15.7707738,12.5301786 L16.3818452,13.9957143 L17.1735714,12.6204167 L18.7553571,12.4927381 L17.6897619,11.313869 L18.0526786,9.77208335 L16.6069048,10.4219643 L15.2488095,9.6 L15.4208333,11.1790476 L14.2161905,12.2060714 L15.7707738,12.5301786 L15.7707738,12.5301786 Z M25.1401786,8.16726191 L24.3800595,6.77196431 L23.73625,8.22470239 L22.1730357,8.52303569 L23.3532738,9.58142856 L23.1495833,11.1546429 L24.5263095,10.3586905 L25.9620833,11.04 L25.6307738,9.48541665 L26.7191667,8.33232144 L25.1401786,8.16726191 Z M39.4247619,31.540119 L38.1668452,30.5733333 L38.16125,32.1581548 L36.8475595,33.0489286 L38.3605357,33.5479762 L38.8064881,35.0695238 L39.7444643,33.7888095 L41.3320833,33.8332738 L40.3999405,32.5455357 L40.9377381,31.0581548 L39.4247619,31.540119 L39.4247619,31.540119 Z M34.2903571,37.8589286 L33.6909524,36.3889881 L32.8861905,37.75875 L31.3057738,37.8734524 L32.361369,39.0580357 L31.9855952,40.5982143 L33.4397619,39.9629762 L34.7923214,40.8032738 L34.6330357,39.2228571 L35.8376786,38.1974405 L34.2903571,37.8589286 L34.2903571,37.8589286 Z M24.884881,42.1558333 L25.6380357,43.5569643 L26.294881,42.1083929 L27.8580952,41.8289286 L26.6848214,40.758869 L26.900119,39.1870833 L25.5175595,39.9688095 L24.0889881,39.2775595 L24.4073214,40.8291071 L23.3030952,41.9780357 L24.884881,42.1558333 L24.884881,42.1558333 Z M10.7956548,18.6727381 L12.046369,19.655119 L12.0649405,18.0689286 L13.3844643,17.1825595 L11.879881,16.6733333 L11.4452976,15.1445833 L10.4959524,16.4166667 L8.90833335,16.3592262 L9.82767856,17.6529167 L9.27964287,19.1445238 L10.7956548,18.6727381 L10.7956548,18.6727381 Z M5.20952383,25.5207738 C5.04327383,18.8059524 8.30892861,12.1672024 14.3926786,8.31934521 C20.4777976,4.47142856 27.8752976,4.36238091 33.8844048,7.37720239 L35.3357738,6.45922617 C33.5575,5.46541665 31.6443453,4.73815474 29.6294048,4.28636904 C26.9373214,3.68113096 24.1952977,3.60529761 21.4845833,4.05130952 C18.6779167,4.51583335 16.0247024,5.52845239 13.6009524,7.06446431 C11.178631,8.6004167 9.12482144,10.562381 7.50416665,12.900119 C5.93517856,15.1545833 4.83238096,17.6659524 4.22571431,20.3535714 C3.77392861,22.3655357 3.61327383,24.4049405 3.75392856,26.437381 L5.20952383,25.5207738 Z M44.7254167,24.4939881 C44.898869,31.2088095 41.6332143,37.8475595 35.5494643,41.6940476 C29.4657143,45.546131 22.0669048,45.652381 16.0591071,42.637619 L14.6049405,43.5569643 C16.3832143,44.5479167 18.2977381,45.2767262 20.3129762,45.7283929 C23.0047619,46.333631 25.7468452,46.4125 28.4575,45.9634524 C31.2641667,45.498869 33.9174405,44.4876786 36.3397619,42.9516667 C38.7620833,41.4156547 40.8158929,39.4536905 42.4379167,37.117381 C44.001131,34.860119 45.1039286,32.3503571 45.7091667,29.6641071 C46.1623214,27.6505357 46.3202381,25.6097619 46.1795238,23.577381 L44.7254167,24.4939881 Z M18.781131,15.243631 C20.485,14.1680357 22.3593453,13.5941667 24.2410714,13.4795238 L26.4869048,12.0595833 C23.5195238,11.7096429 20.5480357,12.3780953 17.9838095,13.9973214 C15.4266071,15.6149405 13.5520833,18.0172619 12.6013095,20.8453571 L14.8457738,19.4256548 C15.7579762,17.7675596 17.0789286,16.3220238 18.781131,15.243631 Z M31.1595238,34.7697619 C29.4556548,35.8483929 27.5827381,36.4220238 25.7010119,36.5366667 L23.4564881,37.9566071 C26.4225,38.3065476 29.392619,37.6366667 31.9582143,36.0174405 C34.5154167,34.40125 36.3899405,31.9975 37.3392857,29.1694048 L35.0961905,30.5921429 C34.1841071,32.2427977 32.8617857,33.6941667 31.1595238,34.7697619 Z" id="形状" fill="#00BF8A"></path>
<path d="M13.4734524,27.2072619 L13.526369,26.4886905 L14.6629167,26.5584524 L14.434881,27.1040476 C15.4719048,28.7209524 16.1698214,29.776369 16.5285714,30.2683333 L16.0015476,30.9486905 L15.612619,30.3423214 L9.83339287,34.0489881 L12.0890476,37.5658929 C12.335119,38.0168453 12.7229167,38.0533333 13.2515476,37.6760119 L18.7122024,34.173631 C19.2757143,33.8505357 19.4574405,33.467381 19.2592857,33.0239881 C19.0604762,32.5810714 18.7345238,31.9725595 18.2809524,31.1981548 L18.5084524,31.0522619 C19.39,32.4266667 20.0756548,32.9950595 20.5651786,32.7569643 C20.6032738,33.4172024 20.2102381,33.9731548 19.3873214,34.4252381 L13.0621429,38.4821429 C12.4420833,38.9173214 11.9229762,38.7760714 11.503869,38.0552381 C9.72380952,35.2799405 8.67964287,33.6864286 8.37303569,33.2740476 L9.65303569,32.9666667 L9.47047617,33.4830952 L9.67785713,33.8065476 L15.4570833,30.0998214 L13.72,27.3914881 L8.48684521,30.7479762 C8.09226187,31.0010714 7.75410713,31.2750595 7.4725,31.5697024 L6.82964287,31.4685714 L13.4734524,27.2072619 Z" id="路径" fill="#00BF8A"></path>
<path d="M12.4036905,39.0260119 C11.9542857,39.0260119 11.566131,38.7517262 11.2499405,38.2106548 C9.48863096,35.4646429 8.44023809,33.8633333 8.13416665,33.4516667 L7.86523809,33.0899405 L10.1161905,32.5494048 L9.83160713,33.3542857 L15.0458333,30.009881 L13.630119,27.802619 L8.6475,30.9983929 C8.27482144,31.2374405 7.95184521,31.49875 7.68761904,31.7752381 L7.58005952,31.8877976 L6.00958335,31.6410119 L13.1875595,27.0370833 L13.251131,26.173631 L15.098869,26.2870238 L14.7696429,27.0747024 C15.7556548,28.6102976 16.4280953,29.6254167 16.7689881,30.0929762 L16.9007738,30.2736905 L15.978631,31.4641667 L15.5227976,30.7535119 L10.2446429,34.138869 L12.3503571,37.4233333 C12.4666071,37.6364286 12.5717857,37.6364286 12.6166667,37.6364286 C12.6979762,37.6364286 12.8441071,37.60125 13.0786905,37.4338095 L13.0909524,37.4254762 L18.5642857,33.9154167 C19.1752381,33.565119 19.0485714,33.2816667 18.9876786,33.1453571 C18.7941071,32.7141071 18.469881,32.1094047 18.0242857,31.3484524 L17.8798214,31.1017857 L18.5984524,30.6409524 L18.7591071,30.8914881 C19.6972023,32.3540476 20.1741667,32.5119643 20.3357143,32.5119643 C20.3716667,32.5119643 20.4032738,32.5047619 20.435119,32.4892262 L20.8367262,32.293869 L20.8624405,32.7397024 C20.9073214,33.5183929 20.4623214,34.1715476 19.5397619,34.6810119 L13.2278571,38.7293452 C12.9458333,38.9261904 12.6685714,39.0260119 12.4036905,39.0260119 Z M8.86791665,33.46125 C9.34922617,34.1672024 10.3166667,35.6529762 11.7543452,37.8945238 L11.761131,37.9055952 C11.96375,38.2540476 12.1799405,38.4307143 12.4036905,38.4307143 C12.5454167,38.4307143 12.7094643,38.3660119 12.8911905,38.2385119 L12.9014881,38.2316071 L13.057619,38.1314286 C12.903631,38.1985714 12.7575595,38.2316667 12.6166667,38.2316667 C12.38875,38.2316667 12.068631,38.1422619 11.8331548,37.7182143 L9.14130952,33.521131 L9.18976191,33.3839286 L8.86791665,33.46125 L8.86791665,33.46125 Z M19.4280357,32.6814881 C19.4633017,32.7545588 19.4975904,32.8280971 19.5308929,32.9020833 C19.659881,33.1908929 19.7622024,33.7025 19.2197619,34.1791667 L19.2441071,34.1644048 C19.813631,33.8514881 20.1422619,33.5016072 20.2394643,33.1019643 C19.9854167,33.0741072 19.7174405,32.9361905 19.4280357,32.6814881 L19.4280357,32.6814881 Z M15.8682738,30.1896429 L16.0244643,30.4331548 L16.1575595,30.26125 C15.7708333,29.7120833 15.122381,28.7272619 14.1843452,27.2647024 L14.1000595,27.1333333 L14.2268452,26.8298214 L13.8015476,26.80375 L13.7875,26.9945238 L13.8098214,26.9802381 L15.8682738,30.1896429 L15.8682738,30.1896429 Z" id="形状" fill="#00BF8A"></path>
<path d="M17.8620833,23.9360119 L17.9013095,23.7967857 C18.4469047,23.7133928 18.9092857,23.6833333 19.2881548,23.7060714 C19.6666667,23.7298214 19.9172024,23.8357143 20.0379167,24.0239286 C20.1590476,24.2127976 20.1972023,24.4067262 20.1540476,24.6055357 C20.1102976,24.8048809 20.0581547,24.9238095 19.9976786,24.9625595 C19.876131,25.0405357 19.7073214,24.9776786 19.4913095,24.7739286 C19.1758333,24.4822619 18.6325,24.2030952 17.8620833,23.9360119 L17.8620833,23.9360119 Z M23.6352976,29.532619 C24.1456547,29.6617262 24.7254762,29.6802381 25.3727381,29.5878571 C26.0203571,29.496131 27.0089286,29.0519047 28.3395833,28.2554762 C29.6695238,27.4595238 31.1025,26.4549405 32.6369643,25.2425 L32.7406548,25.4042262 C32.2197024,25.9281547 32.0872619,26.3554167 32.3426786,26.686369 C30.916369,27.6011905 29.7385714,28.3182143 28.8096429,28.8382738 C27.8797024,29.3580953 27.0782738,29.7107738 26.4050595,29.8956548 C25.7307143,30.0803572 25.123869,30.1183333 24.5830357,30.0088095 C24.0115476,29.9189286 23.6542262,29.9296429 23.51125,30.0400595 C23.3680357,30.1515476 23.2371429,30.4636905 23.1170238,30.9775595 C22.997381,31.4920238 22.9475595,31.9322619 22.9691667,32.2990476 L21.9494643,32.21125 C22.1452977,31.5152381 22.527381,30.7763095 23.0956548,29.9927976 L20.9177976,26.5972619 L20.5992262,26.8015476 C20.2045833,27.0546428 19.8664286,27.328631 19.584881,27.6233929 L18.9419643,27.5222619 L20.7166667,26.3839881 L20.7304167,25.8046429 L21.7695833,25.8227381 L21.5870833,26.3392857 L23.6352976,29.532619 Z M28.7970833,26.165 C29.2994048,25.8810714 29.6719643,25.6608333 29.915119,25.504881 C30.1575595,25.3493453 30.2102976,25.1639286 30.0717857,24.9480357 L29.2680357,23.694881 L27.1292262,25.0666667 L28.2959524,26.8857738 L27.86,27.5076786 L26.5376786,25.4460714 L24.5354167,26.7302976 L25.779881,28.6705952 L25.2983929,29.3217262 C24.8615477,28.575 24.2464881,27.5815476 23.45125,26.3416667 C22.656369,25.1025 22.0444048,24.1827381 21.6167857,23.5816667 L22.6497024,23.4897024 L24.6064286,22.2347024 C24.2689881,21.8431548 23.6783333,21.6889286 22.833869,21.7741071 L22.8471429,21.5945238 C23.4144643,21.3447024 24.0276786,21.1992262 24.6858929,21.1567857 L25.42875,19.3110119 L22.379881,21.2665476 C21.9546429,21.5392857 21.6016667,21.8227381 21.32,22.1175 L20.6770833,22.0163095 L25.3186905,19.0392857 L25.4949405,18.4128571 L26.8066071,18.6555357 C26.3039286,18.9404762 25.6684523,19.7849405 24.900119,21.1905357 C24.9648214,21.2256547 25.032381,21.2964881 25.10125,21.403869 C25.1879167,21.5390476 25.1895833,21.7091071 25.1070833,21.913631 L27.1548214,20.6002381 L27.2140476,19.9917262 L28.1818452,19.998631 L28.0447619,20.4858333 L30.7930357,24.7707143 C31.1169643,25.2100595 31.0364286,25.7181548 30.5506548,26.2953571 C30.2782738,25.9379762 29.7280953,25.9485119 28.9008333,26.3266071 L28.7970833,26.165 L28.7970833,26.165 Z M22.66875,23.819881 L23.4464881,25.0325595 L25.44875,23.7483333 L24.6710119,22.5356548 L22.66875,23.819881 L22.66875,23.819881 Z M23.6020833,25.2750595 L24.379881,26.4877976 L26.3821429,25.2035714 L25.6043452,23.9908333 L23.6020833,25.2750595 L23.6020833,25.2750595 Z M25.2625595,22.15625 L26.0402976,23.3689286 L28.1791071,21.9971429 L27.4013095,20.7844643 L25.2625595,22.15625 Z M26.1958929,23.6114286 L26.9736905,24.8241667 L29.1125,23.452381 L28.3347024,22.2396429 L26.1958929,23.6114286 L26.1958929,23.6114286 Z" id="形状" fill="#00BF8A"></path>
<path d="M23.2864286,32.6251786 L21.5655357,32.4770238 L21.6629762,32.1307738 C21.8531547,31.454881 22.2139881,30.7335119 22.7365476,29.9843452 L20.8279167,27.0085714 L20.759881,27.0522024 C20.3871429,27.2913095 20.0641667,27.552619 19.8000595,27.8291071 L19.6924405,27.9417262 L18.1220238,27.6947024 L20.4228571,26.2189881 L20.4399405,25.5020238 L22.1878571,25.5324405 L21.9161905,26.30125 L23.8205357,29.2703571 C24.0623809,29.3219643 24.3235119,29.3481547 24.59875,29.3481548 L24.5988095,29.3481548 C24.7157143,29.3481548 24.8364881,29.3434524 24.9602976,29.3340476 C24.52625,28.5988095 23.934881,27.6472619 23.2006548,26.5025 C22.4181548,25.2825595 21.803631,24.3579762 21.3741667,23.7544048 L21.0732143,23.3314286 L22.5503571,23.1999405 L24.093869,22.21 C23.80375,22.0644048 23.388869,22.0174405 22.8635714,22.0704167 L22.5107738,22.1060119 L22.5549405,21.5079762 L22.5403571,21.5172619 C22.1372619,21.7758333 21.7989881,22.0469643 21.535,22.3233333 L21.427381,22.4359524 L19.8570238,22.1888095 L25.0625595,18.8500595 L25.2817857,18.0710119 L27.6639881,18.5117857 L26.9531548,18.9147024 C26.6552977,19.0835119 26.1252977,19.6077381 25.2724405,21.1320833 C25.2991667,21.1657738 25.3255357,21.2028572 25.3514881,21.2433929 C25.373631,21.2779167 25.3950595,21.3179762 25.4132738,21.3636905 L26.872381,20.4278571 L26.9439286,19.692381 L28.57375,19.7039881 L28.3672619,20.4379167 L31.0383929,24.602619 C31.271131,24.9228571 31.4341667,25.414881 31.0770833,26.0597024 C31.5413782,25.7173121 31.9998563,25.3671034 32.4523214,25.0092262 L32.7100595,24.8055952 L33.12,25.4449405 L32.9516071,25.6143452 C32.5553571,26.0127976 32.4297023,26.3124404 32.5782143,26.5048214 L32.7766071,26.7618452 L32.5032738,26.9371429 C31.0830357,27.8480953 29.8891667,28.5752381 28.9549405,29.0982738 C28.007381,29.6279167 27.1760119,29.9927977 26.48375,30.1829167 C25.7688095,30.3786905 25.1124405,30.4186905 24.5304762,30.3021429 C24.2940476,30.2651786 24.0967857,30.2464286 23.9442262,30.2464286 C23.7472619,30.2464286 23.6898214,30.2782738 23.6892262,30.2785714 C23.6885714,30.2794048 23.561131,30.3848214 23.4066667,31.0455952 C23.29375,31.53125 23.2464286,31.9472619 23.2660714,32.2819048 L23.2864286,32.6251786 Z M24.9466667,26.820119 L26.1411905,28.6825595 L25.7651786,29.191131 C26.3595833,29.0070238 27.1710119,28.6080953 28.1868452,28.000119 C28.8855357,27.5819643 29.6188095,27.101369 30.3803571,26.5628571 L30.3139881,26.4757738 C30.2671429,26.4142857 30.1791667,26.3325595 29.9571429,26.3325595 C29.7226786,26.3325595 29.4089286,26.4216667 29.0246429,26.5973214 L28.7898214,26.7046429 L28.3767262,26.0608333 L28.6507738,25.9059524 C29.1420833,25.6282738 29.5133929,25.4090476 29.7545833,25.2544048 C29.8333333,25.2038691 29.848631,25.1714286 29.85,25.1684524 C29.8494048,25.1683333 29.8469643,25.1485714 29.8214286,25.10875 L29.1783333,24.106131 L27.5404762,25.1565476 L28.6542857,26.8931548 L27.8490476,28.0418452 L26.4479167,25.8573214 L24.9466667,26.820119 L24.9466667,26.820119 Z M24.0132738,25.3649405 L24.4697024,26.0766071 L25.9708929,25.1136905 L25.5144048,24.4020238 L24.0132738,25.3649405 Z M23.0799405,23.9097024 L23.5363095,24.621369 L25.0375,23.6585119 L24.581131,22.9468452 L23.0799405,23.9097024 L23.0799405,23.9097024 Z M26.6070833,23.70125 L27.0635714,24.4129762 L28.7013095,23.3625595 L28.2448214,22.6508333 L26.6070833,23.70125 Z M25.67375,22.2460714 L26.1301786,22.9577381 L27.7679167,21.9073214 L27.3114881,21.1956548 L25.67375,22.2460714 Z M24.8044048,20.0650595 L23.0422619,21.1952976 C23.4942262,21.0298214 23.9754167,20.9224405 24.4785119,20.8748214 L24.8044048,20.0650595 L24.8044048,20.0650595 Z M19.8858333,25.2925009 C19.6984524,25.2925009 19.5025595,25.193631 19.2870238,24.9902976 C19.0060119,24.7305357 18.4930357,24.4697619 17.7645833,24.2172024 L17.4995238,24.1253571 L17.6667857,23.5315476 L17.8563095,23.502619 C18.4195833,23.4165476 18.9066667,23.385119 19.3058929,23.4089881 C19.7840477,23.4389881 20.1143453,23.5918452 20.2883929,23.8632738 C20.452619,24.1192857 20.5052381,24.3902381 20.4448214,24.6685714 C20.3801786,24.9630357 20.2945238,25.1256548 20.1583333,25.2129762 C20.0770096,25.2650763 19.9824147,25.292682 19.8858333,25.2925009 L19.8858333,25.2925009 Z" id="形状" fill="#00BF8A"></path>
<path d="M29.6220833,16.33625 L29.6353571,16.1566071 C30.3369643,16.048869 30.8735119,16.0185714 31.24625,16.0647024 C31.6183929,16.1113095 31.8617857,16.2404762 31.9765476,16.4521429 C32.0904762,16.6642857 32.1208333,16.8445238 32.0667262,16.9933333 C32.0119047,17.1425595 31.9546428,17.236369 31.8942857,17.275119 C31.7726786,17.3530952 31.5473809,17.2693452 31.2190476,17.0235119 C30.7905952,16.6904167 30.2582738,16.4613095 29.6220833,16.33625 L29.6220833,16.33625 Z M35.5250595,22.135 C36.0314881,22.1908333 36.5653571,22.1719643 37.126131,22.0779167 C37.6867262,21.9849405 38.3444643,21.7244047 39.0985119,21.2979167 C39.8525,20.8713095 40.5175,20.4733333 41.0941071,20.1035119 C41.518631,19.8313095 41.9879167,19.5115476 42.5016071,19.14375 C43.015,18.7769643 43.6190476,18.3325 44.3123214,17.8111905 L44.4160119,17.9729167 C43.877619,18.4697023 43.7132738,18.88 43.9207143,19.2033929 C42.5380953,20.0518453 41.386131,20.7434524 40.4657738,21.2767857 C39.5446429,21.8104762 38.7785119,22.1682143 38.1682143,22.3510119 C37.5568453,22.533631 36.9751786,22.59375 36.4207738,22.5304167 C35.8667262,22.4676786 35.5213095,22.4798214 35.3847619,22.567381 C35.2482738,22.6549405 35.1230357,22.9447024 35.010119,23.4352381 C34.8969047,23.9268452 34.8394047,24.4379762 34.8391667,24.9711905 L33.8391667,24.813869 C34.1870299,24.0563693 34.5366142,23.299661 34.8879167,22.54375 L32.7619048,19.2289881 L32.3978571,19.4625 C32.0032143,19.7155952 31.6650595,19.9895238 31.3834524,20.2842262 L30.7405952,20.1831548 L32.4698214,19.0740476 L32.6851786,18.3083333 L33.6852381,18.4656548 L33.5026786,18.9820833 L35.5250595,22.135 L35.5250595,22.135 Z M37.3416667,13.952381 C36.5813095,12.7669048 36.0556547,11.9817262 35.7664881,11.5966071 L37.0982738,11.37 L36.9416667,11.9268452 L37.97875,13.54375 L38.9798214,12.9016667 L39.2343452,11.9967262 L40.5460714,12.2394048 L38.1342262,13.7863095 L40.9343452,18.1520238 C41.1247023,18.448869 41.2031547,18.7213095 41.1703571,18.9705357 C41.1375,19.2197619 41.00375,19.4963095 40.7697619,19.7979762 C40.3114881,19.4839881 39.596369,19.505 38.62625,19.8605952 L38.5225595,19.698869 C39.3935714,19.2543452 39.9200595,18.9736905 40.1020238,18.8569643 C40.2840477,18.7401786 40.3061905,18.5744643 40.1676786,18.3584524 L37.4972024,14.194881 L34.3573214,16.20875 C34.1141667,16.3647619 33.8521429,16.5898214 33.5704762,16.8845833 L32.9275595,16.7834524 L37.3416667,13.952381 Z M34.4795833,17.1003571 L34.4927976,16.9206548 C35.3720833,16.8897024 36.0223214,16.9193453 36.4444643,17.0095833 C36.8663691,17.1009524 37.1305357,17.2452977 37.236369,17.4431548 C37.3417857,17.6419643 37.3721429,17.8223214 37.3265476,17.9842857 C37.2807143,18.1475 37.2275,18.247619 37.1670238,18.286369 C37.0454167,18.3643452 36.8116072,18.267381 36.4659524,17.9942857 C35.9727976,17.6259523 35.3104762,17.3286905 34.4795833,17.1003571 Z" id="形状" fill="#00BF8A"></path>
<path d="M35.1366667,25.3191071 L33.4047024,25.0466071 L33.56875,24.6894643 C33.8940824,23.981146 34.2208887,23.2735056 34.5491667,22.5665476 L32.6721429,19.6400595 L32.558631,19.7128571 C32.1857738,19.9519643 31.8628571,20.2133333 31.5986905,20.4897024 L31.491131,20.6022619 L29.9207143,20.3553571 L32.2139881,18.8844048 L32.4703571,17.9730357 L34.0852381,18.2270833 L33.8318452,18.94375 L35.6974405,21.8524405 C36.1357143,21.8877381 36.597619,21.8647024 37.0769643,21.7842857 C37.6000595,21.6975 38.2307738,21.4467262 38.9520238,21.03875 C39.56375,20.6926786 40.1219048,20.3622024 40.6163095,20.0535119 L40.6016071,20.0434524 C40.2320833,19.7902381 39.5891071,19.8245833 38.72875,20.14 L38.5046429,20.2221429 L38.0947619,19.5830357 L38.3873214,19.43375 C39.4560714,18.8883333 39.8223214,18.6827976 39.941369,18.6064286 C39.946474,18.6031964 39.9514202,18.5997202 39.9561905,18.5960119 C39.9516071,18.5816667 39.941131,18.5564881 39.9171429,18.5191071 L37.407381,14.6060714 L34.5179762,16.4592262 C34.4362013,16.5121817 34.3571708,16.5692593 34.2811905,16.6302381 L34.4822619,16.6231548 C34.7092262,16.6151786 34.9243453,16.611131 35.1215476,16.611131 C35.7155952,16.611131 36.1686905,16.64625 36.5066071,16.7184524 C37.0241071,16.8305357 37.3484523,17.0216072 37.49875,17.3026786 C37.6414286,17.5717262 37.6797024,17.8278571 37.6129167,18.064881 C37.5454762,18.3051786 37.4548214,18.4552381 37.327619,18.5367857 C37.2519643,18.5852976 37.1649405,18.6099405 37.0689881,18.6099405 C36.8595238,18.6099405 36.6175595,18.4928571 36.2845833,18.2302976 C35.8255357,17.8883333 35.1917262,17.6046428 34.4006548,17.3872619 L34.1648214,17.3224405 L34.2114286,16.6872619 C34.0758333,16.8008333 33.9334524,16.9354762 33.7856548,17.0902381 L33.6780357,17.2027976 L32.3742262,16.9976786 C32.3672634,17.0307589 32.3579541,17.0633015 32.346369,17.0950595 C32.2664286,17.3126786 32.1739881,17.4491667 32.0549405,17.5255357 C31.9769048,17.5755952 31.8872024,17.6008928 31.7882143,17.6008929 C31.5871429,17.6008929 31.3495833,17.4930953 31.0405357,17.2617262 C30.6469643,16.9557143 30.1517857,16.743631 29.5645833,16.6282143 L29.3057738,16.5773214 L29.3558929,15.8983333 L29.590119,15.862381 C30.0923214,15.7852381 30.5211905,15.746131 30.8647619,15.746131 C31.0182143,15.746131 31.1588095,15.7539286 31.2827381,15.7692857 C31.7542857,15.8283333 32.0755357,16.0103571 32.2380952,16.3102381 C32.32625,16.4744047 32.3761309,16.6300595 32.3877381,16.7760119 L36.9301786,13.8625595 C36.2664286,12.8322024 35.7952976,12.1305952 35.5283929,11.7751786 L35.2354762,11.3849405 L37.5120833,10.9975595 L37.2642857,11.878631 L38.0685714,13.1324405 L38.7239286,12.7120833 L39.0214286,11.6545833 L41.3401786,12.0835714 L38.5454762,13.8760714 L41.1849405,17.99125 C41.4131548,18.3471429 41.5075595,18.6895833 41.4654762,19.0092857 C41.4380952,19.2173809 41.3558928,19.4372023 41.2203571,19.6660714 C41.5646428,19.43875 41.9360119,19.1825595 42.3283929,18.9016071 C42.8390477,18.5368452 43.44625,18.0899405 44.1335119,17.5732143 L44.3898214,17.3804762 L44.801369,18.0222619 L44.6179167,18.1915476 C44.3850595,18.406369 44.017381,18.8026786 44.1713095,19.042619 L44.3351786,19.2981548 L44.0764286,19.4569643 C42.6896429,20.3079762 41.525119,21.0068453 40.6150595,21.5341667 C39.6798214,22.0760714 38.8852976,22.4467857 38.2536905,22.6359524 C37.6052976,22.8295833 36.977619,22.8933333 36.3870833,22.8259524 C36.167619,22.801131 35.9817857,22.7885119 35.8350595,22.7885119 C35.6397024,22.7885119 35.5652976,22.8108333 35.5466071,22.8179167 C35.5258333,22.839881 35.422381,22.971131 35.3002381,23.5018452 C35.1920238,23.9715476 35.1370833,24.4658928 35.1368452,24.9711905 L35.1366667,25.3191071 L35.1366667,25.3191071 Z" id="形状" fill="#00BF8A"></path>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="50px" height="50px" viewBox="0 0 50 50" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>驳回</title>
<g id="游戏" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="我的任务-撤销页" transform="translate(-1851, -71)" fill-rule="nonzero">
<g id="驳回" transform="translate(1851, 71)">
<rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="50" height="50"></rect>
<path d="M48.9604167,18.1563095 L41.587381,6.53083335 C40.9435714,5.51708335 39.5982143,5.21714287 38.5814286,5.85535713 L1.78476191,29.1335714 C0.770773828,29.777381 0.471071436,31.1227381 1.10791665,32.1336905 L8.48095239,43.7606548 C9.12482144,44.7718453 10.470119,45.0715477 11.4841667,44.4333929 L48.2822024,21.1567857 C49.2989881,20.512619 49.6044643,19.1689286 48.9604167,18.1563095 Z M47.4918452,19.907381 L10.6938095,43.1870238 C10.3683333,43.3920833 9.94232144,43.2960714 9.73726191,42.9719643 L2.36422617,31.3450595 C2.15910713,31.0195238 2.25517856,30.5949405 2.58065479,30.3870833 L39.380119,7.10886904 C39.7058929,6.90517856 40.1332143,7.00142856 40.3352976,7.32553569 L47.711369,18.9522619 C47.9092262,19.2707738 47.8117857,19.6981548 47.4918452,19.907381 Z M15.7707738,12.5301786 L16.3818452,13.9957143 L17.1735714,12.6204167 L18.7553571,12.4927381 L17.6897619,11.313869 L18.0526786,9.77208335 L16.6069048,10.4219643 L15.2488095,9.6 L15.4208333,11.1790476 L14.2161905,12.2060714 L15.7707738,12.5301786 L15.7707738,12.5301786 Z M25.1401786,8.16726191 L24.3800595,6.77196431 L23.73625,8.22470239 L22.1730357,8.52303569 L23.3532738,9.58142856 L23.1495833,11.1546429 L24.5263095,10.3586905 L25.9620833,11.04 L25.6307738,9.48541665 L26.7191667,8.33232144 L25.1401786,8.16726191 Z M39.4247619,31.540119 L38.1668452,30.5733333 L38.16125,32.1581548 L36.8475595,33.0489286 L38.3605357,33.5479762 L38.8064881,35.0695238 L39.7444643,33.7888095 L41.3320833,33.8332738 L40.3999405,32.5455357 L40.9377381,31.0581548 L39.4247619,31.540119 L39.4247619,31.540119 Z M34.2903571,37.8589286 L33.6909524,36.3889881 L32.8861905,37.75875 L31.3057738,37.8734524 L32.361369,39.0580357 L31.9855952,40.5982143 L33.4397619,39.9629762 L34.7923214,40.8032738 L34.6330357,39.2228571 L35.8376786,38.1974405 L34.2903571,37.8589286 L34.2903571,37.8589286 Z M24.884881,42.1558333 L25.6380357,43.5569643 L26.294881,42.1083929 L27.8580952,41.8289286 L26.6848214,40.758869 L26.900119,39.1870833 L25.5175595,39.9688095 L24.0889881,39.2775595 L24.4073214,40.8291071 L23.3030952,41.9780357 L24.884881,42.1558333 L24.884881,42.1558333 Z M10.7956548,18.6727381 L12.046369,19.655119 L12.0649405,18.0689286 L13.3844643,17.1825595 L11.879881,16.6733333 L11.4452976,15.1445833 L10.4959524,16.4166667 L8.90833335,16.3592262 L9.82767856,17.6529167 L9.27964287,19.1445238 L10.7956548,18.6727381 L10.7956548,18.6727381 Z M5.20952383,25.5207738 C5.04327383,18.8059524 8.30892861,12.1672024 14.3926786,8.31934521 C20.4777976,4.47142856 27.8752976,4.36238091 33.8844048,7.37720239 L35.3357738,6.45922617 C33.5575,5.46541665 31.6443453,4.73815474 29.6294048,4.28636904 C26.9373214,3.68113096 24.1952977,3.60529761 21.4845833,4.05130952 C18.6779167,4.51583335 16.0247024,5.52845239 13.6009524,7.06446431 C11.178631,8.6004167 9.12482144,10.562381 7.50416665,12.900119 C5.93517856,15.1545833 4.83238096,17.6659524 4.22571431,20.3535714 C3.77392861,22.3655357 3.61327383,24.4049405 3.75392856,26.437381 L5.20952383,25.5207738 Z M44.7254167,24.4939881 C44.898869,31.2088095 41.6332143,37.8475595 35.5494643,41.6940476 C29.4657143,45.546131 22.0669048,45.652381 16.0591071,42.637619 L14.6049405,43.5569643 C16.3832143,44.5479167 18.2977381,45.2767262 20.3129762,45.7283929 C23.0047619,46.333631 25.7468452,46.4125 28.4575,45.9634524 C31.2641667,45.498869 33.9174405,44.4876786 36.3397619,42.9516667 C38.7620833,41.4156547 40.8158929,39.4536905 42.4379167,37.117381 C44.001131,34.860119 45.1039286,32.3503571 45.7091667,29.6641071 C46.1623214,27.6505357 46.3202381,25.6097619 46.1795238,23.577381 L44.7254167,24.4939881 Z M18.781131,15.243631 C20.485,14.1680357 22.3593453,13.5941667 24.2410714,13.4795238 L26.4869048,12.0595833 C23.5195238,11.7096429 20.5480357,12.3780953 17.9838095,13.9973214 C15.4266071,15.6149405 13.5520833,18.0172619 12.6013095,20.8453571 L14.8457738,19.4256548 C15.7579762,17.7675596 17.0789286,16.3220238 18.781131,15.243631 Z M31.1595238,34.7697619 C29.4556548,35.8483929 27.5827381,36.4220238 25.7010119,36.5366667 L23.4564881,37.9566071 C26.4225,38.3065476 29.392619,37.6366667 31.9582143,36.0174405 C34.5154167,34.40125 36.3899405,31.9975 37.3392857,29.1694048 L35.0961905,30.5921429 C34.1841071,32.2427977 32.8617857,33.6941667 31.1595238,34.7697619 Z" id="形状" fill="#FF4D4F"></path>
<g id="已驳回" transform="translate(25.0359, 25) rotate(-32) translate(-25.0359, -25)translate(8.2659, 19.372)" fill="#FF4D4F">
<path d="M6.3,4.74 L6.3,1.74 L0.744,1.74 C0.592,1.74 0.448,1.768 0.312,1.824 L0,1.284 C0.224,1.324 0.424,1.344 0.6,1.344 L6.084,1.344 C6.316,0.888 6.444,0.642 6.468,0.606 C6.492,0.57 6.536,0.552 6.6,0.552 C6.664,0.552 6.776,0.6 6.936,0.696 C7.096,0.792 7.338,0.948 7.662,1.164 C7.986,1.38 8.176,1.514 8.232,1.566 C8.288,1.618 8.316,1.672 8.316,1.728 C8.316,1.84 8.184,1.952 7.92,2.064 L7.92,4.236 C7.92,4.516 7.924,4.748 7.932,4.932 L7.956,5.412 C7.956,5.492 7.912,5.562 7.824,5.622 C7.736,5.682 7.582,5.734 7.362,5.778 C7.142,5.822 6.934,5.844 6.738,5.844 C6.542,5.844 6.42,5.828 6.372,5.796 C6.324,5.764 6.3,5.712 6.3,5.64 L6.3,5.136 L1.644,5.136 L1.644,8.736 C1.644,8.984 1.708,9.174 1.836,9.306 C1.964,9.438 2.218,9.538 2.598,9.606 C2.978,9.674 3.504,9.708 4.176,9.708 C5.88,9.708 6.948,9.648 7.38,9.528 C7.812,9.408 8.128,9.188 8.328,8.868 C8.528,8.548 8.72,8.004 8.904,7.236 C8.928,7.132 8.964,7.08 9.012,7.08 C9.06,7.08 9.078,7.166 9.066,7.338 C9.054,7.51 9.048,7.688 9.048,7.872 C9.048,8.304 9.1,8.614 9.204,8.802 C9.308,8.99 9.48,9.16 9.72,9.312 C9.872,9.4 9.948,9.538 9.948,9.726 C9.948,9.914 9.806,10.132 9.522,10.38 C9.238,10.628 8.774,10.79 8.13,10.866 C7.486,10.942 6.536,10.98 5.28,10.98 C3.672,10.98 2.532,10.926 1.86,10.818 C1.188,10.71 0.74,10.522 0.516,10.254 C0.292,9.986 0.18,9.548 0.18,8.94 L0.18,4.752 C0.18,4.208 0.168,3.76 0.144,3.408 C0.528,3.448 0.896,3.506 1.248,3.582 C1.6,3.658 1.802,3.714 1.854,3.75 C1.906,3.786 1.932,3.828 1.932,3.876 C1.932,3.98 1.836,4.06 1.644,4.116 L1.644,4.74 L6.3,4.74 Z" id="路径"></path>
<path d="M18.828,1.716 C19.148,1.14 19.388,0.568 19.548,-9.09494702e-13 C19.876,0.12 20.212,0.268 20.556,0.444 C20.9,0.62 21.118,0.742 21.21,0.81 C21.302,0.878 21.348,0.944 21.348,1.008 C21.348,1.072 21.29,1.114 21.174,1.134 C21.058,1.154 20.894,1.292 20.682,1.548 C20.47,1.804 20.264,2.048 20.064,2.28 C21.104,2.84 21.624,3.388 21.624,3.924 C21.624,4.156 21.546,4.362 21.39,4.542 C21.234,4.722 21.014,4.812 20.73,4.812 C20.446,4.812 20.214,4.656 20.034,4.344 C19.854,4.032 19.536,3.66 19.08,3.228 C18.464,3.732 17.834,4.148 17.19,4.476 C16.546,4.804 16.152,4.968 16.008,4.968 C15.96,4.968 15.936,4.948 15.936,4.908 C15.936,4.868 15.996,4.804 16.116,4.716 C16.972,4.084 17.7,3.356 18.3,2.532 C17.596,1.948 16.868,1.444 16.116,1.02 C16.028,0.964 15.984,0.922 15.984,0.894 C15.984,0.866 16.008,0.852 16.056,0.852 C16.144,0.852 16.518,0.952 17.178,1.152 C17.838,1.352 18.388,1.54 18.828,1.716 Z M14.004,5.676 L14.364,1.38 L11.868,1.38 C11.716,1.38 11.572,1.408 11.436,1.464 L11.136,0.96 C11.328,0.976 11.528,0.984 11.736,0.984 L14.172,0.984 C14.34,0.672 14.45,0.48 14.502,0.408 C14.554,0.336 14.612,0.3 14.676,0.3 C14.74,0.3 14.98,0.45 15.396,0.75 C15.812,1.05 16.02,1.246 16.02,1.338 C16.02,1.43 15.896,1.524 15.648,1.62 L15.324,5.064 C15.604,5.224 15.856,5.388 16.08,5.556 C16.304,5.724 16.448,5.842 16.512,5.91 C16.576,5.978 16.608,6.046 16.608,6.114 C16.608,6.182 16.476,6.284 16.212,6.42 C16.132,7.42 16.058,8.222 15.99,8.826 C15.922,9.43 15.85,9.846 15.774,10.074 C15.698,10.302 15.578,10.498 15.414,10.662 C15.25,10.826 15.024,10.96 14.736,11.064 C14.448,11.168 14.192,11.22 13.968,11.22 C13.776,11.22 13.676,11.12 13.668,10.92 C13.652,10.6 13.572,10.368 13.428,10.224 C13.284,10.08 13.032,9.936 12.672,9.792 C12.576,9.752 12.528,9.718 12.528,9.69 C12.528,9.662 12.592,9.656 12.72,9.672 C13.112,9.712 13.416,9.732 13.632,9.732 C14.064,9.732 14.328,9.642 14.424,9.462 C14.52,9.282 14.62,8.688 14.724,7.68 C13.476,8.2 12.684,8.534 12.348,8.682 C12.012,8.83 11.76,8.958 11.592,9.066 C11.424,9.174 11.324,9.228 11.292,9.228 C11.26,9.228 11.234,9.21 11.214,9.174 C11.194,9.138 11.14,8.972 11.052,8.676 C10.964,8.38 10.868,8.012 10.764,7.572 C12.268,7.556 13.596,7.504 14.748,7.416 L14.844,6.072 L12.648,6.072 L12.408,6.324 C12.352,6.388 12.296,6.42 12.24,6.42 C12.184,6.42 11.982,6.318 11.634,6.114 C11.286,5.91 11.112,5.78 11.112,5.724 C11.112,5.668 11.152,5.616 11.232,5.568 C11.424,5.456 11.524,5.284 11.532,5.052 L11.604,3.576 C11.652,3.008 11.668,2.584 11.652,2.304 C12.372,2.4 12.812,2.474 12.972,2.526 C13.132,2.578 13.212,2.638 13.212,2.706 C13.212,2.774 13.132,2.848 12.972,2.928 L12.768,5.676 L14.004,5.676 Z M19.776,8.784 C20.368,9.176 21.088,9.488 21.936,9.72 C22.08,9.76 22.152,9.798 22.152,9.834 C22.152,9.87 22.084,9.924 21.948,9.996 C21.596,10.18 21.308,10.552 21.084,11.112 C21.044,11.208 20.996,11.256 20.94,11.256 C20.844,11.256 20.552,11.094 20.064,10.77 C19.576,10.446 19.16,10.096 18.816,9.72 C18.12,10.24 17.338,10.626 16.47,10.878 C15.602,11.13 15.096,11.256 14.952,11.256 C14.928,11.256 14.916,11.252 14.916,11.244 C14.916,11.22 15.004,11.16 15.18,11.064 C16.596,10.312 17.604,9.584 18.204,8.88 C17.836,8.256 17.58,7.552 17.436,6.768 C17.292,5.984 17.22,5.436 17.22,5.124 C17.22,5.02 17.24,4.968 17.28,4.968 C17.32,4.968 17.356,5.032 17.388,5.16 C17.708,6.36 18.192,7.304 18.84,7.992 C19.304,7.2 19.6,6.2 19.728,4.992 C20.952,5.248 21.564,5.44 21.564,5.568 C21.564,5.624 21.512,5.676 21.408,5.724 C21.304,5.772 21.222,5.854 21.162,5.97 C21.102,6.086 21.016,6.296 20.904,6.6 C20.592,7.488 20.216,8.216 19.776,8.784 Z" id="形状"></path>
<path d="M25.224,1.296 L31.356,1.296 C31.444,1.112 31.53,0.948 31.614,0.804 C31.698,0.66 31.754,0.576 31.782,0.552 C31.81,0.528 31.848,0.516 31.896,0.516 C31.992,0.516 32.29,0.68 32.79,1.008 C33.29,1.336 33.54,1.554 33.54,1.662 C33.54,1.77 33.392,1.896 33.096,2.04 L33.096,9.204 C33.096,9.572 33.1,9.828 33.108,9.972 L33.12,10.368 C33.12,10.512 32.996,10.636 32.748,10.74 C32.5,10.844 32.196,10.896 31.836,10.896 C31.644,10.896 31.548,10.78 31.548,10.548 L31.548,9.876 L25.032,9.876 L25.032,10.392 C25.032,10.496 25.012,10.578 24.972,10.638 C24.932,10.698 24.83,10.762 24.666,10.83 C24.502,10.898 24.312,10.952 24.096,10.992 C23.88,11.032 23.744,11.052 23.688,11.052 C23.632,11.052 23.604,11.016 23.604,10.944 L23.628,10.38 C23.644,9.988 23.652,9.632 23.652,9.312 L23.652,1.752 C23.652,1.352 23.644,0.996 23.628,0.684 C24.116,0.804 24.648,1.008 25.224,1.296 Z M31.548,9.48 L31.548,1.692 L25.176,1.692 C25.144,1.732 25.096,1.764 25.032,1.788 L25.032,9.48 L31.548,9.48 Z M27.42,3.564 L29.028,3.564 C29.236,3.156 29.382,2.952 29.466,2.952 C29.55,2.952 29.722,3.042 29.982,3.222 C30.242,3.402 30.46,3.558 30.636,3.69 C30.812,3.822 30.9,3.946 30.9,4.062 C30.9,4.178 30.788,4.264 30.564,4.32 L30.564,6.984 C30.564,7.12 30.568,7.24 30.576,7.344 L30.6,7.608 C30.6,7.68 30.56,7.732 30.48,7.764 L30.156,7.896 C30.02,7.944 29.852,7.968 29.652,7.968 C29.452,7.968 29.33,7.96 29.286,7.944 C29.242,7.928 29.202,7.896 29.166,7.848 C29.13,7.8 29.112,7.744 29.112,7.68 L29.112,7.296 L27.36,7.296 L27.36,7.74 C27.36,7.788 27.35,7.822 27.33,7.842 C27.31,7.862 27.238,7.9 27.114,7.956 C26.99,8.012 26.862,8.05 26.73,8.07 C26.598,8.09 26.42,8.1 26.196,8.1 C26.052,8.1 25.984,8.032 25.992,7.896 C26.008,7.712 26.016,7.416 26.016,7.008 L26.016,4.02 C26.016,3.684 26.004,3.344 25.98,3 C26.572,3.2 27.052,3.388 27.42,3.564 Z M29.112,6.9 L29.112,3.96 L27.612,3.96 C27.564,4.016 27.48,4.072 27.36,4.128 L27.36,6.9 L29.112,6.9 Z" id="形状"></path>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="50px" height="50px" viewBox="0 0 50 50" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>已撤销</title>
<g id="游戏" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="我的任务-撤销页" transform="translate(-404, -777)" fill-rule="nonzero">
<g id="编组-4备份-4" transform="translate(132, 727.96)">
<g id="已撤销" transform="translate(272, 49.04)">
<rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="50" height="50"></rect>
<path d="M48.9604167,18.1563095 L41.587381,6.53083335 C40.9435714,5.51708335 39.5982143,5.21714287 38.5814286,5.85535713 L1.78476191,29.1335714 C0.770773828,29.777381 0.471071436,31.1227381 1.10791665,32.1336905 L8.48095239,43.7606548 C9.12482144,44.7718453 10.470119,45.0715477 11.4841667,44.4333929 L48.2822024,21.1567857 C49.2989881,20.512619 49.6044643,19.1689286 48.9604167,18.1563095 Z M47.4918452,19.907381 L10.6938095,43.1870238 C10.3683333,43.3920833 9.94232144,43.2960714 9.73726191,42.9719643 L2.36422617,31.3450595 C2.15910713,31.0195238 2.25517856,30.5949405 2.58065479,30.3870833 L39.380119,7.10886904 C39.7058929,6.90517856 40.1332143,7.00142856 40.3352976,7.32553569 L47.711369,18.9522619 C47.9092262,19.2707738 47.8117857,19.6981548 47.4918452,19.907381 Z M15.7707738,12.5301786 L16.3818452,13.9957143 L17.1735714,12.6204167 L18.7553571,12.4927381 L17.6897619,11.313869 L18.0526786,9.77208335 L16.6069048,10.4219643 L15.2488095,9.6 L15.4208333,11.1790476 L14.2161905,12.2060714 L15.7707738,12.5301786 L15.7707738,12.5301786 Z M25.1401786,8.16726191 L24.3800595,6.77196431 L23.73625,8.22470239 L22.1730357,8.52303569 L23.3532738,9.58142856 L23.1495833,11.1546429 L24.5263095,10.3586905 L25.9620833,11.04 L25.6307738,9.48541665 L26.7191667,8.33232144 L25.1401786,8.16726191 Z M39.4247619,31.540119 L38.1668452,30.5733333 L38.16125,32.1581548 L36.8475595,33.0489286 L38.3605357,33.5479762 L38.8064881,35.0695238 L39.7444643,33.7888095 L41.3320833,33.8332738 L40.3999405,32.5455357 L40.9377381,31.0581548 L39.4247619,31.540119 L39.4247619,31.540119 Z M34.2903571,37.8589286 L33.6909524,36.3889881 L32.8861905,37.75875 L31.3057738,37.8734524 L32.361369,39.0580357 L31.9855952,40.5982143 L33.4397619,39.9629762 L34.7923214,40.8032738 L34.6330357,39.2228571 L35.8376786,38.1974405 L34.2903571,37.8589286 L34.2903571,37.8589286 Z M24.884881,42.1558333 L25.6380357,43.5569643 L26.294881,42.1083929 L27.8580952,41.8289286 L26.6848214,40.758869 L26.900119,39.1870833 L25.5175595,39.9688095 L24.0889881,39.2775595 L24.4073214,40.8291071 L23.3030952,41.9780357 L24.884881,42.1558333 L24.884881,42.1558333 Z M10.7956548,18.6727381 L12.046369,19.655119 L12.0649405,18.0689286 L13.3844643,17.1825595 L11.879881,16.6733333 L11.4452976,15.1445833 L10.4959524,16.4166667 L8.90833335,16.3592262 L9.82767856,17.6529167 L9.27964287,19.1445238 L10.7956548,18.6727381 L10.7956548,18.6727381 Z M5.20952383,25.5207738 C5.04327383,18.8059524 8.30892861,12.1672024 14.3926786,8.31934521 C20.4777976,4.47142856 27.8752976,4.36238091 33.8844048,7.37720239 L35.3357738,6.45922617 C33.5575,5.46541665 31.6443453,4.73815474 29.6294048,4.28636904 C26.9373214,3.68113096 24.1952977,3.60529761 21.4845833,4.05130952 C18.6779167,4.51583335 16.0247024,5.52845239 13.6009524,7.06446431 C11.178631,8.6004167 9.12482144,10.562381 7.50416665,12.900119 C5.93517856,15.1545833 4.83238096,17.6659524 4.22571431,20.3535714 C3.77392861,22.3655357 3.61327383,24.4049405 3.75392856,26.437381 L5.20952383,25.5207738 Z M44.7254167,24.4939881 C44.898869,31.2088095 41.6332143,37.8475595 35.5494643,41.6940476 C29.4657143,45.546131 22.0669048,45.652381 16.0591071,42.637619 L14.6049405,43.5569643 C16.3832143,44.5479167 18.2977381,45.2767262 20.3129762,45.7283929 C23.0047619,46.333631 25.7468452,46.4125 28.4575,45.9634524 C31.2641667,45.498869 33.9174405,44.4876786 36.3397619,42.9516667 C38.7620833,41.4156547 40.8158929,39.4536905 42.4379167,37.117381 C44.001131,34.860119 45.1039286,32.3503571 45.7091667,29.6641071 C46.1623214,27.6505357 46.3202381,25.6097619 46.1795238,23.577381 L44.7254167,24.4939881 Z M18.781131,15.243631 C20.485,14.1680357 22.3593453,13.5941667 24.2410714,13.4795238 L26.4869048,12.0595833 C23.5195238,11.7096429 20.5480357,12.3780953 17.9838095,13.9973214 C15.4266071,15.6149405 13.5520833,18.0172619 12.6013095,20.8453571 L14.8457738,19.4256548 C15.7579762,17.7675596 17.0789286,16.3220238 18.781131,15.243631 Z M31.1595238,34.7697619 C29.4556548,35.8483929 27.5827381,36.4220238 25.7010119,36.5366667 L23.4564881,37.9566071 C26.4225,38.3065476 29.392619,37.6366667 31.9582143,36.0174405 C34.5154167,34.40125 36.3899405,31.9975 37.3392857,29.1694048 L35.0961905,30.5921429 C34.1841071,32.2427977 32.8617857,33.6941667 31.1595238,34.7697619 Z" id="形状" fill="#86909C"></path>
<g transform="translate(25.5507, 24.7154) rotate(-32) translate(-25.5507, -24.7154)translate(8.5647, 19.0634)" fill="#86909C">
<path d="M6.3,4.716 L6.3,1.716 L0.744,1.716 C0.592,1.716 0.448,1.744 0.312,1.8 L-9.09494702e-13,1.26 C0.224,1.3 0.424,1.32 0.6,1.32 L6.084,1.32 C6.316,0.864 6.444,0.618 6.468,0.582 C6.492,0.546 6.536,0.528 6.6,0.528 C6.664,0.528 6.776,0.576 6.936,0.672 C7.096,0.768 7.338,0.924 7.662,1.14 C7.986,1.356 8.176,1.49 8.232,1.542 C8.288,1.594 8.316,1.648 8.316,1.704 C8.316,1.816 8.184,1.928 7.92,2.04 L7.92,4.212 C7.92,4.492 7.924,4.724 7.932,4.908 L7.956,5.388 C7.956,5.468 7.912,5.538 7.824,5.598 C7.736,5.658 7.582,5.71 7.362,5.754 C7.142,5.798 6.934,5.82 6.738,5.82 C6.542,5.82 6.42,5.804 6.372,5.772 C6.324,5.74 6.3,5.688 6.3,5.616 L6.3,5.112 L1.644,5.112 L1.644,8.712 C1.644,8.96 1.708,9.15 1.836,9.282 C1.964,9.414 2.218,9.514 2.598,9.582 C2.978,9.65 3.504,9.684 4.176,9.684 C5.88,9.684 6.948,9.624 7.38,9.504 C7.812,9.384 8.128,9.164 8.328,8.844 C8.528,8.524 8.72,7.98 8.904,7.212 C8.928,7.108 8.964,7.056 9.012,7.056 C9.06,7.056 9.078,7.142 9.066,7.314 C9.054,7.486 9.048,7.664 9.048,7.848 C9.048,8.28 9.1,8.59 9.204,8.778 C9.308,8.966 9.48,9.136 9.72,9.288 C9.872,9.376 9.948,9.514 9.948,9.702 C9.948,9.89 9.806,10.108 9.522,10.356 C9.238,10.604 8.774,10.766 8.13,10.842 C7.486,10.918 6.536,10.956 5.28,10.956 C3.672,10.956 2.532,10.902 1.86,10.794 C1.188,10.686 0.74,10.498 0.516,10.23 C0.292,9.962 0.18,9.524 0.18,8.916 L0.18,4.728 C0.18,4.184 0.168,3.736 0.144,3.384 C0.528,3.424 0.896,3.482 1.248,3.558 C1.6,3.634 1.802,3.69 1.854,3.726 C1.906,3.762 1.932,3.804 1.932,3.852 C1.932,3.956 1.836,4.036 1.644,4.092 L1.644,4.716 L6.3,4.716 Z" id="路径"></path>
<path d="M15.132,2.268 L14.652,2.268 C14.492,2.268 14.348,2.312 14.22,2.4 L13.908,1.836 C14.1,1.86 14.3,1.872 14.508,1.872 L16.956,1.872 C17.108,1.584 17.228,1.378 17.316,1.254 C17.404,1.13 17.476,1.068 17.532,1.068 C17.692,1.068 18.056,1.364 18.624,1.956 C18.68,1.308 18.712,0.656 18.72,0 C19.184,0.08 19.594,0.164 19.95,0.252 C20.306,0.34 20.506,0.4 20.55,0.432 C20.594,0.464 20.616,0.5 20.616,0.54 C20.616,0.612 20.566,0.67 20.466,0.714 C20.366,0.758 20.292,0.82 20.244,0.9 C20.196,0.98 20.106,1.228 19.974,1.644 C19.842,2.06 19.68,2.52 19.488,3.024 L20.28,3.024 C20.584,2.432 20.784,2.136 20.88,2.136 C20.976,2.136 21.214,2.3 21.594,2.628 C21.974,2.956 22.164,3.17 22.164,3.27 C22.164,3.37 22.088,3.42 21.936,3.42 L20.772,3.42 C21.316,3.548 21.588,3.656 21.588,3.744 C21.588,3.784 21.548,3.834 21.468,3.894 C21.388,3.954 21.332,4.024 21.3,4.104 C21.268,4.184 21.236,4.32 21.204,4.512 C20.988,6.088 20.656,7.336 20.208,8.256 C20.576,8.704 21.128,9.212 21.864,9.78 C21.944,9.844 21.984,9.892 21.984,9.924 C21.984,9.956 21.944,9.984 21.864,10.008 C21.672,10.056 21.486,10.154 21.306,10.302 C21.126,10.45 21,10.594 20.928,10.734 C20.856,10.874 20.79,10.944 20.73,10.944 C20.67,10.944 20.61,10.922 20.55,10.878 C20.49,10.834 20.342,10.656 20.106,10.344 C19.87,10.032 19.672,9.728 19.512,9.432 C19.144,9.928 18.718,10.356 18.234,10.716 C17.75,11.076 17.456,11.256 17.352,11.256 C17.336,11.256 17.328,11.248 17.328,11.232 C17.328,11.168 17.444,11.024 17.676,10.8 C18.188,10.32 18.656,9.544 19.08,8.472 C18.688,7.416 18.516,6.212 18.564,4.86 C18.42,5.092 18.276,5.304 18.132,5.496 C18.156,5.536 18.168,5.58 18.168,5.628 C18.168,5.78 18.044,5.892 17.796,5.964 L17.796,9.996 C17.796,10.276 17.654,10.522 17.37,10.734 C17.086,10.946 16.864,11.052 16.704,11.052 C16.624,11.052 16.558,11.024 16.506,10.968 C16.454,10.912 16.422,10.814 16.41,10.674 C16.398,10.534 16.344,10.412 16.248,10.308 C16.152,10.204 16.018,10.124 15.846,10.068 C15.674,10.012 15.588,9.974 15.588,9.954 C15.588,9.934 15.716,9.924 15.972,9.924 C16.228,9.924 16.398,9.892 16.482,9.828 C16.566,9.764 16.608,9.656 16.608,9.504 L16.608,8.58 L15.336,8.58 L15.336,10.512 C15.336,10.6 15.318,10.656 15.282,10.68 C15.246,10.704 15.13,10.756 14.934,10.836 C14.738,10.916 14.5,10.956 14.22,10.956 C14.148,10.956 14.112,10.924 14.112,10.86 L14.136,10.296 C14.152,9.904 14.16,9.548 14.16,9.228 L14.16,5.952 C14.16,5.56 14.152,5.212 14.136,4.908 C14.672,5.004 15.056,5.104 15.288,5.208 L16.476,5.208 C16.636,4.96 16.734,4.812 16.77,4.764 C16.806,4.716 16.852,4.692 16.908,4.692 C16.94,4.692 17.082,4.764 17.334,4.908 C17.586,5.052 17.792,5.184 17.952,5.304 C18.28,4.36 18.492,3.348 18.588,2.268 L16.5,2.268 C16.684,2.3 16.776,2.362 16.776,2.454 C16.776,2.546 16.712,2.6 16.584,2.616 C16.312,2.64 15.764,3.028 14.94,3.78 L16.968,3.72 C16.84,3.376 16.672,3.136 16.464,3 C16.376,2.944 16.332,2.904 16.332,2.88 C16.332,2.856 16.36,2.844 16.416,2.844 C16.72,2.844 17.088,2.942 17.52,3.138 C17.952,3.334 18.168,3.612 18.168,3.972 C18.168,4.188 18.1,4.376 17.964,4.536 C17.828,4.696 17.664,4.776 17.472,4.776 C17.192,4.776 17.052,4.54 17.052,4.068 C15.852,4.348 15.012,4.604 14.532,4.836 C14.444,4.876 14.372,4.896 14.316,4.896 C14.26,4.896 14.216,4.88 14.184,4.848 C13.888,5.048 13.592,5.256 13.296,5.472 L13.296,9.768 C13.296,10.088 13.284,10.318 13.26,10.458 C13.236,10.598 13.176,10.71 13.08,10.794 C12.984,10.878 12.802,10.958 12.534,11.034 C12.266,11.11 12.068,11.148 11.94,11.148 C11.812,11.148 11.738,11.044 11.718,10.836 C11.698,10.628 11.652,10.47 11.58,10.362 C11.508,10.254 11.366,10.166 11.154,10.098 C10.942,10.03 10.836,9.984 10.836,9.96 C10.836,9.936 10.954,9.924 11.19,9.924 C11.426,9.924 11.62,9.91 11.772,9.882 C11.924,9.854 12.022,9.8 12.066,9.72 C12.11,9.64 12.132,9.508 12.132,9.324 L12.132,6.42 C11.932,6.596 11.768,6.748 11.64,6.876 C11.512,7.004 11.432,7.068 11.4,7.068 C11.368,7.068 11.344,7.058 11.328,7.038 C11.312,7.018 11.224,6.798 11.064,6.378 C10.904,5.958 10.804,5.692 10.764,5.58 C11.236,5.468 11.692,5.348 12.132,5.22 L12.132,3.228 L11.376,3.228 C11.184,3.228 11.012,3.252 10.86,3.3 L10.656,2.784 C10.84,2.816 11.04,2.832 11.256,2.832 L12.132,2.832 L12.132,1.416 C12.132,0.928 12.116,0.496 12.084,0.12 C12.508,0.12 12.868,0.144 13.164,0.192 C13.46,0.24 13.608,0.306 13.608,0.39 C13.608,0.474 13.504,0.556 13.296,0.636 L13.296,2.832 L13.416,2.832 C13.632,2.432 13.786,2.232 13.878,2.232 C13.97,2.232 14.28,2.496 14.808,3.024 C14.928,2.8 15.036,2.548 15.132,2.268 Z M14.676,3.228 L13.296,3.228 L13.296,4.896 C13.656,4.792 13.924,4.712 14.1,4.656 C13.94,4.176 13.86,3.908 13.86,3.852 C13.86,3.78 13.936,3.72 14.088,3.672 C14.304,3.608 14.5,3.46 14.676,3.228 Z M19.956,3.42 L19.32,3.42 C19.144,3.844 18.96,4.216 18.768,4.536 C18.96,5.672 19.208,6.544 19.512,7.152 C19.752,6.128 19.9,4.884 19.956,3.42 Z M15.336,6.648 L16.608,6.648 L16.608,5.604 L15.576,5.604 C15.536,5.708 15.456,5.78 15.336,5.82 L15.336,6.648 Z M16.608,7.044 L15.336,7.044 L15.336,8.184 L16.608,8.184 L16.608,7.044 Z M14.868,0.036 C15.412,0.036 15.876,0.116 16.26,0.276 C16.644,0.436 16.836,0.692 16.836,1.044 C16.836,1.26 16.762,1.446 16.614,1.602 C16.466,1.758 16.268,1.836 16.02,1.836 C15.844,1.836 15.72,1.782 15.648,1.674 C15.576,1.566 15.54,1.41 15.54,1.206 C15.54,1.002 15.482,0.804 15.366,0.612 C15.25,0.42 15.12,0.288 14.976,0.216 C14.832,0.144 14.76,0.096 14.76,0.072 C14.76,0.048 14.796,0.036 14.868,0.036 Z" id="形状"></path>
<path d="M25.176,2.412 L25.98,2.412 C26.236,2.02 26.388,1.794 26.436,1.734 C26.484,1.674 26.536,1.644 26.592,1.644 C26.672,1.644 26.87,1.792 27.186,2.088 C27.502,2.384 27.66,2.578 27.66,2.67 C27.66,2.762 27.544,2.808 27.312,2.808 L25.02,2.808 C24.764,3.376 24.504,3.888 24.24,4.344 L25.632,4.344 C25.912,3.928 26.074,3.698 26.118,3.654 C26.162,3.61 26.204,3.588 26.244,3.588 C26.332,3.588 26.536,3.724 26.856,3.996 C27.176,4.268 27.336,4.46 27.336,4.572 C27.336,4.684 27.228,4.74 27.012,4.74 L25.968,4.74 C25.976,4.9 25.884,5.012 25.692,5.076 L25.692,6.684 L25.896,6.684 C26.176,6.276 26.34,6.042 26.388,5.982 C26.436,5.922 26.484,5.892 26.532,5.892 C26.58,5.892 26.644,5.918 26.724,5.97 C26.804,6.022 26.956,6.154 27.18,6.366 C27.404,6.578 27.556,6.744 27.636,6.864 L27.636,4.584 C27.636,4.184 27.628,3.828 27.612,3.516 C28.14,3.636 28.604,3.776 29.004,3.936 L29.628,3.936 L29.628,1.224 C29.628,0.824 29.62,0.468 29.604,0.156 C29.964,0.164 30.298,0.182 30.606,0.21 C30.914,0.238 31.11,0.272 31.194,0.312 C31.278,0.352 31.32,0.406 31.32,0.474 C31.32,0.542 31.236,0.62 31.068,0.708 L31.068,3.396 C31.508,2.708 31.96,1.804 32.424,0.684 C32.752,0.868 33.07,1.072 33.378,1.296 C33.686,1.52 33.862,1.66 33.906,1.716 C33.95,1.772 33.972,1.822 33.972,1.866 C33.972,1.91 33.952,1.94 33.912,1.956 C33.872,1.972 33.794,1.98 33.678,1.98 C33.562,1.98 33.452,2.006 33.348,2.058 C33.244,2.11 32.91,2.338 32.346,2.742 C31.782,3.146 31.356,3.444 31.068,3.636 L31.068,3.936 L31.68,3.936 L31.944,3.468 C31.984,3.396 32.04,3.36 32.112,3.36 C32.264,3.36 32.564,3.506 33.012,3.798 C33.46,4.09 33.684,4.304 33.684,4.44 C33.684,4.544 33.544,4.652 33.264,4.764 L33.264,9.84 C33.264,10.304 33.22,10.618 33.132,10.782 C33.044,10.946 32.834,11.074 32.502,11.166 C32.17,11.258 31.944,11.304 31.824,11.304 C31.64,11.304 31.52,11.212 31.464,11.028 C31.36,10.692 31.238,10.476 31.098,10.38 C30.958,10.284 30.724,10.208 30.396,10.152 C30.252,10.12 30.18,10.086 30.18,10.05 C30.18,10.014 30.264,9.996 30.432,9.996 C30.984,9.988 31.336,9.956 31.488,9.9 C31.64,9.844 31.716,9.724 31.716,9.54 L31.716,8.016 L29.016,8.016 L29.016,10.848 C29.016,10.92 29.006,10.97 28.986,10.998 C28.966,11.026 28.846,11.08 28.626,11.16 C28.406,11.24 28.198,11.28 28.002,11.28 C27.806,11.28 27.688,11.274 27.648,11.262 C27.608,11.25 27.588,11.22 27.588,11.172 L27.612,10.608 C27.628,10.216 27.636,9.86 27.636,9.54 L27.636,7.032 C27.604,7.064 27.528,7.08 27.408,7.08 L25.692,7.08 L25.692,9.084 C26.58,8.604 27.072,8.336 27.168,8.28 C27.264,8.224 27.328,8.196 27.36,8.196 C27.392,8.196 27.408,8.204 27.408,8.22 C27.408,8.276 27.308,8.408 27.108,8.616 C26.908,8.824 26.506,9.282 25.902,9.99 C25.298,10.698 24.972,11.09 24.924,11.166 C24.876,11.242 24.82,11.28 24.756,11.28 C24.652,11.28 24.47,11.034 24.21,10.542 C23.95,10.05 23.82,9.772 23.82,9.708 C23.82,9.644 23.882,9.592 24.006,9.552 C24.13,9.512 24.212,9.458 24.252,9.39 C24.292,9.322 24.312,9.168 24.312,8.928 L24.312,7.08 L23.436,7.08 C23.276,7.08 23.132,7.124 23.004,7.212 L22.656,6.648 C22.848,6.672 23.048,6.684 23.256,6.684 L24.312,6.684 L24.312,4.74 L24.012,4.74 C23.868,4.996 23.638,5.336 23.322,5.76 C23.006,6.184 22.812,6.396 22.74,6.396 C22.716,6.396 22.704,6.372 22.704,6.324 C22.704,6.276 22.736,6.176 22.8,6.024 C23.504,4.264 23.896,2.368 23.976,0.336 C24.4,0.384 24.824,0.45 25.248,0.534 C25.672,0.618 25.906,0.68 25.95,0.72 C25.994,0.76 26.016,0.8 26.016,0.84 C26.016,0.92 25.972,0.972 25.884,0.996 C25.796,1.02 25.734,1.058 25.698,1.11 C25.662,1.162 25.606,1.298 25.53,1.518 C25.454,1.738 25.336,2.036 25.176,2.412 Z M29.016,5.748 L31.716,5.748 L31.716,4.332 L29.256,4.332 C29.208,4.42 29.128,4.484 29.016,4.524 L29.016,5.748 Z M31.716,6.144 L29.016,6.144 L29.016,7.62 L31.716,7.62 L31.716,6.144 Z M27.24,1.068 C27.432,1.068 27.714,1.13 28.086,1.254 C28.458,1.378 28.752,1.554 28.968,1.782 C29.184,2.01 29.292,2.252 29.292,2.508 C29.292,2.764 29.22,2.974 29.076,3.138 C28.932,3.302 28.758,3.384 28.554,3.384 C28.35,3.384 28.182,3.32 28.05,3.192 C27.918,3.064 27.852,2.916 27.852,2.748 L27.864,2.328 C27.864,2.032 27.82,1.804 27.732,1.644 C27.644,1.484 27.484,1.336 27.252,1.2 C27.188,1.16 27.156,1.128 27.156,1.104 C27.156,1.08 27.184,1.068 27.24,1.068 Z" id="形状"></path>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="50px" height="50px" viewBox="0 0 50 50" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>已通过备份</title>
<g id="审批中心" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="转端-审批记录" transform="translate(-1850, -240)">
<g id="5.反馈/3.Modal弹窗/展示/3空" transform="translate(1296, 0)">
<g id="已通过备份" transform="translate(554, 240)">
<rect id="矩形" fill="#000000" fill-rule="nonzero" opacity="0" x="0" y="0" width="50" height="50"></rect>
<path d="M48.9604167,18.1563095 L41.587381,6.53083335 C40.9435714,5.51708335 39.5982143,5.21714287 38.5814286,5.85535713 L1.78476191,29.1335714 C0.770773828,29.777381 0.471071436,31.1227381 1.10791665,32.1336905 L8.48095239,43.7606548 C9.12482144,44.7718453 10.470119,45.0715477 11.4841667,44.4333929 L48.2822024,21.1567857 C49.2989881,20.512619 49.6044643,19.1689286 48.9604167,18.1563095 Z M47.4918452,19.907381 L10.6938095,43.1870238 C10.3683333,43.3920833 9.94232144,43.2960714 9.73726191,42.9719643 L2.36422617,31.3450595 C2.15910713,31.0195238 2.25517856,30.5949405 2.58065479,30.3870833 L39.380119,7.10886904 C39.7058929,6.90517856 40.1332143,7.00142856 40.3352976,7.32553569 L47.711369,18.9522619 C47.9092262,19.2707738 47.8117857,19.6981548 47.4918452,19.907381 Z M15.7707738,12.5301786 L16.3818452,13.9957143 L17.1735714,12.6204167 L18.7553571,12.4927381 L17.6897619,11.313869 L18.0526786,9.77208335 L16.6069048,10.4219643 L15.2488095,9.6 L15.4208333,11.1790476 L14.2161905,12.2060714 L15.7707738,12.5301786 L15.7707738,12.5301786 Z M25.1401786,8.16726191 L24.3800595,6.77196431 L23.73625,8.22470239 L22.1730357,8.52303569 L23.3532738,9.58142856 L23.1495833,11.1546429 L24.5263095,10.3586905 L25.9620833,11.04 L25.6307738,9.48541665 L26.7191667,8.33232144 L25.1401786,8.16726191 Z M39.4247619,31.540119 L38.1668452,30.5733333 L38.16125,32.1581548 L36.8475595,33.0489286 L38.3605357,33.5479762 L38.8064881,35.0695238 L39.7444643,33.7888095 L41.3320833,33.8332738 L40.3999405,32.5455357 L40.9377381,31.0581548 L39.4247619,31.540119 L39.4247619,31.540119 Z M34.2903571,37.8589286 L33.6909524,36.3889881 L32.8861905,37.75875 L31.3057738,37.8734524 L32.361369,39.0580357 L31.9855952,40.5982143 L33.4397619,39.9629762 L34.7923214,40.8032738 L34.6330357,39.2228571 L35.8376786,38.1974405 L34.2903571,37.8589286 L34.2903571,37.8589286 Z M24.884881,42.1558333 L25.6380357,43.5569643 L26.294881,42.1083929 L27.8580952,41.8289286 L26.6848214,40.758869 L26.900119,39.1870833 L25.5175595,39.9688095 L24.0889881,39.2775595 L24.4073214,40.8291071 L23.3030952,41.9780357 L24.884881,42.1558333 L24.884881,42.1558333 Z M10.7956548,18.6727381 L12.046369,19.655119 L12.0649405,18.0689286 L13.3844643,17.1825595 L11.879881,16.6733333 L11.4452976,15.1445833 L10.4959524,16.4166667 L8.90833335,16.3592262 L9.82767856,17.6529167 L9.27964287,19.1445238 L10.7956548,18.6727381 L10.7956548,18.6727381 Z M5.20952383,25.5207738 C5.04327383,18.8059524 8.30892861,12.1672024 14.3926786,8.31934521 C20.4777976,4.47142856 27.8752976,4.36238091 33.8844048,7.37720239 L35.3357738,6.45922617 C33.5575,5.46541665 31.6443453,4.73815474 29.6294048,4.28636904 C26.9373214,3.68113096 24.1952977,3.60529761 21.4845833,4.05130952 C18.6779167,4.51583335 16.0247024,5.52845239 13.6009524,7.06446431 C11.178631,8.6004167 9.12482144,10.562381 7.50416665,12.900119 C5.93517856,15.1545833 4.83238096,17.6659524 4.22571431,20.3535714 C3.77392861,22.3655357 3.61327383,24.4049405 3.75392856,26.437381 L5.20952383,25.5207738 Z M44.7254167,24.4939881 C44.898869,31.2088095 41.6332143,37.8475595 35.5494643,41.6940476 C29.4657143,45.546131 22.0669048,45.652381 16.0591071,42.637619 L14.6049405,43.5569643 C16.3832143,44.5479167 18.2977381,45.2767262 20.3129762,45.7283929 C23.0047619,46.333631 25.7468452,46.4125 28.4575,45.9634524 C31.2641667,45.498869 33.9174405,44.4876786 36.3397619,42.9516667 C38.7620833,41.4156547 40.8158929,39.4536905 42.4379167,37.117381 C44.001131,34.860119 45.1039286,32.3503571 45.7091667,29.6641071 C46.1623214,27.6505357 46.3202381,25.6097619 46.1795238,23.577381 L44.7254167,24.4939881 Z M18.781131,15.243631 C20.485,14.1680357 22.3593453,13.5941667 24.2410714,13.4795238 L26.4869048,12.0595833 C23.5195238,11.7096429 20.5480357,12.3780953 17.9838095,13.9973214 C15.4266071,15.6149405 13.5520833,18.0172619 12.6013095,20.8453571 L14.8457738,19.4256548 C15.7579762,17.7675596 17.0789286,16.3220238 18.781131,15.243631 Z M31.1595238,34.7697619 C29.4556548,35.8483929 27.5827381,36.4220238 25.7010119,36.5366667 L23.4564881,37.9566071 C26.4225,38.3065476 29.392619,37.6366667 31.9582143,36.0174405 C34.5154167,34.40125 36.3899405,31.9975 37.3392857,29.1694048 L35.0961905,30.5921429 C34.1841071,32.2427977 32.8617857,33.6941667 31.1595238,34.7697619 Z" id="形状" fill="#00BF8A" fill-rule="nonzero"></path>
<text id="已完成" transform="translate(25, 24.5) rotate(-32) translate(-25, -24.5)" font-family="STSongti-SC-Black, Songti SC" font-size="12" font-weight="700" fill="#00BF8A">
<tspan x="7" y="29">已完成</tspan>
</text>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<template>
<div class="search-item">
<div class="item-label">{{ label }}</div>
<div class="item-content">
<el-select v-model.trim="main_game_id" filterable remote clearable :style="{ 'width': width || '' }"
reserve-keyword placeholder="请输入主游戏名" :remote-method="remoteMethod" :loading="loading" :disabled='disabled'
@change="returnSelectResult" @focus="gameNameList = optionsList">
<el-option v-for="item in gameNameList" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</div>
</div>
</template>
<script>
import { selectSearch } from '@/api/game'
import { searchcondition } from '@/api/pigeon'
export default {
// gameType:存在的时候取信鸽的游戏列表接口 gameDefaultList 编辑的时候 如果没有当前的游戏 id 主动加上去
props: ['defaultValue', 'width', 'label', 'disabled','gameType','gameDefaultList','isResize'],
data() {
return {
loading: false,
main_game_id: '',
gameNameList: [],
optionsList: []
}
},
watch: {
defaultValue(newVal) {
if (newVal) {
this.gameType?this.main_game_id = newVal:this.main_game_id = Number(newVal)
} else {
return ''
}
},
isResize(newVal, oldVal) {
if (newVal) {
this.main_game_id = ''
this.$emit('result', this.main_game_id, '')
}
},
},
mounted() {
this.defaultValue && this.gameType ? this.main_game_id = Number(this.defaultValue) : this.main_game_id = this.defaultValue
this.switchGameList()
},
methods: {
switchGameList() {
if(this.gameType){
this.requestPigeonGameList()
}else{
this.requestGameList()
}
},
requestGameList() {
const data = {
type: 'mainGameList',
value: '',
weixin_blong_id: ''
}
selectSearch(data).then(res => {
this.loading = false
if (res.status_code == 1) {
this.gameNameList = this.optionsList = res.data.data
}
})
},
requestPigeonGameList() {
const data = {
corp_gift_package_main_games:1,
}
searchcondition(data).then(res => {
this.loading = false
if (res.status_code == 1 && res.data.corp_gift_package_main_games?.length > 0) {
this.gameNameList = this.optionsList = res.data.corp_gift_package_main_games
if(this.gameDefaultList.length > 0){
const gameItem = this.gameNameList.find(item=>item.value === this.gameDefaultList[0].value)
if(!gameItem){
this.gameNameList = this.optionsList = this.gameNameList.concat(this.gameDefaultList)
}
}
}
})
},
remoteMethod(query) {
if (query !== '') {
this.gameNameList = this.optionsList.filter(item => {
return item.label.toLowerCase()
.indexOf(query.toLowerCase()) > -1
})
} else {
this.gameNameList = []
}
},
returnSelectResult(value) {
const label = this.gameNameList.find(item => item.value == this.main_game_id)
label ? this.$emit('result', this.main_game_id, label.label) : this.$emit('result', this.main_game_id, '')
}
}
}
</script>
<style lang="scss" scoped>
.newPage {
width: 100%;
height: 100%;
.el-select {
width: 100%;
}
}
</style>
\ No newline at end of file
<template>
<div class="no-content-container">
<div class="no-content-box">
<!-- 自定义 SVG 图标 -->
<!-- <i class=""></i> -->
<!-- 文字内容 -->
<div class="content">
<h3 class="title">{{ title }}</h3>
<p class="description">{{ description }}</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'NoContent',
props: {
// 主标题
title: {
type: String,
default: '暂无数据'
},
// 描述文字
description: {
type: String,
default: '当前没有任何数据,请稍后再试或联系管理员'
},
// 是否显示操作区域
showAction: {
type: Boolean,
default: false
},
// 是否显示刷新按钮
showRefresh: {
type: Boolean,
default: false
},
// 图标颜色主题
iconTheme: {
type: String,
default: 'default', // default, primary, success, warning, danger
validator: (value) => ['default', 'primary', 'success', 'warning', 'danger'].includes(value)
}
},
methods: {
handleRefresh() {
this.$emit('refresh');
}
}
}
</script>
<style lang="scss" scoped>
.no-content-container {
display: flex;
align-items: center;
justify-content: center;
min-height: 300px;
padding: 40px 20px;
background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
border-radius: 12px;
position: relative;
overflow: hidden;
// 背景装饰
&::before {
content: '';
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(0, 191, 138, 0.05) 0%, transparent 50%);
pointer-events: none;
}
}
.no-content-box {
text-align: center;
max-width: 400px;
position: relative;
z-index: 1;
}
.icon-wrapper {
position: relative;
margin-bottom: 32px;
display: inline-block;
}
.no-data-icon {
width: 120px;
height: 120px;
color: #6c757d;
filter: drop-shadow(0 8px 16px rgba(0, 0, 0, 0.1));
animation: float 3s ease-in-out infinite;
}
// 图标主题色
.no-content-container[data-theme="primary"] .no-data-icon {
color: #00BF8A;
}
.no-content-container[data-theme="success"] .no-data-icon {
color: #67c23a;
}
.no-content-container[data-theme="warning"] .no-data-icon {
color: #e6a23c;
}
.no-content-container[data-theme="danger"] .no-data-icon {
color: #f56c6c;
}
// 装饰圆点
.decorative-dots {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
pointer-events: none;
}
.dot {
position: absolute;
width: 6px;
height: 6px;
background: #00BF8A;
border-radius: 50%;
opacity: 0.6;
}
.dot-1 {
top: 20%;
left: 15%;
animation: pulse 2s ease-in-out infinite;
}
.dot-2 {
top: 30%;
right: 20%;
animation: pulse 2s ease-in-out infinite 0.5s;
}
.dot-3 {
bottom: 25%;
left: 25%;
animation: pulse 2s ease-in-out infinite 1s;
}
// 文字内容
.content {
.title {
font-size: 24px;
font-weight: 600;
color: #2c3e50;
margin: 0 0 12px 0;
line-height: 1.3;
}
.description {
font-size: 14px;
color: #6c757d;
line-height: 1.6;
margin: 0 0 24px 0;
max-width: 300px;
margin-left: auto;
margin-right: auto;
}
}
.action-area {
margin-top: 32px;
.el-button {
padding: 12px 24px;
border-radius: 6px;
font-weight: 500;
box-shadow: 0 4px 12px rgba(0, 191, 138, 0.3);
transition: all 0.3s ease;
&:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(0, 191, 138, 0.4);
}
i {
margin-right: 6px;
}
}
}
// 动画效果
@keyframes float {
0%, 100% {
transform: translateY(0px);
}
50% {
transform: translateY(-10px);
}
}
@keyframes pulse {
0%, 100% {
opacity: 0.6;
transform: scale(1);
}
50% {
opacity: 1;
transform: scale(1.2);
}
}
// 响应式设计
@media (max-width: 768px) {
.no-content-container {
min-height: 250px;
padding: 30px 15px;
}
.no-data-icon {
width: 80px;
height: 80px;
}
.content {
.title {
font-size: 20px;
}
.description {
font-size: 13px;
}
}
.action-area {
margin-top: 24px;
.el-button {
padding: 10px 20px;
font-size: 14px;
}
}
}
// 暗色主题支持
@media (prefers-color-scheme: dark) {
.no-content-container {
background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%);
&::before {
background: radial-gradient(circle, rgba(0, 191, 138, 0.1) 0%, transparent 50%);
}
}
.content {
.title {
color: #ecf0f1;
}
.description {
color: #bdc3c7;
}
}
}
</style>
\ No newline at end of file
<template>
<div class="newPage rowFlex allCenter">
<el-pagination
:total="Number(pageInfo.total)"
:current-page.sync="pageInfo.page"
:page-size="Number(pageInfo.page_size)"
background
layout="total,prev, pager, next, jumper"
@current-change="handleCurrentChange"
>
</el-pagination>
</div>
</template>
<script type="text/javascript">
export default {
name: 'page',
props: ['pageInfo'],
data() {
return {}
},
mounted() {
},
methods: {
handleCurrentChange(newPage) {
this.pageInfo.page = newPage
this.$emit('requestNextPage', this.pageInfo)
}
}
}
</script>
<style lang="scss" scoped>
.newPage {
width: 100%;
height: 60px;
background: #fff;
border-radius: 0 0 5px 5px;
padding-bottom: 20px;
}
</style>
\ No newline at end of file
<template>
<!-- 简单版的图文编辑器 可以上传 截图上传图片 能实现简单的图文编辑功能 -->
<div class="textEditor">
<div
class="rowFlex columnCenter textEditorTitle"
@click.stop="watchImage"
>
<el-image
class="watchImage"
src="https://wanxiaomeng-1255977238.cos.ap-shanghai.myqcloud.com/mxy/web/eye.png"
> </el-image>
<p class="watchImageText">查看大图</p>
</div>
<!-- 只展示不编辑 -->
<div
v-if="!contenteditable"
:id="domid"
class="qualityRemark noActive"
>
<div v-html="remark"></div>
</div>
<!-- 可以编辑 -->
<div
v-else
:id="domid"
class="qualityRemark"
:class="contenteditable ? 'active' : 'noActive'"
:contenteditable="contenteditable"
@blur.stop="handleBlurEvent"
@input="handleInputEvent"
></div>
<!-- 查看大图 -->
<el-dialog
title="查看大图"
append-to-body
center
:visible.sync="showScoleImage"
>
<div class="showScoleImageContent columnFlex allCenter" v-html="remark"></div>
</el-dialog>
</div>
</template>
<script>
import { base64toFile } from '@/utils/index'
export default {
props: ['remark', 'contenteditable', 'domid'], // remark 原来的图文内容 contenteditable 是否可编辑 domid 编辑器的 DomId resultReamrk 方法吐出最后的编辑好的内容
data() {
return {
srcList: [],
chatMessage: {},
imgList: [],
htmlContent: '',
showScoleImage: false
}
},
mounted() {
this.$nextTick(() => {
this.chatMessage = document.getElementById(`${this.domid}`)
this.remark && this.remark.length > 0 && this.contenteditable ? this.chatMessage.innerHTML = this.remark : ''
})
},
methods: {
handleBlurEvent() {
// this.handleImage()
},
handleInputEvent() {
this.handleImage()
},
async watchImage() {
if (this.remark.trim().length > 0) {
this.chatMessage.innerHTML = this.remark
this.srcList = []
const imgList = this.chatMessage.querySelectorAll('img')
if (imgList && imgList.length > 0) {
for (let index = 0; index < imgList.length; index++) {
this.srcList.push(imgList[index].src)
}
}
this.showScoleImage = true
} else {
this.$message.warning('内容为空')
}
},
async handleImage() {
this.srcList = []
const imgListElement = this.chatMessage.querySelectorAll('img')
let imgList = []
if (imgListElement.length > 0) {
for (let i = 0; i < imgListElement.length; i++) {
const nodeItem = imgListElement[i]
if (nodeItem.src.indexOf('data:image') !== -1) {
imgList.push(nodeItem)
}
}
} else {
imgList = []
}
if (imgList && imgList.length > 0) {
for (let index = 0; index < imgList.length; index++) {
if (imgList[index].src.indexOf('http:') !== -1) {
this.srcList.push(imgList[index].src)
} else {
const img = base64toFile(imgList[index].src)
const uploadConfig = {
dir: '/company_wx/service/avatars/'
}
this.srcList.push(imgList[index].src)
const result = await this.uploading(img, uploadConfig)
imgList[index].src = result.data
}
}
this.$emit('resultReamrk', this.chatMessage.innerHTML)
this.$emit('update:remark', this.chatMessage.innerHTML)
} else {
this.$emit('resultReamrk', this.chatMessage.innerHTML)
this.$emit('update:remark', this.chatMessage.innerHTML)
}
}
}
}
</script>
<style lang="scss" scoped>
.watchImage {
width: 20px;
height: 20px;
margin-right: 5px;
cursor: pointer;
}
.textEditorTitle{
width: 100px;
}
.watchImageText{
color: #00bf8a;
cursor: pointer;
}
.noActive {
background: #f5f7fa;
color: #c0c4cc;
}
.active {
background: #fff;
color: #333;
}
.showScoleImageContent{
width: 100%;
line-height: 16px;
margin-top: 30px;
img{
max-width: 80%;
}
}
</style>
<style>
.qualityRemark {
width: 100%;
height: 150px;
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 10px;
overflow: auto;
line-height: 20px;
}
.qualityRemark img {
width: 80px !important;
height: auto !important;
margin-right: 5px;
margin-top:10px;
margin-right: 10px;
}
.showScoleImageContent{
width: 100%;
overflow: auto;
line-height: 16px;
}
.showScoleImageContent img{
max-width: 100%;
margin-bottom: 20px;
}
</style>
\ No newline at end of file
# 企业微信客户端侧边栏应用开发
基于企业微信客户端 开发侧边栏功能 企业微信的文档 [企业微信文档]([链接地址](https://developer.work.weixin.qq.com/document/path/94352) ) 首先需要调用微信的 授权接口 进行授权拿到 用户的 code 等信息
以下是初始化页面需要完成的功能
# 需求流程
## 1.企微授权
每次进去页面都需要去进行企微授权 授权成功后 通过接口 获取 当前客服号的 userid 和 企业微信签名的一些信息 去校验签名 然后调用 企业微信的 js sdk 来获取 企业微信的一些api 然后再进行 侧边栏的开发
主要页面的功能在 `@/App.vue` 中 这个逻辑只是暂时写在 App.vue 中 需要你帮我重构一下 重新规划页面逻辑处理
`@/App.vue` 中 的方法和功能如下
- `Authorize` 方法: 如果当前页面没有授权过 则重定向到企业微信的授权页面
- `handleAuthCode` 方法: 每次进入页面都要重新调用这个方法 先查看 当前 url 中 是否有 code 参数 如果有 code 参数 则调用 `getAuthUser` 方法 去获取 用户的信息 然后再进行 企业微信的签名校验 然后再调用 企业微信的 js sdk 来获取 企业微信的一些api 然后再进行 侧边栏的开发
- `getAuthUser` 方法:通过 code 获取当前登录企业微信的用户信息 userid 这个userid 要储存在 cookie 中 过期时间 为 7 天
- `getSignature` 方法: 通过接口获取 企业微信的签名信息 然后调用 企业微信的 js sdk 来获取 企业微信的一些api 然后再进行 侧边栏的开发 这个接口的调用应该在 钉钉授权成功以后 调用 如果没有钉钉授权成功 则不调用 说明使用人 没有登录 不需要调用企微微信的一些功能
- `register`方法: 钉钉登录成功以后 回调到当前页面地址 需要 用之前获取的签名信息 去校验 企业签名和应用签名 通过后就可以使用 企业微信的 js sdk 来获取一些 api 方法
## 2. 在企业微信jssdk 初始化完成后 钉钉扫码界面的开发
### 2.1 钉钉扫码界面的开发
进入侧边栏页面需要钉钉扫码登录 所以需要先进入钉钉扫码登录页面 所有的页面都需要先登录 扫码登录页面是 `@/views/ddLogin.vue` 这个页面的逻辑如下
- `initOrganization` 方法: 获取当前的组织架构列表 可以通过 选择组织架构来决定获取
- `handleLogin` 方法: 通过钉钉的扫码登录 扫码成功后钉钉会重定向一个后端地址 会携带钉钉的 code 参数 后端获取到 code 参数 后 会重定向当前的前端页面 url 上 会携带 token 参数 然后把 token 存在 cookie 中 过期时间 为 7 天
- 每次刷新重新进入页面的时候 都要检查一下 cookie 中是否有 token 如果有 说明已经登录过了 不需要重新钉钉扫码登录 如果没有 则需要重新钉钉扫码登录
### 2.2 钉钉扫码登录成功以后
1. 钉钉扫码登录成功以后 才可以查看其他的页面 如果钉钉没有扫码登录 则无法查看其他的页面 页面只展示钉钉扫码登录的页面
2. 钉钉扫码登录成功以后 会把 token 存在 cookie 中 过期时间 为 7 天
3. 登录成功以后会有一个退出的按钮 点击退出按钮 会把 cookie 中的 token 删除 清除 token 然后跳转到钉钉扫码登录页面 重新钉钉扫码登录
4. 需要把钉钉扫码成功后的 token 每次请求接口的时候 放在请求头中 每个接口需要放上 token 才能获取到数据 后端需要校验 请你帮我完成这部分工作
### 3.cookie 中需要缓存 通过企业微信获取的 userid 和 钉钉扫码成功后 获取的 token
### 4.关于回调地址
1. 本项目中会经历两次页面回调 一次是企微的授权验证回调 一次是 钉钉登录成功的回调 回调页面必须在首页完成 因为这个回调地址已经配置过了 不能更改 至于写在 app.vue 中还是 vuex 中 或者 另外的 js 中 你自己决定 只需要保证 在用户登录的时候 能够拿到 token 就可以了
2. 回调的时候 引入
```js
import {getParams} from '@/utils/index.js'
```
获取 url 后面的参数 储存在 vuex 中
本项目中会经历两次页面回调 一次是企微的授权验证回调 一次是 钉钉登录成功的回调 回调页面必须在首页完成 因为这个回调地址已经配置过了 钉钉回调成功后 页面 url 上会带一个 type=ding 的参数 需要根据这个参数来判断 是钉钉回调还是企微回调 如果是钉钉的回调 表明 微信授权的逻辑已经完成了 可以直接去 首页了
\ No newline at end of file
# 企业微信开发接入文档
# 企业微信开发接入文档
## 一、前期准备
### 1.1 开发者平台配置
1. 登录 企业微信开发者平台
2. 创建应用并获取以下信息:
- corpid(企业ID)
- agentid(应用ID)
- Secret(应用密钥)
3. 配置可信域名
4. 开通相关接口权限
## 二、项目配置
在配置签名的时候 后端签名时候的 url 应该是 重定向回来的那个 url 带 code 和 state 参数 而不是 在企微后台设置的那个 url 就是 后端签名的 url 要和 授权的时候 当前的那个页面的 url 一样 但是不包含 # 和 # 后面的url 内容
应该是 https://companywx.jianshuwenhua.com/company_app/index.html?code=-aXitj4Tt8UNLq_evPRgECSVS6zHpP6-r3ofYzk0BeM&state=STATE 带上参数去签名
### 2.1 引入企业微信 JS-SDK
在项目的 index.html 中添加:
老版本引入 方式:
```
<script src="https://res.wx.qq.com/open/js/
jweixin-1.2.0.js"></script>
```
新版本引入方法
```
<script src="https://wwcdn.weixin.qq.com/node/open/js/wecom-jssdk-2.0.2.js"></script>
```
### 2.2 基础配置示例
查看文档 [文档](https://developer.work.weixin.qq.com/document/path/94325)
以下是老版本的配置内容
先配置 企业应用 id 签名 然后 在配置 应用id 签名 必须先配置企业 id的签名人 然后再配置应用id的签名
```
wx.config({
  beta: true, // 必须这么写,否则wx.invoke调用形式
  的jsapi会有问题
  debug: false, // 开启调试模式
  appId: corp_id, // 必填,企业微信的corpID
  timestamp: time, // 必填,生成签名的时间戳
  nonceStr: nonceStr, // 必填,生成签名的随机串
  signature: signature, // 必填,签名
  jsApiList: ["getContext", 
  "getCurExternalContact"] // 必填,需要使用的JS
  接口列表
});
```
### 2.3 应用配置示例
```
wx.agentConfig({
  corpid: corp_id, // 必填,企业微信的corpid
  agentid: agentid, // 必填,企业微信的应用id
  timestamp: time, // 必填,生成签名的时间戳
  nonceStr: nonceStr, // 必填,生成签名的随机串
  signature: signature, // 必填,签名
  jsApiList: ["getContext", 
  "getCurExternalContact"], // 必填,需要使用的JS
  接口列表
  success: function(res) {
    // 回调
  },
  fail: function(res) {
    if (res.errMsg.indexOf('function not 
    exist') > -1) {
      alert('版本过低请升级')
    }
  }
});
```
新版本的配置
同时配置企业签名 和 应用签名 配置完成调用 wx的方法即可
```
ww.register({
corpId: that.userInfo.corp_id, // 必填,当前用户企业所属企业ID
agentId: 1000013, // 必填,当前应用的AgentID
jsApiList: jsApiList, // 必填,需要使用的JSAPI列表
getConfigSignature:function(){ // // 必填,根据url生成企业签名的回调函数
return new Promise((resolve, reject) => {
resolve({
nonceStr: that.userInfo.nonceStr,
timestamp: that.userInfo.time,
signature: that.userInfo.corp_signature,
})
})
},
getAgentConfigSignature:function(){ // 必填,根据url生成应用签名的回调函数
return new Promise((resolve, reject) => {
resolve({
nonceStr: that.userInfo.nonceStr,
timestamp: that.userInfo.time,
signature: that.userInfo.agent_signature,
})
})
}
})
```
## 三、常用接口
### 3.1 获取外部联系人信息
```
wx.invoke('getCurExternalContact', {
}, function(res) {
  if (res.err_msg == 
  "getCurExternalContact:ok") {
    var userId = res.userId; //返回当前外部联系人
    userId
  } else {
    //错误处理
  }
});
```
## 四、环境配置
### 4.1 开发环境配置
```
// .env.development
VUE_APP_CORPID=your_development_corpid
VUE_APP_AGENTID=your_development_agentid
```
### 4.2 生产环境配置
```
// .env.production
VUE_APP_CORPID=your_production_corpid
VUE_APP_AGENTID=your_production_agentid
```
## 六、常见问题
### 6.1 接口调用失败
- 检查域名配置
- 验证 corpid 和 agentid 正确性
- 确认环境是否支持 HTTPS
- 检查签名是否正确
- 后端授权时的 url 是否和当前授权页面的 url 是否一直 包含参数和是否一直 但是不包含 # 和 # 后面的url 内容
# 1.后端签名时候的 url 应该是 重定向回来的那个 url 带 code 和 state 参数 而不是 在企微后台设置的那个 url
应该是 https://companywx.jianshuwenhua.com/company_app/index.html?code=-aXitj4Tt8UNLq_evPRgECSVS6zHpP6-r3ofYzk0BeM&state=STATE 带上参数去签名
# 1.掌权扫码登录的时候需要在 钉钉应用后台添加授权跳转地址 由于每个主体的域名不一样 所以所有的主体的地址都需要添加 新增加的主体也需要在钉钉应用后台添加
# 2.这里用 hash 模式 因为本项目是在企微 服务器下的一个二级页面 如果用 history 模式 需要修改 nginx 配置 在 nginx 配置中 需要添加
```
location /company_app/ {
root /usr/share/nginx/html; # 注意这里是html,不是html/company_app
try_files $uri $uri/ /company_app/index.html;
}
```
这个配置是 如果访问的 url 是 /company_app/ 那么就访问 /company_app/index.html 这个文件 用 hash 模式不用修改 nginx 配置 直接用就行了
如果用 history 需要在 vue.config.js 中配置 historyApiFallback: true, 解决本地开发404问题
# 3. 在域名的二级目录下 重新上传一个 带路由的项目时 需要在 router.js 中设置 base 目录 本地不需要设置
```
base:process.env.NODE_ENV === 'production' ? '/company_app' : '/',
```
# 4.打包到测试环境的时候 用 npm run build:stage 打包到正式环境的时候 用 npm run build:prod
因为企微侧边栏是跟当前登录的主体的域名下的 html 文件 主体域名下 没有测试和正式的域名 只有一个域名
例如 简书 的域名 https://companywx.jianshuwenhua.com/ 不管在 正式环境还是在测试环境的掌微中 都是跳转这个域名 所以 在配置钉钉回调的时候 回调地址有测试和正式的域名 但是 在企微侧边栏打开的页面只有一个 域名 companywx.jianshuwenhua.com 所以在打包到测试环境的时候
用 npm run build:stage 打包到正式环境的时候 用 npm run build:prod
# 5. 谨记 当打包上线到正式环境的时候 一定要 用npm run build:prod 重新打包一次 要不钉钉扫码登录会有问题 回调地址会有错误
# 6. 只用到企业微信应用的 api 的时候 可以只注册 企业微信应用的签名 当用到 企业的api 的时候 需要注册企业的签名 当用到什么 api 的时候 就用那个的签名 具体看官方文档
\ No newline at end of file
# 钉钉扫码登录接入文档
# 钉钉扫码登录接入文档
## 一、前期准备
### 1.1 开发者平台配置
1. 登录 钉钉开放平台
2. 创建应用并获取以下信息:
- AppID(应用ID)
- AppSecret(应用密钥)
3. 配置应用回调域名
4. 开通"扫码登录"功能权限
## 二、项目配置
### 2.1 引入钉钉 SDK
在项目的 index.html 中添加:
```
<script src="https://g.alicdn.com/dingding/
dingtalk-jsapi/2.13.42/dingtalk.open.js"></
script>
```
### 2.2 创建登录组件
```
<template>
  <div class="DDlogin">
    <h2>钉钉扫码登录</h2>
    <div id="login_container"></div>
  </div>
</template>
<script>
export default {
  name: "DDLogin",
  data() {
    return {
      appid: process.env.
      VUE_APP_DINGTALK_APPID,
      dingRedirect_uri: encodeURIComponent
      (window.location.origin + '/login'),
      dingCodeConfig: {
        id: "login_container",
        style: "border:none;
        background-color:#FFFFFF;",
        width: "400",
        height: "400",
      }
    }
  },
  methods: {
    initDingLogin() {
      window.DDLogin(this.getDingCodeConfig);
    },
    addDingListener() {
      const handleMessage = (event) => {
        if (event.origin === "https://login.
        dingtalk.com") {
          this.handleLoginTmpCode(event.data);
        }
      };
      window.addEventListener("message", 
      handleMessage, false);
    }
  }
}
</script>
```
## 三、登录流程
1. 用户访问登录页面
2. 初始化钉钉扫码组件
3. 用户使用钉钉APP扫描二维码
4. 获取临时授权码(loginTmpCode)
5. 重定向到回调地址并携带 code
6. 后端验证 code 并返回登录态
## 四、环境配置
### 4.1 开发环境配置
```
// .env.development
VUE_APP_DINGTALK_APPID=your_development_appid
VUE_APP_REDIRECT_URI=http://localhost:8080/
login
```
### 4.2 生产环境配置
```
// .env.production
VUE_APP_DINGTALK_APPID=your_production_appid
VUE_APP_REDIRECT_URI=https://your-domain.com/
login
```
## 五、注意事项
### 5.1 安全性
1. AppSecret 禁止在前端暴露
2. 必须使用 HTTPS 协议
3. 注意防范 CSRF 攻击
### 5.2 开发建议
1. 建议本地开发使用 HTTPS
2. 区分开发和生产环境配置
3. 做好错误处理和异常提示
## 六、常见问题
### 6.1 扫码无法回调
- 检查回调域名配置
- 验证 AppID 正确性
- 确认环境是否支持 HTTPS
### 6.2 登录失败
- 检查网络连接
- 验证应用配置
- 查看控制台错误信息
## 七、上线检查清单
- 更新正式环境 AppID
- 配置正确的回调域名
- 确认 HTTPS 证书有效
- 测试完整登录流程
- 验证错误处理机制
- 检查日志记录
## 八、参考资料
- 钉钉开放平台文档
- 扫码登录接入指南
\ No newline at end of file
...@@ -2,11 +2,42 @@ import Vue from 'vue' ...@@ -2,11 +2,42 @@ import Vue from 'vue'
import App from './App.vue' import App from './App.vue'
import router from './router' import router from './router'
import store from './store' import store from './store'
// import '@/styles/index.scss' // global css // import ElementUI from 'element-ui';
Vue.config.productionTip = false import Cookies from 'js-cookie';
import _ from 'lodash';
import 'lib-flexible/flexible.js'
// Vue.use(ElementUI);
import '@/styles/element-theme-colors.css';
import '@/styles/index.scss';
import moment from 'moment'
import VConsole from 'vconsole';
import 'bi-element-ui/lib/bi-element-ui.css'
import Element from 'bi-eleme'
import 'bi-eleme/lib/theme-chalk/index.css'
import BiElementUi from 'bi-element-ui'
import 'bi-element-ui/lib/bi-element-ui.css'
import uploading from '@/utils/cos-upload'
if(process.env.NODE_ENV !== 'production'){
new VConsole();
}
Vue.use(uploading)
Vue.use(BiElementUi, {
dev: process.env.NODE_ENV !== 'production',
env: process.env.NODE_ENV,
system: null
})
Vue.use(Element, {
size: Cookies.get('size') || 'small' // set element-ui default size
// locale: enLang, // 如果使用中文,无需设置,请删除
})
new Vue({ new Vue({
router, router,
store, store,
render: h => h(App) render: h => h(App)
}).$mount('#app') }).$mount('#app')
Vue.config.productionTip = false
Vue.prototype.$cookies = Cookies;
Vue.prototype.$lodash = _;
Vue.prototype.$moment = moment;
import { debounce } from '@/utils'
import { mapState } from 'vuex'
export default {
watch: {
accountSelect: {
handler:debounce(function(newVal, oldVal) {
console.log(12313,'出发了')
if (newVal && newVal !== "" && newVal !== oldVal) {
this.memberChange()
}
},300)
}
},
computed: {
...mapState('game', ['accountSelect'])
},
}
\ No newline at end of file
import Vue from 'vue' import Vue from 'vue'
import VueRouter from 'vue-router' import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue' import userInfo from '../views/userInfo/userInfo.vue'
import {getAuthUser} from '@/api/user' import quickReply from '../views/quickReply.vue'
import giftRecord from '../views/giftRecord.vue'
import applyRecord from '../views/applyRecord.vue'
import quickSend from '../views/quickSend.vue'
import addressBook from '../views/addressBook.vue'
import Cookies from 'js-cookie'
import store from '@/store'
Vue.use(VueRouter) Vue.use(VueRouter)
function Authorize() { import { getParams } from '@/utils/index'
// 先获取企微配置信息
let originUrl = location.href; originUrl;
let redirectUrl = originUrl.split('?')[0];
let returnUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=wweaefe716636df3d1&redirect_uri=${encodeURIComponent(redirectUrl)}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect`
window.location.href = returnUrl;
}
// 通过oAuth2授权获取当前用户userId
function getWxUserInfo(to, from, next, authCode,corp_id) {
getAuthUser({code:authCode,corp_id:'wweaefe716636df3d1'}).then((res) => {
let { code, data, message } = res || {};
if (code === 200) {
let { userId } = data || {};
if (userId) {
localStorage.setItem('userId', userId);
next();
} else {
Authorize(to)
}
} else {
console.log(message);
// PC端侧边栏tab页面切换后再切回来, 页面地址还是上次重定向后的带code的,此时code已经消费过一次,再调接口获取用户信息会失败, 所以加上重新授权的逻辑
Authorize(to)
}
}).catch(() => {
Authorize(to)
})
}
const routes = [ const routes = [
{ {
path: '/', path: '/',
name: 'home', redirect: '/userInfo'
component: HomeView
}, },
{ {
path: '/about', path: '/index.html',
name: 'about', redirect: '/userInfo'
component: () => import('../views/AboutView.vue') },
} {
path: '/userInfo',
name: 'userInfo',
component: userInfo
},
{
path: '/quickReply',
name: 'quickReply',
component: quickReply
},
{
path: '/giftRecord',
name: 'giftRecord',
component: giftRecord
},
{
path: '/applyRecord',
name: 'applyRecord',
component: applyRecord
},
{
path: '/quickSend',
name: 'quickSend',
component: quickSend
},
{
path: '/addressBook',
name: 'addressBook',
component: addressBook
},
{
path: '/login',
name: 'login',
component: () => import('../views/login.vue')
},
{
path: '/testWx',
name: 'testWx',
component: () => import('../views/testWx.vue')
},
] ]
const router = new VueRouter({ const router = new VueRouter({
mode: 'hash', /* 这里用 hash 模式 因为本项目是在企微 服务器下的一个二级页面 如果用 history 模式 需要修改 nginx 配置 在 nginx 配置中 需要添加 location /company_app/ {
base: process.env.BASE_URL, root /usr/share/nginx/html; # 注意这里是html,不是html/company_app
try_files $uri $uri/ /company_app/index.html;
}
这个配置是 如果访问的 url 是 /company_app/ 那么就访问 /company_app/index.html 这个文件
用 hash 模式不用修改 nginx 配置 直接用就行了
如果用 history 需要在 vue.config.js 中配置 historyApiFallback: true, 解决404问题
*/
mode: 'history',
base:process.env.NODE_ENV === 'development' ? '/' : '/company_app',
routes routes
}) })
// router/index.js
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
// 判断是否是微信浏览器打开 // 需要登录态的页面
let ua = navigator.userAgent.toLowerCase(); const needAuth = !['/login'].includes(to.path)
let isWeixin = ua.indexOf('micromessenger') != -1; // 检查登录信息
if (!isWeixin) { const wecomUserId = Cookies.get('userid')
const cser_id = Cookies.get('cser_id')
const token = Cookies.get('token')
const urlParams = getParams();
// 本地测试数据
if(Cookies.get('external_userid')){
store.state.user.external_userid = Cookies.get('external_userid')
}
if (needAuth) {
if (wecomUserId && token && store.state.user.external_userid) {
// 登录信息齐全,允许进入
next() next()
return } else {
// 缺少登录信息,跳转到登录页
// 跳转到 login 的时候带上当前 url 的参数
next({
path: '/login',
query: urlParams
})
// next()
} }
// 企微环境获取当前用户userId和外部客户externalUserId
let code = to.query.code || '';
let corp_id = to.query.corp_id || '';
if (code) {
// 有code说明是授权过的,重定向地址, 调接口获取当前用户信息
getWxUserInfo(to, from, next, code,corp_id);
} else { } else {
// 获取授权 // 登录页、回调页等不需要校验
Authorize(to); next()
} }
}) })
export default router export default router
import Vue from 'vue' import Vue from 'vue'
import Vuex from 'vuex' import Vuex from 'vuex'
import user from './modules/user'
import game from './modules/game'
Vue.use(Vuex) Vue.use(Vuex)
export default new Vuex.Store({ export default new Vuex.Store({
...@@ -13,5 +14,7 @@ export default new Vuex.Store({ ...@@ -13,5 +14,7 @@ export default new Vuex.Store({
actions: { actions: {
}, },
modules: { modules: {
user,
game
} }
}) })
// 和游戏相关的逻辑处理
// 管理公共的store
import { zyouBindMember } from '@/api/works'
const state = {
accountSelect: '', // 当前选中的用户的member_id
bindGameUserList: [], // 用户绑定的游戏角色
changeSelectWindow: false, // 切换客服窗口的时候 下发通知
gameUserInfo:{},
chatUserInfo: {}, // 当前选中的用户的详情
}
const mutations = {
set_accountSelect(state, data) {
state.accountSelect = data
},
set_bindGameUserList(state, data) {
state.bindGameUserList = data
},
set_chatUserInfo(state, data) {
state.chatUserInfo = data
},
set_gameUserInfo(state, data) {
state.gameUserInfo = data
}
}
const actions = {
// 游戏绑定用户
gameBindUser({ dispatch, commit }, data) {
return new Promise((resolve, reject) => {
zyouBindMember(data).then(async (res) => {
if (res.status_code == 1) {
res.data.data.map((item) => {
item.member_id = item.member_id + ''
})
if (res.data.data && res.data.data.length > 0) {
res.data.data.map((item) => {
item.label = item.username
item.value = item.member_id
})
}
commit('set_bindGameUserList', res.data.data)
resolve(res.data.data)
}
})
})
},
}
export default {
namespaced: true,
state,
mutations,
actions
}
import Cookies from 'js-cookie'
import { companyviewConfig } from '@/api/user'
const state = {
userInfo: {
"userid": "JinDuoXia",
"corp_id": "wweaefe716636df3d1",
"nonceStr": "xL1ZHTEt8d5GrjMG",
"agent_signature": "05a47ef848266c48ff28f52e7749ba8b70adcc14",
"corp_signature": "29e61720786b3c6dac31f1041c70878b4819842e",
"time": 1747726636,
external_userid:''
},
userid:Cookies.get('userid'),
corp_id:'',
external_userid:'',
token:'',
cser_info:{
cser_id:'',
cser_name:''
},
cser_id:'',
cser_name:'',
signData:{
corp_id:'',
agent_signature:'',
corp_signature:'',
time:''
},
weixin_blongs_id_list:[],
external_userid:''
// 六子的 用户id wm5rUgMgAAjqjOcqp8i3lEhFZDQieWug
// 我的 userid JinDuoXia cser_id 4090 corp_id wweaefe716636df3d1 cser_id 4090 token token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJpc3MiOjQwOTAsImlhdCI6MTc0NzgxMjMxMiwiZXhwIjoxNzQ4NDE3MTEyLCJuYmYiOjE3NDc4MTIzMTIsInN1YiI6InRva2Vu6K6k6K-BIiwianRpIjoiMjBkOTY3MDZiYzI1MDdmY2MxOWI2MjU1YTM0YWQ3M2YifQ.yX7E7QHV7x2ubpa8iK3Avy794EiHNCaW2CtB4A4UQWo
}
const mutations = {
set_userInfo(state,userInfo){
state.userInfo = userInfo
},
set_userid(state,userid){
state.userid = userid
},
set_corp_id(state,corp_id){
state.corp_id = corp_id
},
set_external_userid(state,external_userid){
state.external_userid = external_userid
},
set_token(state,token){
state.token = token
},
set_cser_info(state,cser_info){
state.cser_info = cser_info
},
set_signData(state,signData){
state.signData = signData
},
set_cser_id(state,cser_id){
state.cser_id = cser_id
},
set_cser_name(state,cser_name){
state.cser_name = cser_name
},
set_weixin_blongs_id_list(state, data) {
if (data.length === 0) {
state.weixin_blongs_id_list = []
} else {
state.weixin_blongs_id_list = data
}
},
}
const actions = {
async requestCompanyviewConfig({ commit, state }, data) {
const res = await companyviewConfig(data)
let blongsList = []
let returnList = []
if (res.data.weixin_blongs_name && Object.keys(res.data.weixin_blongs_name).length > 0) {
blongsList = res.data.weixin_blongs_name
returnList = Object.keys(blongsList).map(key => ({
label: blongsList[key],
value: key
}))
commit('set_weixin_blongs_id_list', returnList)
}
},
}
export default {
namespaced: true,
state,
mutations,
actions
}
\ No newline at end of file
/* ================================
Element UI 自定义主题颜色配置文件
主题色:#00BF8A (翠绿色)
================================ */
/* 主色调配置 */
:root {
/* 主要品牌色 - 翠绿色主题 */
--el-color-primary: #00BF8A !important; /* 主色:翠绿色,用于按钮、链接等主要交互元素 */
--el-color-primary-light-1: #1ac794 !important; /* 主色浅1度:鼠标悬停效果 */
--el-color-primary-light-2: #33cf9e !important; /* 主色浅2度 */
--el-color-primary-light-3: #4dd7a8 !important; /* 主色浅3度:禁用状态 */
--el-color-primary-light-5: #80e3c0 !important; /* 主色浅5度:背景高亮 */
--el-color-primary-light-7: #b3efd7 !important; /* 主色浅7度:背景色 */
--el-color-primary-light-8: #ccf4e3 !important; /* 主色浅8度:表格条纹 */
--el-color-primary-light-9: #e6faef !important; /* 主色浅9度:页面背景 */
--el-color-primary-dark-2: #009972 !important; /* 主色深2度:按钮按下效果 */
/* 功能色配置 */
--el-color-success: #67c23a !important; /* 成功色:绿色,成功提示、通过状态 */
--el-color-success-light-3: #95d475 !important; /* 成功色浅3度 */
--el-color-success-light-5: #b3e19d !important; /* 成功色浅5度 */
--el-color-success-light-7: #d1edc4 !important; /* 成功色浅7度 */
--el-color-success-light-8: #e1f3d8 !important; /* 成功色浅8度 */
--el-color-success-light-9: #f0f9eb !important; /* 成功色浅9度 */
--el-color-success-dark-2: #529b2e !important; /* 成功色深2度 */
--el-color-warning: #e6a23c !important; /* 警告色:橙色,警告提示、需注意状态 */
--el-color-warning-light-3: #eebe77 !important; /* 警告色浅3度 */
--el-color-warning-light-5: #f3d19e !important; /* 警告色浅5度 */
--el-color-warning-light-7: #f8e3c5 !important; /* 警告色浅7度 */
--el-color-warning-light-8: #faecd8 !important; /* 警告色浅8度 */
--el-color-warning-light-9: #fdf6ec !important; /* 警告色浅9度 */
--el-color-warning-dark-2: #b88230 !important; /* 警告色深2度 */
--el-color-danger: #f56c6c !important; /* 危险色:红色,错误提示、删除操作 */
--el-color-danger-light-3: #f89898 !important; /* 危险色浅3度 */
--el-color-danger-light-5: #fab6b6 !important; /* 危险色浅5度 */
--el-color-danger-light-7: #fcd3d3 !important; /* 危险色浅7度 */
--el-color-danger-light-8: #fde2e2 !important; /* 危险色浅8度 */
--el-color-danger-light-9: #fef0f0 !important; /* 危险色浅9度 */
--el-color-danger-dark-2: #c45656 !important; /* 危险色深2度 */
--el-color-info: #909399 !important; /* 信息色:灰色,次要信息、辅助文本 */
--el-color-info-light-3: #b1b3b8 !important; /* 信息色浅3度 */
--el-color-info-light-5: #c8c9cc !important; /* 信息色浅5度 */
--el-color-info-light-7: #dedfe0 !important; /* 信息色浅7度 */
--el-color-info-light-8: #e9e9eb !important; /* 信息色浅8度 */
--el-color-info-light-9: #f4f4f5 !important; /* 信息色浅9度 */
--el-color-info-dark-2: #73767a !important; /* 信息色深2度 */
/* 文字颜色 */
--el-text-color-primary: #303133; /* 主要文字:最深,用于标题、重要内容 */
--el-text-color-regular: #606266; /* 常规文字:正文内容 */
--el-text-color-secondary: #909399; /* 次要文字:辅助说明 */
--el-text-color-placeholder: #a8abb2; /* 占位文字:输入框提示文字 */
--el-text-color-disabled: #c0c4cc; /* 禁用文字:不可操作状态 */
/* 边框颜色 */
--el-border-color: #dcdfe6; /* 基础边框:默认边框色 */
--el-border-color-light: #e4e7ed; /* 浅色边框:分割线 */
--el-border-color-lighter: #ebeef5; /* 更浅边框:卡片边框 */
--el-border-color-extra-light: #f2f6fc; /* 极浅边框:背景分割 */
--el-border-color-dark: #d4d7de; /* 深色边框:强调边框 */
--el-border-color-darker: #cdd0d6; /* 更深边框:表格边框 */
/* 填充颜色 */
--el-fill-color: #f0f2f5; /* 基础填充:页面背景 */
--el-fill-color-light: #f5f7fa; /* 浅色填充:卡片背景 */
--el-fill-color-lighter: #fafafa; /* 更浅填充:输入框背景 */
--el-fill-color-extra-light: #fafcff; /* 极浅填充:悬停背景 */
--el-fill-color-dark: #ebedf0; /* 深色填充:禁用背景 */
--el-fill-color-darker: #e6e8eb; /* 更深填充:按钮禁用背景 */
--el-fill-color-blank: #ffffff; /* 纯白填充:纸质背景 */
/* 背景颜色 */
--el-bg-color: #ffffff; /* 基础背景:主要背景色 */
--el-bg-color-page: #f2f3f5; /* 页面背景:整体页面背景 */
--el-bg-color-overlay: #ffffff; /* 覆盖背景:弹窗、抽屉背景 */
/* 遮罩颜色 */
--el-overlay-color: rgba(0, 0, 0, 0.8); /* 重度遮罩:模态对话框 */
--el-overlay-color-light: rgba(0, 0, 0, 0.7); /* 中度遮罩:抽屉遮罩 */
--el-overlay-color-lighter: rgba(0, 0, 0, 0.5); /* 轻度遮罩:提示遮罩 */
/* 阴影颜色 */
--el-box-shadow: 0 12px 32px 4px rgba(0, 0, 0, 0.04),
0 8px 20px rgba(0, 0, 0, 0.08); /* 基础投影 */
--el-box-shadow-light: 0 0px 12px rgba(0, 0, 0, 0.12); /* 浅色投影:卡片阴影 */
--el-box-shadow-lighter: 0 0px 6px rgba(0, 0, 0, 0.12); /* 更浅投影:按钮阴影 */
--el-box-shadow-dark: 0 16px 48px 16px rgba(0, 0, 0, 0.08),
0 12px 32px rgba(0, 0, 0, 0.12),
0 8px 16px -8px rgba(0, 0, 0, 0.16); /* 深色投影:弹窗阴影 */
}
/* ================================
层级控制 - 确保重要组件在最顶层
================================ */
/* Message 消息提示 - 设置为最高层级 */
.el-message {
z-index: 99999 !important; /* 最高层级,确保不被任何元素遮挡 */
}
/* ================================
组件样式重写示例 - 翠绿色主题
================================ */
/* 按钮组件颜色调整 */
.el-button--primary {
background-color: #00BF8A !important;
border-color: #00BF8A !important;
color: #ffffff !important;
}
.el-button--primary:hover {
background-color: #1ac794 !important;
border-color: #1ac794 !important;
}
.el-button--primary:active,
.el-button--primary:focus {
background-color: #009972 !important;
border-color: #009972 !important;
}
.el-button--primary.is-disabled {
background-color: #4dd7a8 !important;
border-color: #4dd7a8 !important;
}
/* 成功按钮 */
.el-button--success {
background-color: var(--el-color-success);
border-color: var(--el-color-success);
color: #ffffff;
}
/* 警告按钮 */
.el-button--warning {
background-color: var(--el-color-warning);
border-color: var(--el-color-warning);
color: #ffffff;
}
/* 危险按钮 */
.el-button--danger {
background-color: var(--el-color-danger);
border-color: var(--el-color-danger);
color: #ffffff;
}
/* 信息按钮 */
.el-button--info {
background-color: var(--el-color-info);
border-color: var(--el-color-info);
color: #ffffff;
}
/* 表单组件颜色 - 激活状态使用主题色 */
.el-input__inner:focus {
border-color: #00BF8A !important;
}
.el-textarea__inner:focus {
border-color: #00BF8A !important;
}
.el-select .el-input.is-focus .el-input__inner {
border-color: #00BF8A !important;
}
.el-select-dropdown__item.selected {
color: #00BF8A !important;
}
.el-date-editor.el-input.is-active .el-input__inner {
border-color: #00BF8A !important;
}
/* 复选框和单选框 - 激活状态使用主题色 */
.el-checkbox__input.is-checked .el-checkbox__inner {
background-color: #00BF8A !important;
border-color: #00BF8A !important;
}
.el-checkbox__input.is-indeterminate .el-checkbox__inner {
background-color: #00BF8A !important;
border-color: #00BF8A !important;
}
.el-radio__input.is-checked .el-radio__inner {
border-color: #00BF8A !important;
}
.el-radio__input.is-checked .el-radio__inner::after {
background-color: #00BF8A !important;
}
/* 开关组件 - 激活状态使用主题色 */
.el-switch.is-checked .el-switch__core {
background-color: #00BF8A !important;
}
/* 滑块组件 - 激活状态使用主题色 */
.el-slider__button {
border-color: #00BF8A !important;
}
.el-slider__bar {
background-color: #00BF8A !important;
}
.el-slider__button:hover {
border-color: #00BF8A !important;
}
/* 导航菜单颜色 - 激活状态使用主题色 */
.el-menu-item:hover {
background-color: #e6faef !important;
color: #00BF8A !important;
}
.el-menu-item.is-active {
color: #00BF8A !important;
background-color: #e6faef !important;
}
/* 标签页 - 激活状态使用主题色 */
.el-tabs__active-bar {
background-color: #00BF8A !important;
}
.el-tabs__item.is-active {
color: #00BF8A !important;
}
.el-tabs__nav-wrap.is-scrollable .el-tabs__nav-scroll {
border-bottom: 1px solid #e4e7ed;
}
/* 步骤条 - 激活状态使用主题色 */
.el-steps .el-step__head.is-process {
color: #00BF8A !important;
border-color: #00BF8A !important;
}
.el-steps .el-step__head.is-finish {
color: #00BF8A !important;
border-color: #00BF8A !important;
}
.el-step__icon.is-text {
background-color: #00BF8A !important;
}
/* 消息提示颜色 */
.el-message--success {
background-color: var(--el-color-success-light-9);
border-color: var(--el-color-success-light-8);
}
.el-message--warning {
background-color: var(--el-color-warning-light-9);
border-color: var(--el-color-warning-light-8);
}
.el-message--error {
background-color: var(--el-color-danger-light-9);
border-color: var(--el-color-danger-light-8);
}
.el-message--info {
background-color: var(--el-color-info-light-9);
border-color: var(--el-color-info-light-8);
}
/* 标签颜色 */
.el-tag--primary {
background-color: #e6faef !important;
border-color: #ccf4e3 !important;
color: #00BF8A !important;
}
.el-tag--success {
background-color: var(--el-color-success-light-9);
border-color: var(--el-color-success-light-8);
color: var(--el-color-success);
}
.el-tag--warning {
background-color: var(--el-color-warning-light-9);
border-color: var(--el-color-warning-light-8);
color: var(--el-color-warning);
}
.el-tag--danger {
background-color: var(--el-color-danger-light-9);
border-color: var(--el-color-danger-light-8);
color: var(--el-color-danger);
}
/* 链接组件 - 激活状态使用主题色 */
.el-link--primary {
color: #00BF8A !important;
}
.el-link--primary:hover {
color: #1ac794 !important;
}
.el-link--primary:active {
color: #009972 !important;
}
/* 分页组件 - 激活状态使用主题色 */
.el-pagination .el-pager li.active {
background-color: #00BF8A !important;
color: #ffffff !important;
}
.el-pagination .el-pager li:hover {
color: #00BF8A !important;
}
.el-pagination button:hover {
color: #00BF8A !important;
}
/* 进度条 - 使用主题色 */
.el-progress-bar__inner {
background-color: #00BF8A !important;
}
.el-progress__text {
color: #00BF8A !important;
}
/* 穿梭框 - 激活状态使用主题色 */
.el-transfer-panel__item.is-checked {
background-color: #e6faef !important;
color: #00BF8A !important;
}
.el-transfer-panel__header .el-checkbox__input.is-checked .el-checkbox__inner {
background-color: #00BF8A !important;
border-color: #00BF8A !important;
}
/* ================================
使用说明:
1. 将此文件保存后,在main.js中引入:import './element-theme-colors.css'
2. 或在你的主样式文件中 @import 引入
3. 主题色已设置为 #00BF8A (翠绿色)
4. 所有组件的激活状态都使用了主题色
5. Message组件已设置为最高层级(z-index: 99999)
6. 支持深色模式,可通过媒体查询添加dark主题
================================ */
\ No newline at end of file
// cover some element-ui styles
.el-breadcrumb__inner,
.el-breadcrumb__inner a {
font-weight: 400 !important;
}
.el-upload {
input[type='file'] {
display: none !important;
}
}
.el-upload__input {
display: none;
}
// to fixed https://github.com/ElemeFE/element/issues/2461
.el-dialog {
transform: none;
left: 0;
position: relative;
margin: 0 auto;
}
// refine element ui upload
.upload-container {
.el-upload {
width: 100%;
.el-upload-dragger {
width: 100%;
height: 200px;
}
}
}
// dropdown
.el-dropdown-menu {
a {
display: block;
}
}
// to fix el-date-picker css style
.el-range-separator {
box-sizing: content-box;
}
.el-radio-button:focus {
box-shadow: none !important;
}
.el-drawer__header > span,
.el-tabs__item {
outline: none;
}
.el-drawer__body {
position: relative;
}
.error-message {
z-index: 5000 !important;
}
.el-drawer__header>span,.el-tabs__item{
outline: none;
}
.el-icon-circle-close {
color: #fff;
}
\ No newline at end of file
// 全局函数和变量
$color: #00BF8A; // 全局颜色
@function vw($px) {
@return ($px / 1920) * 100vw;
}
@function vh($px) {
@return ($px / 1080) * 100vw;
}
.flex_x {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
}
.flex_y {
display: flex;
flex-flow: column;
justify-content: space-between;
}
.flex_wrap {
display: flex;
flex-wrap: wrap;
flex-direction: row;
justify-content: space-between;
}
.ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.item-content {
.el-select--small {
.el-tag:first-child {
max-width: 64% !important;
}
}
}
.BiInput_single_clear {
.el-input__suffix {
display: none !important;
}
}
.display_none_dialog {
.el-drawer__body::-webkit-scrollbar {
/*滚动条整体样式*/
width: 0;
background: #fff;
border-radius: 3px;
}
.el-drawer__body::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
width: 0;
border-radius: 3px;
background: rgba(221, 221, 221, 1);
}
}
.radio {
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
}
.el-input__count {
vertical-align: top;
}
.el-range-separator {
margin-right: 10px !important;
}
:root {
--primary-color: #2563eb;
--primary-hover: #1d4ed8;
--bg-color: #f8fafc;
--chat-bg: #ffffff;
--user-msg-bg: #2563eb;
--ai-msg-bg: #f1f5f9;
--border-color: #e2e8f0;
--text-primary: #1e293b;
--text-secondary: #64748b;
}
\ No newline at end of file
@import "./variables.scss";
@import "./mixin.scss";
@import "./transition.scss";
@import "./element-ui.scss";
@import "./sidebar.scss";
@import "./ui.scss";
@import 'uistyle.scss';
@import './reset.scss';
// @tailwind base; // 重设的 css 代码 // @tailwind base; // 重设的 css 代码
// @tailwind components; // @tailwind components;
@tailwind utilities; // @import "./variables.scss";
// @import "./element-variables.scss";
// @import "./index.css";
// @import "./element-theme-colors.css";
body { body {
height: 100%; height: 100%;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
...@@ -18,6 +12,8 @@ body { ...@@ -18,6 +12,8 @@ body {
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB,
Microsoft YaHei, Arial, sans-serif; Microsoft YaHei, Arial, sans-serif;
font-size: 14px; font-size: 14px;
margin: 0 ;
padding: 0;
} }
label { label {
...@@ -412,6 +408,7 @@ li { ...@@ -412,6 +408,7 @@ li {
font-weight: 500; font-weight: 500;
color: rgba(0, 0, 0, 0.85); color: rgba(0, 0, 0, 0.85);
margin-bottom: 20px; margin-bottom: 20px;
padding: 15px;
} }
.el-table__cell { .el-table__cell {
...@@ -582,6 +579,13 @@ li { ...@@ -582,6 +579,13 @@ li {
margin-bottom: 5px; margin-bottom: 5px;
} }
} }
.el-form-item{
margin-bottom: 10px;
.el-input__inner{
height: 32px;
line-height: 32px;
}
}
@mixin clearfix {
&:after {
content: "";
display: table;
clear: both;
}
}
@mixin scrollBar {
&::-webkit-scrollbar-track-piece {
background: #d3dce6;
}
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-thumb {
background: #99a9bf;
border-radius: 20px;
}
}
@mixin relative {
position: relative;
width: 100%;
height: 100%;
}
.success {
background-color: #67c23a;
}
// .info {
// background-color: #909399;
// }
.primary {
background-color: #409eff;
}
.danger {
background-color: #f56c6c;
}
.warning {
background-color: #e6a23c;
}
.content-outer {
.bi-tabs-box {
background-color: #fff;
margin-bottom: 10px;
overflow-y: hidden;
.el-tabs__nav-wrap.is-top::after {
content: none;
}
.el-tabs__active-bar.is-top {
top: 0;
}
.el-tabs__header.is-top {
margin-bottom: 0;
}
.el-tabs__content {
padding: 0;
display: none;
overflow: initial;
}
.el-tabs__item.is-top {
min-width: 100px;
text-align: center;
}
// .el-tabs--border-card {
// border: none;
// box-shadow: none;
// .el-tabs__nav {
// display: flex;
// }
// & > .el-tabs__header {
// border-bottom: none;
// .el-tabs__item {
// margin-top: 0;
// border: none;
// display: block;
// }
// }
// }
}
& > .content-head.container {
padding-bottom: 0 !important;
background-color: white;
}
.content-table {
margin-top: 10px;
background-color: white;
padding: 20px;
.action-box {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
}
.table-table {
padding-bottom: 20px;
}
.pagination-container {
margin-top: 20px;
display: flex;
justify-content: center;
}
}
.drawer-container {
// padding: 20px;
}
}
.bi-column-container {
display: flex;
justify-content: space-between;
.column-container {
margin-left: 20px;
width: 230px;
flex: 0 0 230px;
}
}
.colorStatus {
display: inline-block;
> p {
display: inline;
}
.all {
padding: 2px 8px;
height: 20px;
line-height: 16px;
border-radius: 4px;
font-size: 12px;
font-weight: 400;
color: #3491fa;
border: 1px solid #c3e7fe;
background: #e8f7ff;
}
// 成功
.success {
padding: 2px 8px;
height: 20px;
line-height: 16px;
background: #e1fff0;
border-radius: 4px;
font-size: 12px;
font-weight: 400;
color: #00bf8a;
}
.indeter {
padding: 2px 8px;
height: 20px;
line-height: 16px;
background: #fffae0;
border-radius: 4px;
font-size: 12px;
font-weight: 400;
border-radius: 4px;
border: 1px solid #ffe4ba;
color: #ff7d00;
}
.fail {
padding: 2px 8px;
height: 20px;
line-height: 16px;
background: #ffece8;
border-radius: 4px;
font-size: 12px;
font-weight: 400;
color: #f53f3f;
border: 1px solid #fdcdc5;
}
.normal {
padding: 2px 8px;
height: 20px;
line-height: 16px;
background: #f4f4f4;
border-radius: 4px;
font-size: 12px;
font-weight: 400;
color: #86909c;
}
.dianFail {
display: inline-block;
width: 8px;
height: 8px;
background: #f45454;
border-radius: 5px;
}
.dianLineup {
display: inline-block;
width: 8px;
height: 8px;
background: #c9cdd4;
border-radius: 5px;
}
.dianLoading {
display: inline-block;
width: 8px;
height: 8px;
background: #f45454;
border-radius: 5px;
}
.dianSuccess {
display: inline-block;
width: 8px;
height: 8px;
background: #00bf8a;
border-radius: 5px;
}
.dianWait {
display: inline-block;
width: 8px;
height: 8px;
background: #ff9d02;
border-radius: 5px;
}
.dianNormal {
display: inline-block;
width: 8px;
height: 8px;
background: #c9cdd4;
border-radius: 5px;
}
.dianOk {
display: inline-block;
width: 8px;
height: 8px;
background: #0fc6c2;
border-radius: 5px;
}
.dianKou {
display: inline-block;
width: 8px;
height: 8px;
background: #3491fa;
border-radius: 5px;
}
}
.el-dialog {
.dialog-footer {
position: relative;
}
}
// 弹窗的按钮位置
.dialog-footer {
width: calc(100%);
position: absolute;
bottom: 0px;
right: 0;
padding-top: 20px;
padding-bottom: 20px;
padding-right: 20px;
border-top: 1px solid rgba(0, 0, 0, 0.06);
justify-content: flex-end;
overflow: hidden;
background: #fff;
z-index: 10;
.btn {
width: 84px;
height: 32px;
}
}
.tableheader-popper-editdialog {
.dialog-footer {
padding-top: 0;
padding-right: 0;
}
}
.el-drawer__header {
padding: 0 20px !important;
line-height: 58px;
height: 58px;
// padding-bottom: 0;
margin-bottom: 0;
font-size: 16px;
font-weight: 500;
color: rgba(0, 0, 0, 0.85);
// border: 1px rgba(0, 0, 0, 0.06) solid;
// box-shadow: 0 1px 4px rgb(0 21 41 / 8%);
}
// 带background的title
.baseInfo {
width: 100%;
height: auto;
margin-bottom: 10px;
border: 1px solid #f1f5fd;
background: #fff;
.content{
padding-top: 0!important;
}
.title {
width: 100%;
height: 40px;
background: #f7f8fa;
font-size: 14px;
font-weight: 500;
color: #323335;
padding-left: 10px;
line-height: 40px;
margin-bottom: 20px;
}
}
.drawer-container-title{
width: 100%;
height: auto;
font-weight: 500;
font-size: 16px;
color: #323335;
line-height: 22px;
text-align: left;
border-left: 3px solid #00BF8A;
text-indent: 10px;
font-weight: 500;
line-height: 16px;
margin-bottom: 20px;
}
// 弹窗里面的确定 取消按钮暂时固定选择
.layerBtns {
display: flex;
justify-content: flex-end;
.btn {
width: auto;
height: 32px;
}
.el-button {
font-weight: 500 !important;
}
}
.el-image__inner {
border-radius: 5px;
}
p {
margin: 0;
}
//
.infoText {
color: #86909c;
font-size: 12px;
}
// .el-drawer__body{
// position: relative;
// }
.el-dialog__header {
min-height: 40px;
}
.avatar-uploader .el-upload:hover {
// border:1px dashed #00BF8A !important;
}
// form 里面label换行的时候的样式
.lineHeight {
.el-form-item__label {
line-height: 20px !important;
}
}
// 应用icon样式
.miniappIcon {
width: 30px;
height: 30px;
border-radius: 30px;
margin-right: 10px;
}
.miniappIconText {
position: relative;
top: -10px;
}
.textInfo {
color: rgb(153, 153, 153);
font-size: 12px;
}
.textHidden {
word-break: break-all;
}
.redText {
font-size: 14px;
font-weight: 400;
color: #ff4d4f;
}
//注意样式
.carefulText {
width: 100%;
height: 40px;
background: #fff7e8;
border-radius: 4px;
font-size: 14px;
font-weight: 400;
color: #323335;
padding-left: 10px;
margin-top: 0 !important;
margin-bottom: 10px;
display: flex;
align-items: center;
.icon {
color: #ff7d00 !important;
font-size: 14px;
margin: 0 10px;
}
i {
color: #ff7d00 !important;
font-size: 14px;
}
}
.search-form {
.el-select__tags {
max-width: 200px !important;
}
}
.el-form-item__label {
font-weight: 600;
}
.el-table__header .cell {
color: #323335;
font-weight: 500;
}
.el-tooltip {
max-width: 200px;
}
.tooltipWidth {
max-width: 250px;
line-height: 18px !important;
}
.el-tag {
margin-right: 5px !important;
}
.el-date-range-picker__header {
border: none !important;
}
.el-tabs__header {
margin-bottom: 15px;
}
.el-icon-question {
color: #86909c;
}
.id_color {
font-size: 14px;
color: #86909c;
}
#app {
.main-container {
min-height: 100%;
padding-top: 0px !important;
transition: margin-left .28s;
margin-left: $sideBarWidth;
position: relative;
}
.sidebar-container {
transition: width 0.28s;
width: $sideBarWidth !important;
background-color: $menuBg;
height: 100%;
position: fixed;
font-size: 0px;
top: 0;
bottom: 0;
left: 0;
z-index: 1001;
overflow: hidden;
box-shadow: 0 1px 4px #00152914;
// reset element-ui css
.horizontal-collapse-transition {
transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
}
.scrollbar-wrapper {
overflow-x: hidden !important;
}
.el-scrollbar__bar.is-vertical {
right: 0px;
}
.el-scrollbar {
height: 100%;
}
&.has-logo {
.el-scrollbar {
height: calc(100% - 90px);
}
}
.is-horizontal {
display: none;
}
a {
display: inline-block;
width: 100%;
overflow: hidden;
}
.svg-icon {
margin-right: 16px;
width: 22px;
height: 22px;
background-size: contain;
color: #8893aa;
}
.sub-el-icon {
margin-right: 12px;
margin-left: -2px;
}
.el-menu {
border: none;
height: 100%;
width: 100% !important;
}
// menu hover
.submenu-title-noDropdown,
.el-submenu__title {
&:hover {
background-color: $menuHover !important;
}
}
.is-active > .el-submenu__title,
.is-active > .el-submenu__title svg,
.is-active.submenu-title-noDropdown,
.is-active.submenu-title-noDropdown svg {
color: $subMenuActiveText !important;
}
& .nest-menu .el-submenu>.el-submenu__title,
& .el-submenu .el-menu-item {
min-width: $sideBarWidth !important;
// background-color: $subMenuBg !important;
&:hover {
background-color: $subMenuHover !important;
}
}
}
.hideSidebar {
.sidebar-container {
width: 54px !important;
}
.main-container {
margin-left: 54px;
}
.submenu-title-noDropdown {
padding: 0 !important;
position: relative;
.el-tooltip {
padding: 0 !important;
.svg-icon {
margin-left: 15px;
}
.sub-el-icon {
margin-left: 19px;
}
}
}
.el-submenu {
overflow: hidden;
&>.el-submenu__title {
padding: 0 !important;
.svg-icon {
margin-left: 15px;
}
.sub-el-icon {
margin-left: 19px;
}
.el-submenu__icon-arrow {
display: none;
}
}
}
.el-menu--collapse {
.el-submenu {
&>.el-submenu__title {
&>span {
height: 0;
width: 0;
overflow: hidden;
visibility: hidden;
display: inline-block;
}
}
}
}
}
.el-menu--collapse .el-menu .el-submenu {
min-width: $sideBarWidth !important;
}
// mobile responsive
.mobile {
.main-container {
margin-left: 0px;
}
.sidebar-container {
transition: transform .28s;
width: $sideBarWidth !important;
}
&.hideSidebar {
.sidebar-container {
pointer-events: none;
transition-duration: 0.3s;
transform: translate3d(-$sideBarWidth, 0, 0);
}
}
}
.withoutAnimation {
.main-container,
.sidebar-container {
transition: none;
}
}
}
// when menu collapsed
.el-menu--vertical {
&>.el-menu {
.svg-icon {
margin-right: 16px;
}
.sub-el-icon {
margin-right: 12px;
margin-left: -2px;
}
}
.nest-menu .el-submenu>.el-submenu__title,
.el-menu-item {
&:hover {
// you can use $subMenuHover
background-color: $menuHover !important;
}
}
// the scroll bar appears when the subMenu is too long
>.el-menu--popup {
max-height: 100vh;
overflow-y: auto;
&::-webkit-scrollbar-track-piece {
background: #d3dce6;
}
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-thumb {
background: #99a9bf;
border-radius: 20px;
}
}
}
.el-menu-item{
position: relative;
&::after{
content:' ';
position: absolute;
width: 3px;
height: 0;
right: 0;
top: 0;
transition: .3s;
}
&.is-active::after{
height: 100%
}
}
.el-submenu .el-menu-item{
padding-left: 60px !important;
}
.el-submenu__title{
font-size: 16px !important;
font-weight: 500 !important;
color: #323335 !important;
}
.submenu-title-noDropdown:not(.el-submenu .submenu-title-noDropdown){
font-size: 16px !important;
font-weight: 500 !important;
color: #323335 !important;
}
\ No newline at end of file
// global transition css
/* fade */
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.28s;
}
.fade-enter,
.fade-leave-active {
opacity: 0;
}
/* fade-transform */
.fade-transform-leave-active,
.fade-transform-enter-active {
transition: all .5s;
}
.fade-transform-enter {
opacity: 0;
transform: translateX(-30px);
}
.fade-transform-leave-to {
opacity: 0;
transform: translateX(30px);
}
// rotage-transform
.rotage-transform-leave-active,
.rotage-transform-enter-active {
transition: all 1s;
}
.rotage-transform-enter {
transform: rotate(180deg);
}
.rotage-transform-leave-to {
transform: rotate(0deg);
}
/* breadcrumb transition */
.breadcrumb-enter-active,
.breadcrumb-leave-active {
transition: all .5s;
}
.breadcrumb-enter,
.breadcrumb-leave-active {
opacity: 0;
transform: translateX(20px);
}
.breadcrumb-move {
transition: all .5s;
}
.breadcrumb-leave-active {
position: absolute;
}
$themeColor: #00BF8A;
$sidebarWidthOpen: 190px;
$sidebarWidthClosed: 56px;
$navbarHeight: 50px;
:export {
themeColor: $themeColor;
sidebarWidthOpen: $sidebarWidthOpen;
sidebarWidthClosed: $sidebarWidthClosed;
navbarHeight: $navbarHeight;
}
// @import './ui-variables.scss';
@import './ui-variables.scss';
/* bi-ui-style */
// $appmainWidth
/*
*Font
*默认为font-size: 14px;line-height: 20px;
*/
body {
font-size: 14px;
line-height: 20px;
color: #323335;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
}
#app {
height: 100%;
background-color: #e5e5e5;
.navbar {
height: $navbarHeight;
.navbar-box {
height: $navbarHeight;
line-height: $navbarHeight;
.app-breadcrumb {
padding: 10px 0;
}
}
}
.app-main {
min-height: calc(100vh - #{$navbarHeight});
}
}
.app-main {
.text {
&-12 {
font-size: 12px;
line-height: 18px;
}
&-14 {
font-size: 14px;
line-height: 20px;
}
&-16 {
font-size: 16px;
line-height: 22px;
}
&-24 {
font-size: 16px;
line-height: 34px;
}
}
.container {
padding: 20px;
background: #fff;
border-radius: 4px;
& + .container {
margin-top: 10px;
}
}
}
.search-form {
display: flex;
flex-wrap: wrap;
& + * {
margin-top: 15px !important;
}
.search-item {
min-width: 330px !important;
padding-right: 20px;
padding-bottom: 20px;
margin-bottom: 0;
margin-right: 0;
margin-left: 0;
margin-top: 0;
display: flex;
flex: 0 0 auto;
.item-label,
.select-label {
flex-wrap: 0;
flex-shrink: 0;
padding-right: 10px;
margin-bottom: 0;
margin-right: 0;
margin-left: 0;
margin-top: 0;
text-align: right;
line-height: 16px;
display: flex;
align-items: center;
flex-direction: row-reverse;
max-height: 32px;
overflow: hidden;
}
.select-value {
.el-input__inner {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
}
.item-label {
width: 80px;
}
.select-label {
width: 100px;
margin-right: -1px;
text-align: right;
padding-right: 0;
.is-focus .el-input__inner {
z-index: 1;
}
.el-input__inner {
position: relative;
border-top-right-radius: 0px;
border-bottom-right-radius: 0px;
transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
&:focus {
z-index: 1;
}
}
}
.item-content,
.select-content {
flex-grow: 1;
& > * {
width: 100%;
}
}
.select-content {
height: 32px;
.input-number-range {
position: relative;
border-top-left-radius: 0px;
border-bottom-left-radius: 0px;
&.is-focus {
z-index: 1;
}
}
&:not(.el-select) {
.is-focus .el-input__inner {
z-index: 1;
}
.el-input__inner {
position: relative;
border-top-left-radius: 0px;
border-bottom-left-radius: 0px;
transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
&:focus {
z-index: 1;
}
}
}
&.el-select {
.el-input .el-input__inner {
border-top-left-radius: 0px;
border-bottom-left-radius: 0px;
}
}
}
}
}
.hideSidebar {
.search-form {
@media screen and (max-width: 1103px) {
.search-item {
width: 50%;
// &:nth-last-child(3) ~ .search-item {
// padding-bottom: 0;
// }
}
}
@media screen and (min-width: 1104px) {
.search-item {
width: 33.3%;
// &:nth-last-child(4) ~ .search-item {
// padding-bottom: 0;
// }
}
}
@media screen and (min-width: 1434px) {
.search-item {
width: 25%;
// &:nth-last-child(5) ~ .search-item {
// padding-bottom: 0;
// }
}
}
@media screen and (min-width: 1764px) {
.search-item {
width: 20%;
// &:nth-last-child(6) ~ .search-item {
// padding-bottom: 0;
// }
}
}
}
}
.openSidebar {
.search-form {
@media screen and (max-width: 910px) {
.search-item {
width: 50%;
// &:nth-last-child(3) ~ .search-item {
// padding-bottom: 0;
// }
}
}
@media screen and (min-width: 1240px) {
.search-item {
width: 33.3%;
// &:nth-last-child(4) ~ .search-item {
// padding-bottom: 0;
// }
}
}
@media screen and (min-width: 1570px) {
.search-item {
width: 25%;
// &:nth-last-child(5) ~ .search-item {
// padding-bottom: 0;
// }
}
}
@media screen and (min-width: 1900px) {
.search-item {
width: 20%;
// &:nth-last-child(6) ~ .search-item {
// padding-bottom: 0;
// }
}
}
}
}
/* element-ui */
.el-select,
.el-cascader {
.el-input__inner {
padding-right: 20px;
}
.el-input__suffix {
z-index: 1;
width: 20px;
}
.el-cascader__tags {
width: 210px;
flex-wrap: nowrap;
display: flex;
align-items: center;
}
.el-cascader__search-input {
min-width: 10px;
margin-left: 10px;
}
}
.el-date-editor {
.el-range__close-icon {
width: 15px;
}
}
.el-button + .el-button {
margin-left: 10px;
}
// .el-dialog__wrapper {
// display: flex;
// align-items: center;
// .el-dialog {
// min-width: 480px;
// margin-top: 50px;
// margin-bottom: 50px;
// max-height: calc(100vh - 100px);
// .el-dialog__header {
// padding: 16px 20px;
// line-height: 20px;
// font-size: 16px;
// color: rgba(0, 0, 0, 0.85);
// border-bottom: 1px solid rgba(0, 0, 0, 0.06);
// }
// }
// }
#app .sidebar-container .nest-menu .el-submenu > .el-submenu__title,
#app .sidebar-container .el-submenu .el-menu-item {
// color: #606266;
}
#app .sidebar-container .el-menu .el-menu-item .svg-icon + span {
font-weight: 500;
font-size: 16px;
// color: #606266;
}
#app .sidebar-container .el-menu .el-submenu__title .svg-icon + span {
font-size: 16px;
font-weight: 500;
}
#app .sidebar-container .svg-icon {
color: #8893aa;
}
#app .is-active .svg-icon {
color: #00bf8a;
}
#app .el-table thead th.el-table__cell .cell {
display: inline-block;
}
.el-table--enable-row-hover .el-table__body tr:hover > td.el-table__cell {
// background-color: #fff9f5;
opacity: 1;
}
.el-picker-panel.el-date-range-picker.el-popper.has-sidebar.has-time.my-popper {
z-index: 200000 !important;
}
.input-number-right-aligned .el-input-number__increase,
.input-number-right-aligned .el-input-number__decrease {
display: inline-block;
width: auto;
}
.input-number-right-aligned .el-input {
text-align: left;
}
.input-number-right-aligned .el-input-number__inner {
text-align: left;
}
// .rowFlex .el-input-number .el-input__inner {
// text-align: left !important;
// }
// 框架样式更改 重新规划
#app {
.app-main {
background: #eeeff5;
padding: 0 15px;
.dashboard {
width: calc(100% - 30px);
}
.content-head.container {
border-radius: 4px;
}
// 表格样式
.content-table {
border-radius: 4px;
margin-top: 15px;
}
.el-table {
// 表格里面的选择框
.el-table-column--selection .cell {
padding: 10px 16px !important;
}
.el-table__fixed-right {
background: #fff;
}
}
}
// 面包屑
.app-breadcrumb.el-breadcrumb {
padding: 14px 0;
.no-redirect {
font-size: 14px;
color: #323335;
font-weight: 700;
}
}
.content-head.container {
border-radius: 4px;
}
// 表格样式
.content-table {
border-radius: 4px;
margin-top: 15px;
}
.el-table {
// 表格里面的选择框
.el-table-column--selection .cell {
padding: 10px 16px !important;
}
.el-table__fixed-right {
background: #fff;
}
}
}
// 选择应用
.selectRouter {
.el-input__suffix {
height: 32px;
}
}
.el-tooltip__popper {
max-width: 300px;
}
// .app-main{
// // 图表的icon颜色
// i,.icon{
// color: #86909C;
// }
// }
.tableContent {
color: #323335 !important;
font-weight: 400 !important;
.tableHeader {
background: #f2f3f5;
}
}
.goRight {
width: 28px;
height: 27px;
background: #00bf8a;
border-radius: 14px;
color: #ffffff;
font-size: 16px;
margin: 0 20px;
cursor: pointer;
border-radius: 14px;
i {
color: #ffffff;
font-size: 16px;
margin: 0 20px;
cursor: pointer;
border-radius: 14px;
i {
color: #ffffff;
}
}
}
// 暂无数据
.noContent {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
i {
font-size: 42px;
color: #86909c;
}
.text {
font-size: 14px;
font-weight: 400;
color: #c9cdd4;
margin-top: 5px;
}
}
// 修改 tabs 全局样式
.el-tabs {
.el-tabs__header {
height: 50px;
border-radius: 4px;
}
.el-tabs__nav-scroll {
height: 50px;
}
.el-tabs__item {
height: 50px;
line-height: 50px;
font-size: 16px;
color: #4e5969;
}
.el-tabs__item.is-active{
color: #00bf8a;
}
}
// 表格样式
.content-outer {
.table-table {
padding-bottom: 20px !important;
}
}
.imageIcon {
position: relative;
}
// 统一标签样式
.checkTagsView {
width: 100%;
.tagsItem {
margin-right: 5px;
margin-bottom: 5px;
}
}
// toast 样式
.el-message{
z-index: 999999 !important;
}
// form 表单类型
.el-form-item .el-form-item, .el-form-item .el-form-item.el-form-item--small{
margin-bottom: 16px;
}
// 描述文字样式
.infoTextColor{
color: #86909c;
}
.infoSpan {
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
max-width: 250px;
p {
font-size: 12px;
max-width: 100%;
line-height: 20px;
color: #86909c;
}
span {
color: #ffa81d;
}
}
// tab 样式 .tabs__content 默认 overflow 为 hidden 为 hidden 的时候 表格表头吸顶功能异常 需要 overflow 设置为 initial
.el-tabs__content {
overflow: initial;
}
\ No newline at end of file
...@@ -7,7 +7,11 @@ $green: #30b08f; ...@@ -7,7 +7,11 @@ $green: #30b08f;
$tiffany: #4ab7bd; $tiffany: #4ab7bd;
$yellow: #fec171; $yellow: #fec171;
$panGreen: #30b08f; $panGreen: #30b08f;
$themeColor: #00BF8A;
$sidebarWidthOpen: 190px;
$sidebarWidthClosed: 56px;
$navbarHeight: 50px;
// sidebar // sidebar
$menuText: #606266; $menuText: #606266;
$menuActiveText: #00BF8A; $menuActiveText: #00BF8A;
...@@ -30,6 +34,10 @@ $sideBarWidth: 190px; ...@@ -30,6 +34,10 @@ $sideBarWidth: 190px;
menuBg: $menuBg; menuBg: $menuBg;
menuHover: $menuHover; menuHover: $menuHover;
subMenuBg: $subMenuBg; subMenuBg: $subMenuBg;
themeColor: $themeColor;
sidebarWidthOpen: $sidebarWidthOpen;
sidebarWidthClosed: $sidebarWidthClosed;
navbarHeight: $navbarHeight;
subMenuHover: $subMenuHover; subMenuHover: $subMenuHover;
sideBarWidth: $sideBarWidth; sideBarWidth: $sideBarWidth;
} }
\ No newline at end of file
import Cookies from 'js-cookie' import Cookies from 'js-cookie'
import store from '@/store/index'
const TokenKey = 'authorization' const TokenKey = 'token'
const time = new Date(new Date().getTime() + 10 * 12 * 30 * 24 * 60 * 60 * 1000) const time = new Date(new Date().getTime() + 10 * 12 * 30 * 24 * 60 * 60 * 1000)
export function getToken() { export function getToken() {
return Cookies.get(TokenKey) return Cookies.get(TokenKey) || store.state.user.token
} }
export function setToken(token) { export function setToken(token) {
store.state.user.token = token
return Cookies.set(TokenKey, token, { expires: time }) return Cookies.set(TokenKey, token, { expires: time })
} }
export function removeToken() { export function removeToken() {
store.state.user.token = null
return Cookies.remove(TokenKey) return Cookies.remove(TokenKey)
} }
/*
* @Author: your name
* @Date: 2021-12-30 17:11:51
* @LastEditTime: 2022-01-07 12:49:00
* @LastEditors: Please set LastEditors
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
* @FilePath: \zhangyou_frontend\src\utils\cos-upload.js
*/
import COS from 'cos-js-sdk-v5'
import { randomStr } from '@/utils/randomStr'
// import { getUpload } from '@/api/public'
import { uploadCos } from '@/api/user'
import moment from 'moment'
const configImg = {
dir: '/company_wx/',
bucket: 'companywx-1300623068',
Region: 'ap-nanjing',
file: null,
date: moment().format('YYYYMMDD'),
str: randomStr(),
ext: null
}
// 默认获取
const getOptions = function (params) {
return new Promise(function (reject, resolve) {
uploadCos(params).then((res) => {
if (res.status_code === 1) {
reject(res)
} else {
resolve(res)
}
})
})
}
function uploading(file, config, callbackApi = getOptions) {
const _config = Object.assign({}, configImg, config)
_config.file = file
_config.ext = file.name.slice(file.name.lastIndexOf('.') + 1)
//
return new Promise(function (resolve, reject) {
const cos = new COS({
// 后端获取签名
getAuthorization: function (options, callback) {
//
callbackApi({ bucket: _config.bucket, region: _config.Region }).then(
(res) => {
var credentials = res.data.data.credentials
if (!credentials) return
callback({
TmpSecretId: credentials.tmpSecretId,
TmpSecretKey: credentials.tmpSecretKey,
XCosSecurityToken: credentials.sessionToken,
// 建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
StartTime: res.data.data.startTime, // 时间戳,单位秒,如:1580000000
ExpiredTime: res.data.data.expiredTime // 时间戳,单位秒,如:1580000900
})
}
)
}
})
const accessConfig = {
Bucket: _config.bucket,
Region: _config.Region,
Key:
_config.dir +
_config.date +
'/' +
_config.str +
new Date().valueOf() +
'.' +
_config.ext,
StorageClass: 'STANDARD',
Body: _config.file, // 上传文件对象
onProgress: function (progressData) {}
}
//
cos.putObject(accessConfig, function (err, data) {
if (err) {
reject({
status_code: -1,
msg: '上传失败',
data: err,
config: _config
})
// resolve({
// status_code: -1,
// msg: '上传失败',
// data: err,
// config: _config
// })
}
if (data && data.Location) {
const urlList = data.Location.split('/')
urlList[0] = 'companywxcdn.zwnet.cn'
resolve({
status_code: 1,
msg: '上传成功',
data: 'https://' + urlList.join('/'),
config: _config
})
}
})
})
}
// export default uploading
function _install(Vue) {
if (Vue && Vue.uploading === undefined) {
Vue.prototype.uploading = uploading
} else {
return
}
}
export default _install
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
*/ */
import store from '@/store' import store from '@/store'
import Clipboard from 'clipboard' import Clipboard from 'clipboard'
import * as imageConversion from 'image-conversion'
export function parseTime(time, cFormat) { export function parseTime(time, cFormat) {
if (arguments.length === 0 || !time) { if (arguments.length === 0 || !time) {
return null return null
...@@ -103,7 +102,8 @@ export function formatTime(time, option) { ...@@ -103,7 +102,8 @@ export function formatTime(time, option) {
* @param {string} url * @param {string} url
* @returns {Object} * @returns {Object}
*/ */
export function param2Obj(url) { export function getParams(url) {
url = url || window.location.href;
const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ') const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
if (!search) { if (!search) {
return {} return {}
......
const jsApiList = [
'getCurExternalContact',
]
export default jsApiList
\ No newline at end of file
export function randomStr(len) {
var le = len || 32
var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678' // ****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****
var maxPos = $chars.length
var str = ''
for (var i = 0; i < le; i++) {
str += $chars.charAt(Math.floor(Math.random() * maxPos))
}
return str
}
\ No newline at end of file
import axios from 'axios' import axios from 'axios'
import { MessageBox, Message } from 'element-ui' import { MessageBox, Message } from 'element-ui'
import store from '@/store/index' import store from '@/store/index'
import { getToken } from '@/utils/auth' import { getToken,removeToken } from '@/utils/auth'
// 常量定义 // 常量定义
const CancelToken = axios.CancelToken const CancelToken = axios.CancelToken
const STATUS_CODE_SUCCESS = 1 const STATUS_CODE_SUCCESS = 1
const TOKEN_ERROR_CODES = [50008, 50012, 50014] // Illegal token, Other clients logged in, Token expired import Cookies from 'js-cookie'
/** /**
...@@ -31,16 +31,19 @@ service.interceptors.request.use( ...@@ -31,16 +31,19 @@ service.interceptors.request.use(
const url = config.data const url = config.data
? config.url + JSON.stringify(config.data) ? config.url + JSON.stringify(config.data)
: config.url : config.url
store.state.user.axiosCancelList.push({
url,
cancel: c
})
}) })
const authToken = getToken()
// 设置认证token // 设置认证token
if (store.getters.token) { if (authToken) {
config.headers['authToken'] = getToken() config.headers['Authtoken'] = authToken
}
const corp_id = store.state.user.corp_id || Cookies.get('corp_id')
const userid = Cookies.get('userid')
if (corp_id) {
config.headers['Corp-Id'] = corp_id
}
if (userid) {
config.headers['User-Id'] = userid
} }
return config return config
}, },
...@@ -50,6 +53,7 @@ service.interceptors.request.use( ...@@ -50,6 +53,7 @@ service.interceptors.request.use(
} }
) )
// 响应拦截器 // 响应拦截器
service.interceptors.response.use( service.interceptors.response.use(
/** /**
...@@ -65,33 +69,23 @@ service.interceptors.response.use( ...@@ -65,33 +69,23 @@ service.interceptors.response.use(
(response) => { (response) => {
const res = response.data const res = response.data
// cancelPending(response.config) // cancelPending(response.config)
// 如果状态码不是成功,则判断为错误 // 如果状态码不是成功,则判断为错误
if (res.status_code !== STATUS_CODE_SUCCESS) { if (res.status_code !== STATUS_CODE_SUCCESS) {
// if (res.status_code === -1) {
// return res
// }
Message({ Message({
message: res.msg || 'Error', message: res.msg || 'Error',
type: 'error', type: 'error',
duration: 5 * 1000 duration: 2 * 1000
})
// 处理token相关错误: 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
if (TOKEN_ERROR_CODES.includes(res.status_code)) {
// to re-login
MessageBox.confirm('登录过期,请重新登录', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
console.log('重新登录')
}) })
if (res.status_code === -100) {
// 登录 过期 重新去登录
setTimeout(() => {
removeToken()
window.location.href = window.location.origin +'/company_app/index.html?corp_id='+Cookies.get('corp_id')
}, 2000);
return res
} }
return Promise.reject(new Error(res.msg || 'Error'))
} }
return res return res
}, },
(error) => { (error) => {
...@@ -101,7 +95,6 @@ service.interceptors.response.use( ...@@ -101,7 +95,6 @@ service.interceptors.response.use(
type: 'error', type: 'error',
duration: 5 * 1000 duration: 5 * 1000
}) })
return Promise.reject(error) return Promise.reject(error)
} }
) )
......
<template>
<div class="about">
<h1>about</h1>
</div>
</template>
<template>
<div class="home">
<h1>home</h1>
</div>
</template>
<script>
export default {
name: 'HomeView',
components: {
}
}
</script>
<template>
<div class="addressBook-content">
通讯录
</div>
</template>
<script>
export default {
name: 'AddressBook',
}
</script>
<style lang="scss" scoped>
.addressBook-content{
width: 100%;
height: 100%;
background: #fff;
}
</style>
\ No newline at end of file
<template>
<div class="applyRecord-content">
申请记录
</div>
</template>
<script>
export default {
name: 'ApplyRecord',
}
</script>
<style lang="scss" scoped>
.applyRecord-content{
width: 100%;
height: 100%;
background: #fff;
}
</style>
\ No newline at end of file
<template>
<el-drawer
title="新增关联账号"
:visible="show"
size="360px"
:append-to-body="true"
@close="close"
>
<div class="content">
<el-form
ref="form"
:model="form"
:rules="rules"
label-width="120px"
>
<div class="inputContent">
<el-form-item
label="请输入w账号"
prop="username"
>
<el-input
v-model.trim="form.username"
placeholder="请输入w账号"
class="input-with-select"
>
</el-input>
</el-form-item>
<el-form-item
label="请输入主游戏名"
prop="main_game_id"
>
<el-select
v-model="form.main_game_id"
filterable
remote
clearable
reserve-keyword
placeholder="请输入主游戏名"
style="width: 100%;"
:remote-method="remoteMethod"
:loading="loading"
@focus="gameNameList=optionsList"
>
<el-option
v-for="item in gameNameList"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item
label="请输入区服"
prop="server_info"
>
<el-select
v-model.trim="form.server_info"
filterable
remote
:disabled="form.main_game_id==''"
clearable
style="width: 100%;"
reserve-keyword
placeholder="请先选择主游戏"
:remote-method="remoteMethodServer"
:loading="loading"
>
<el-option
v-for="item in serverNameList"
:key="item.id"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item
label="请输入角色名"
prop="role_name"
>
<el-input
v-model.trim="form.role_name"
placeholder="请输入角色"
class="input-with-select"
>
</el-input>
</el-form-item>
<el-form-item>
<el-button
type="primary"
size="small"
@click="onSubmit"
>搜索</el-button>
</el-form-item>
</div>
</el-form>
<div class="table">
<div class="bind-account-title">
账号列表
</div>
<userTable
:list="tableList"
@checkedTag="checkedTag"
/>
</div>
<!-- <div class="line"></div> w92865226508-->
<div
v-if="userDetails.username"
class="account_select_userInfo"
>
<div class="bind-account-title" style="margin-top: 20px;">
账号详情
</div>
<div class="item rowFlex columnCenter"><span class="label">账号</span>
<p class="text">{{ userDetails.username }}</p> <span
v-if="userDetails.account_type==2"
class="account_type"
></span>
</div>
<div class="item rowFlex columnCenter"><span class="label">获客渠道</span>
<p class="text">{{ userDetails.channel_name }}</p>
</div>
<div class="item rowFlex columnCenter"><span class="label">注册渠道</span>
<p class="text">{{ userDetails.register_channel_name }}</p>
</div>
<div class="item rowFlex columnCenter"><span class="label">运营渠道</span>
<p class="text">{{ userDetails.operator_channel_name }}</p>
</div>
<div class="item rowFlex columnCenter"><span class="label">注册游戏</span>
<p class="text">{{ userDetails.reg_game_name }}</p>
</div>
<div class="item rowFlex columnCenter"><span class="label">主游戏</span>
<p class="text">{{ userDetails.main_game_name }}</p>
</div>
<div class="item rowFlex columnCenter"><span class="label">真实姓名</span>
<p class="text">{{ userDetails.real_name }}</p>
</div>
<div class="item rowFlex columnCenter"><span class="label">手机号</span>
<p class="text">{{ userDetails.mobile }}</p>
</div>
<div class="item rowFlex columnCenter"><span class="label">染色时间</span>
<p class="text">{{ moment( userDetails.seq_time * 1000).format('YYYY-MM-DD') }}</p>
</div>
<div class="item rowFlex columnCenter"><span class="label">注册时间</span>
<p class="text">{{ moment( userDetails.reg_time * 1000).format('YYYY-MM-DD') }}</p>
</div>
<div class="item rowFlex columnCenter"><span class="label">登录系统</span>
<p class="text">{{ userDetails.last_login_os }}</p>
</div>
<div class="item rowFlex columnCenter"><span class="label">充值金额</span>
<p class="text">{{ userDetails.recharge_total }}</p>
</div>
<div class="item rowFlex columnCenter"><span class="label">是否添加微信</span>
<p class="text">{{ userDetails.wechat_add_status_text }}</p>
</div>
</div>
</div>
<page
class="pageInfo"
:page-info="pageInfo"
@requestNextPage="requestNextPage"
/>
<span class="dialog-footer rowFlex">
<el-button
class="btn"
type="primary"
size="small"
:disabled="!userDetails.id"
@click="confirmSubmit"
>确 定</el-button>
<el-button
class="btn"
size="small"
@click="$emit('update:show', false)"
>取 消</el-button>
</span>
</el-drawer>
</template>
<script type="text/javascript">
import moment from 'moment'
import userTable from './userTable.vue'
import { getRoleHoLo, memberView, selectSearch } from '@/api/game'
import { checkZyouBind,zyouBind } from '@/api/works'
import { mapMutations, mapActions, mapState } from 'vuex'
import page from '@/components/page/pageNum.vue'
export default {
components: {
userTable,
page
},
props: ['show'],
data() {
return {
moment,
tableList: [],
checkoutUser: {},
userDetails: {},
loading: false,
pageInfo: {
page: 1,
page_size: 20,
total: 0
},
form: {
member_id: '',
username: '',
role_name: '',
main_game_id: '',
server_info: ''
},
gameNameList: [],
optionsList: [],
serverNameList: [],
rules: {
}
}
},
computed: {
...mapState('game', ['chatUserInfo']),
},
watch: {
show(newVal, oldVal) {
if (newVal) {
// this.requestRoleList()
this.requestGameList()
}
}
},
mounted() {
},
methods: {
...mapActions('game', ['gameBindUser']),
...mapMutations('game', ['set_accountSelect']),
requestRoleList() {
const data = {
member_id: this.form.member_id,
username: this.form.username.trim(),
role_name: this.form.role_name.trim(),
main_game_id: this.form.main_game_id !== '' ? [this.form.main_game_id] : [],
server_info: this.form.server_info !== '' ? [this.form.server_info] : [],
search_type: 'bind',
...this.pageInfo
}
getRoleHoLo(data).then(res => {
if (res.status_code == 1) {
if (res.data.data.length == 0) {
this.tableList = []
this.$message.warning('暂无数据')
} else {
this.tableList = res.data.data
this.pageInfo = res.data.page_info
}
}
})
},
// S181.啊呸¤可瑞 八荒181服
// 分页
requestNextPage(pageInfo) {
this.pageInfo.page = pageInfo.page
this.requestRoleList()
},
remoteMethodServer(query) {
if (query !== '') {
this.loading = true
const data = {
type: 'server_info',
value: query,
main_game_ids: this.form.main_game_id
}
selectSearch(data).then(res => {
this.loading = false
if (res.status_code == 1) {
this.serverNameList = res.data.data
}
})
}
},
remoteMethod(query) {
if (query !== '') {
this.gameNameList = this.optionsList.filter(item => {
return item.label.toLowerCase()
.indexOf(query.toLowerCase()) > -1
})
} else {
this.gameNameList = []
}
},
requestGameList() {
const data = {
type: 'mainGameList',
value: '',
weixin_blong_id: ''
}
selectSearch(data).then(res => {
this.loading = false
if (res.status_code == 1) {
this.gameNameList = this.optionsList = res.data.data
}
})
},
close() {
this.$emit('update:show', false)
this.resizeData()
},
onSubmit() {
this.$refs.form.validate((valid) => {
this.pageInfo = {
page: 1,
page_size: 20,
total: 0
}
if (valid) {
if (this.form.role_name == '' && this.form.username == '') {
this.$message.warning('请输入角色名或者w账号')
return
}
this.requestRoleList()
} else {
console.log('error submit!!')
return false
}
})
},
resizeData() {
this.form = {
member_id: '',
username: '',
role_name: '',
main_game_id: '',
server_info: ''
}
this.tableList = []
this.checkoutUser = {}
this.userDetails = {}
},
confirmSubmit() {
const data = {
member_id: this.userDetails.id && this.userDetails.id != '' ? this.userDetails.id : this.checkoutUser.member_id,
username: this.userDetails.username
}
checkZyouBind(data).then(res => {
console.log(data)
if (!res.data.has_bind) {
this.submit()
} else {
this.$confirm(res.data.tip || '', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
this.submit()
})
.catch((err) => {
console.log(err)
this.$message({
type: 'info',
message: '已取消删除'
})
})
}
})
},
submit() {
const data = {
userid: this.chatUserInfo.userid,
external_userid: this.chatUserInfo.external_userid,
member_id: this.userDetails.id && this.userDetails.id != '' ? this.userDetails.id : this.checkoutUser.member_id,
username: this.userDetails.username,
reg_game_id: this.userDetails.reg_game_id,
main_game_id: this.userDetails.main_game_id,
recharge_total: this.userDetails.recharge_total,
}
// 绑定掌游账号
zyouBind(data).then(res => {
if (res.status_code == 1) {
this.$message.success(res.msg)
this.updateData()
}
})
},
// 更新列表数据
updateData() {
const data = {
userid: this.chatUserInfo.userid,
external_userid: this.chatUserInfo.external_userid
}
this.gameBindUser(data).then(res => {
this.set_accountSelect(this.userDetails.id)
this.close()
})
},
// 勾选活码
checkedTag(value) {
this.checkoutUser = value
const data = {
member_id: value.member_id,
need_channel: 1,
need_roleInfo: 1
}
this.rquestUserInfo(data)
},
rquestUserInfo(data) {
memberView(data).then(res => {
if (res.status_code == 1) {
this.userDetails = res.data
}
})
}
}
}
</script>
<style lang="scss" scoped>
::v-deep .el-drawer {
height: 100%;
overflow: auto;
}
.bind-account-title{
font-size: 16px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 600;
color: #333333;
text-align: left;
margin-bottom: 10px;
}
.content {
width: 100%;
height: 100%;
overflow: auto;
padding-bottom: 200px;
padding: 0 10px;
.inputContent {
width: 100%;
}
.info {
width: 100%;
margin-top: 30px;
overflow: auto;
.table {
width: 100%;
min-width: 500px;
}
}
.line {
position: absolute;
left: 55%;
top: 12%;
transform: translate(-55%, 0);
width: 1px;
height: 70%;
border-right: 1px dashed #e0e0e0;
}
.account_select_userInfo {
width: 100%;
height: auto;
padding-left: 20px;
margin-top: -20px;
.item {
width: 100%;
margin-top: 20px;
.label {
width: 30%;
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #666666;
text-align: left;
margin-right: 20px;
}
.text {
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #333333;
word-wrap: break-word;
}
}
}
}
.account_type {
color: #f56c6c;
font-weight: bold;
margin-left: 5px;
background: #f7eded;
padding: 2px 5px;
border-radius: 3px;
}
.pageInfo {
width: calc(100% - 20px);
height: 82px;
position: absolute;
right: 20px;
bottom: 60px;
background: #fff;
}
.dialog-footer {
width: calc(100% - 20px);
position: absolute;
right: 20px;
bottom: 0;
padding-top: 20px;
padding-bottom: 20px;
border-top: 1px solid rgba(0, 0, 0, 0.06);
justify-content: flex-end;
background: #fff;
z-index: 10;
.btn {
width: 84px;
height: 32px;
}
}
</style>
<style>
::v-deep .el-select-dropdown {
min-width: 210px !important;
}
</style>
\ No newline at end of file
<template>
<div class="bindUserList rowFlex columnCenter">
<div class="select">
<el-select v-model="bindAccount" placeholder="请选择关联账号" :clearable="false" @change="handleChange">
<el-option label="新增关联账号" value="add" @click="addNewUser">
</el-option>
<el-option v-for="(item, index) in bindGameUserList" :key="index" :label="item.username"
:value="item.member_id">
</el-option>
</el-select>
</div>
<p v-if="bindGameUserList.length > 0" class="num">
总共{{ bindGameUserList.length }}个账号
</p>
<el-button type="danger" style="margin-left: 10px;" size="mini" @click="logout">下线</el-button>
<addUser
:show.sync="showLayer"
title="选择玩家"
width="60%"
/>
</div>
</template>
<script type="text/javascript">
import { detailsInfoRequest } from '@/api/works'
import {memberView} from '@/api/game'
import { logout } from '@/api/user'
import { mapState, mapMutations, mapActions } from 'vuex'
import addUser from './addUser.vue'
import { getToken,removeToken } from '@/utils/auth'
// 更新代码
export default {
components: {
addUser
},
data() {
return {
showLayer: false,
accountValue: '',
bindAccount:'',
memberCheckList:[], // 自定义列
}
},
computed: {
...mapState('game', [
'bindGameUserList',
'accountSelect',
'gameUserInfo'
]),
...mapState('user', [
'userid',
'corp_id',
'external_userid'
]),
},
watch: {
accountSelect(newVal,oldVal) {
if(newVal){
console.log(newVal,'hahhaha')
this.gameMemberView()
this.bindAccount = newVal
}
}
},
async mounted() {
console.log(this.external_userid,'external_userid')
this.bindUserList()
this.requestDetails()
},
methods: {
...mapMutations('game', [
'set_accountSelect',
'set_chatUserInfo',
'set_gameUserInfo'
]),
...mapActions('game', ['gameBindUser']),
handleChange(value) {
if (value == 'add') {
this.showLayer = true
} else {
this.set_accountSelect(value)
}
},
gameMemberView(item) {
if (this.accountSelect && this.accountSelect !== '') {
const data = { member_id: this.accountSelect, need_channel: 1, need_roleInfo: 1, need_banned: 1 }
memberView(data).then((res) => {
if (res.status_code === 1) {
this.set_gameUserInfo(res.data)
} else {
this.set_gameUserInfo({})
}
}, (err) => {
this.set_gameUserInfo({})
})
}
},
logout(){
this.$confirm('确定下线吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.userLogout()
}).catch(() => {
this.$message({
type: 'info',
message: '已取消'
})
})
},
async userLogout(){
const data = {
userid: this.userid,
}
const res = await logout(data)
if(res.status_code === 1){
this.$message({
type: 'success',
message: '下线成功'
})
removeToken()
window.location.href = window.location.origin +'/company_app/index.html?corp_id='+this.corp_id
}else{
this.$message({
type: 'error',
message: '下线失败'
})
}
},
addNewUser() {
console.log(11)
},
async requestDetails() {
const data = {
userid: this.userid,
external_userid: this.external_userid
}
const res = await detailsInfoRequest(data)
if (res.data && res.data.userid) {
console.log(res.data,'1231')
this.chatUserDetails = res.data
this.set_chatUserInfo(this.chatUserDetails) // 设置云端信息
console.log(this.chatUserDetails,'1231')
if (this.chatUserDetails.self_defined_columns && this.chatUserDetails.self_defined_columns.length > 0) {
this.memberCheckList =
this.chatUserDetails.self_defined_columns.map(
(item) => item.name
)
} else {
this.memberCheckList = []
}
} else {
this.chatUserDetails = {}
}
// 获取到用户的详情 储存在缓存里面
},
// 绑定列表
async bindUserList() {
const data = {
userid: this.userid,
external_userid: this.external_userid
}
const res = await this.gameBindUser(data)
if (res.length > 0) {
this.set_accountSelect(res[0].member_id)
this.bindAccount = res[0].member_id
} else {
this.set_accountSelect('')
this.bindAccount = ''
}
}
}
}
</script>
<style lang="scss" scoped>
.bindUserList {
margin: 10px;
.select {
::v-deep .el-input--small .el-input__inner {
// border-radius: 16px;
border: none;
// color: $color;
min-width: 200px;
height: 30px;
line-height: 30px;
background: #ecfff6;
color: #46c988;
}
::v-deep .el-input__suffix {
// display: none;
color: #46c988;
}
}
.num {
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 600;
margin-left: 10px;
white-space: nowrap;
color: #F53F3F;
}
}
</style>
\ No newline at end of file
<template>
<el-table
ref="multipleTable"
:data="list"
tooltip-effect="dark"
style="width: 100%"
size="medium"
highlight-current-row
:header-cell-style="{
background: '#F7F8FA',
color: '#333333',
fontWeight: 500,
}"
@current-change="handleCurrent"
>
<el-table-column width="50px">
<template v-slot="scope">
<!-- label值要与el-table数据id实现绑定 -->
<el-radio
v-model="unitInfo.role_id"
style="margin-left:10px;"
:label="scope.row.role_id"
>{{ "" }}</el-radio>
</template>
</el-table-column>
<el-table-column
label="w账号"
prop="username"
>
</el-table-column>
<el-table-column
label="角色名"
prop="role_name"
>
</el-table-column>
<el-table-column
label="区服"
prop="server_name"
>
</el-table-column>
<el-table-column
label="充值金额"
prop="recharge_total"
>
<template v-slot="scope">
{{ scope.row.recharge_total }}
</template>
</el-table-column>
</el-table>
</template>
<script>
export default {
props: ['list'],
data() {
return {
currentRow: [],
unitInfo: {
userId: ''
}
}
},
watch: {
list(newVal, oldVal) {
this.unitInfo = { userId: '' }
}
},
methods: {
handleCurrent(val) {
console.log(val)
if (val) {
this.unitInfo = val
this.$emit('checkedTag', this.unitInfo)
}
}
}
}
</script>
<style scoped lang='scss'>
.el-dropdown {
margin-left: 10px;
}
.tags {
background: #ecfff6;
border-radius: 4px;
border: 1px solid #c5ffe2;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #46c988;
padding: 0 5px;
max-width: 100%;
font-size: 12px;
}
.tagItem {
display: inline-block;
}
.allTags {
.tags {
margin-left: 10px;
}
}
.el-dropdown-link {
cursor: pointer;
}
.qrImage {
width: vw(140);
height: vw(140);
}
.tableImage {
width: 30px;
height: 30px;
border-radius: 30px;
margin-right: 10px;
}
.infoSpan {
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #999999;
max-width: 120px;
span {
color: #ffa81d;
}
}
::v-deep .el-table__header-wrapper .el-checkbox {
display: none;
}
</style>
\ No newline at end of file
<template>
<div class="giftRecord-content">
礼包记录
</div>
</template>
<script>
export default {
name: 'GiftRecord',
}
</script>
<style lang="scss" scoped>
.giftRecord-content{
width: 100%;
height: 100%;
background: #fff;
}
</style>
\ No newline at end of file
// UnifiedLogin.vue
<template>
<div class="loginContent">
<div v-if="!token">
<div>
当前组织:<span class="current-org">{{ currentOrg.name }}</span>
<el-button type="text" @click="showOrgDialog = true">切换组织</el-button>
</div>
<div class="qr-contain" >
<div id="dingTalkLoginContainer" >
</div>
<div class="refresh">
<i
class="el-icon-refresh-right "
@click="refreshDingTalkQRCode"
></i>
</div>
<!-- 生二维码的时候加一个 loading -->
<div class="loading" v-if="qrLoading">
<span class="loading-spinner"></span>
</div>
</div>
<!-- 组织切换弹窗 -->
<el-dialog :visible.sync="showOrgDialog" width="300px" title="选择组织">
<ul style="list-style:none;padding:0;margin-top: -20px;">
<li v-for="org in orgList" :key="org.app_key"
@click="switchOrg(org)"
:style="{
padding: '8px 16px',
cursor: 'pointer',
background: org.app_key === currentOrg.app_key ? '#e6f7ff' : '',
color: org.app_key === currentOrg.app_key ? '#1890ff' : '',
fontWeight: org.app_key === currentOrg.app_key ? 'bold' : 'normal',
borderRadius: '4px',
marginBottom: '4px',
transition: 'background 0.2s'
}"
@mouseover="hoveredOrg = org.app_key"
@mouseleave="hoveredOrg = null"
>
{{ org.name }}
<span v-if="org.app_key === currentOrg.app_key" style="margin-left:8px;">(当前)</span>
</li>
</ul>
</el-dialog>
</div>
</div>
</template>
<script>
import * as ww from '@wecom/jssdk'
import { getOrganization,getAuthUser,getSignature } from '@/api/user'
import Cookies from 'js-cookie'
import { getParams } from '@/utils/index'
import { mapMutations,mapState } from 'vuex'
import { getToken,setToken } from '@/utils/auth'
import jsApiList from '@/utils/jsApiList'
export default {
data() {
return {
wecomUserInfo: null, // 企微用户信息
dingUserInfo: null, // 钉钉用户信息
signData: null, // 企微签名数据
orgList: [],
urlParams:{},
currentOrg: {},
showOrgDialog: false,
hoveredOrg: null,
showRefresh: false, // 控制刷新按钮显示
qrLoading: false, // 控制二维码 loading
redirectUri: process.env.NODE_ENV === 'production' ? 'https://companywx.zwnet.cn/api/api/sidebar_login/ding' : 'https://companywx.zwwlkj03.top/api/api/sidebar_login/ding',
DDTestUrl:'',
token:getToken()
}
},
async mounted() {
this.$nextTick(() => {
this.initLogin()
})
},
computed:{
...mapState('user',['corp_id'])
},
methods: {
...mapMutations('user',['set_corp_id','set_userid','set_userInfo','set_token','set_cser_info','set_signData','set_cser_id','set_cser_name','set_external_userid']),
async initLogin(){
await this.initOrganization();
const urlParams = getParams();
const userid = Cookies.get('userid');
// 如果是钉钉扫码回调页面
if ( urlParams.type && urlParams.type === 'ding') {// 钉钉回调
console.log(1)
this.handleDingCallback();
}else if(this.token){ // 已经钉钉扫码过 重新获取授权 获取签名 注册企微js-sdk
console.log(2)
await this.getSignature();
}else {
console.log(3)
if(!userid){ //没有企微授权过 并且 钉钉扫码成功 开始微信授权
console.log(4)
await this.startWeComSilentAuth();
}else{
console.log(5)
this.initDingTalkLogin(); // 始化钉钉扫码
}
}
// 每次进入页面都缓存corp_id
if(urlParams.corp_id){
this.cacheCorp_id(urlParams.corp_id) // 缓存 corp_id
}
},
// 设置缓存
cacheCorp_id(corp_id){
Cookies.set('corp_id',corp_id, { expires: 7 })
this.set_corp_id(corp_id)
},
cacheuserid(userid){
Cookies.set('userid',userid, { expires: 7 })
this.set_userid(userid)
},
cacheWx_userinfo(userinfo){
Cookies.set('wx_userinfo',JSON.stringify(userinfo), { expires: 7 })
this.set_userInfo(userinfo)
},
cacheCser(cser_id,cser_name){
Cookies.set('cser_id',cser_id, { expires: 7 })
Cookies.set('cser_name',cser_name, { expires: 7 })
this.set_cser_info({
cser_id:cser_id,
cser_name:cser_name
})
this.set_cser_id(cser_id)
this.set_cser_name(cser_name)
},
cacheSignData(signData){
Cookies.set('signData',JSON.stringify(signData), { expires: 7 })
this.set_signData(signData)
},
// 进入的页面地址是 https://companywx.jianshuwenhua.com/company_app/index.html?corp_id=wweaefe716636df3d1
// 1. 企微静默授权
async startWeComSilentAuth() {
this.urlParams = getParams();
const corp_id = Cookies.get('corp_id')
// 确定是第一次进入页面 没有 code 和 state
if (!this.urlParams.code && !this.urlParams.state) {
// 跳转企微静默授权
const redirectUri = encodeURIComponent(window.location.href);
const authUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${corp_id}&redirect_uri=${redirectUri}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect`;
window.location.href = authUrl;
return;
}
// 用code
const res = await getAuthUser({ code: this.urlParams.code, url: window.location.href,corp_id:corp_id });
if (res.status_code === 1) {
// this.cacheWx_userinfo(res.data)
this.cacheuserid(res.data.userid)
this.initDingTalkLogin(); // 初始化钉钉扫码
} else {
console.log('获取useid失败',res)
// 错误处理
}
},
async getSignature(){
console.log('获取签名',window.location.href)
const corp_id = Cookies.get('corp_id')
try{
const res = await getSignature({ corp_id: corp_id, path: window.location.href });
if(res.status_code === 1){
this.signData = res.data
this.cacheSignData(res.data)
try{
this.registerWeComSDK();
}catch(err){
console.log(err,'初始化sdk 失败')
}
}
}catch(err){
console.log(err,'获取签名失败')
window.location.href = window.location.origin +'/company_app/index.html?corp_id='+corp_id+'&msg=signerror'
}
},
getCurExternalContact() {
ww.getCurExternalContact({
success: (res) => {
if (res.err_msg === "getCurExternalContact:ok") {
console.log(res,'重新进入获取企微外部联系人')
this.set_external_userid(res.userId)
// 确保 Vuex 状态更新后再跳转
this.$nextTick(() => {
this.$router.replace('/')
console.log(window.location.href,'window.location.hrefuserInfo')
})
}
},
fail: (err) => {
console.log(err,'获取企微外部联系人失败')
// 错误处理
}
});
},
// 2. 注册企微JS-SDK
registerWeComSDK() {
console.log('删除企业签名',1231)
ww.register({
corpId: Cookies.get('corp_id'),
agentId: this.signData.agent_id,
jsApiList: jsApiList,
// getConfigSignature: () => Promise.resolve({
// nonceStr: this.signData.nonce_str,
// timestamp: this.signData.signature_time,
// signature: this.signData.corp_signature,
// }),
// 只用到应用的 api 可以只进行应用的签名
getAgentConfigSignature: () => Promise.resolve({
nonceStr: this.signData.nonce_str,
timestamp: this.signData.signature_time,
signature: this.signData.agent_signature,
}),
onAgentConfigSuccess: (res) => {
console.log('注册成功可以调用企微 js-sdk',res)
// 注册成功后不立即获取外部联系人,等钉钉扫码后再获取
this.getCurExternalContact()
},
onAgentConfigFail: (err) => {
console.log('注册失败不能使用企微js-sdk',err)
// 错误处理123
}
});
},
// 3. 获取组织列表并选取默认组织
async initOrganization() {
const res = await getOrganization();
if (res.data.status_code === 1) {
this.orgList = res.data.data.data;
// 默认组织逻辑:可根据业务自定义
this.initCurrentApp();
}
},
initCurrentApp() {
const currentApp = this.orgList.find(
(item) => item.app_key === "dingjigp0ksn9nbljdli"
);
this.$set(this, "currentOrg", currentApp);
},
// 4. 初始化钉钉扫码
initDingTalkLogin() {
this.qrLoading = true;
console.log('进入初始化钉钉',this.currentOrg)
if (!this.currentOrg.app_key) return;
const appid = this.currentOrg.app_key;
// 清空二维码容器,防止切换组织后二维码不刷新
const container = document.getElementById('dingTalkLoginContainer');
if (container) container.innerHTML = '';
DDLogin({
id: 'dingTalkLoginContainer',
goto: encodeURIComponent(`https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=${appid}&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=${this.redirectUri}`),
style: 'border:none;background-color:#FFFFFF;margin:0',
width: '210',
height: '250'
});
// 二维码生成后,短暂延迟后隐藏 loading(二维码生成是同步的,但页面渲染有延迟)
this.$nextTick(() => {
setTimeout(() => {
this.qrLoading = false;
}, 1000); // 500ms 平滑过渡
});
window.addEventListener('message', this.handleDingTalkLogin, false);
if (typeof window.addEventListener !== 'undefined') {
window.addEventListener('message', this.handleDingTalkLogin, false)
} else if (typeof window.attachEvent !== 'undefined') {
window.attachEvent('onmessage', this.handleDingTalkLogin)
}
},
// https://companywx.jianshuwenhua.com/company_app/login?code=success&cser_id=4090&cser_name=%E6%AF%9B%E7%BB%86%E4%BA%9A&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOjQwOTAsImRhdGEiOnsiY3Nlcl9pZCI6NDA5MCwiY3Nlcl9uYW1lIjoi5q-b57uG5LqaIn0sImlhdCI6MTc0Nzk5MDM0MiwiZXhwIjoxNzUwNTgyMzQyLCJuYmYiOjE3NDc5OTAzNDIsInN1YiI6InRva2Vu6K6k6K-BIiwianRpIjoiYzYzYTM4NGYzMTFmODVlMGQ2Nzg2ZmJiMTdhNjQzN2EifQ.5ADPtqISjxOqbrDOzlKkCpfTr78Sv0Sdi-_Y1RRiMH0&type=ding
// 5. 切换组织
switchOrg(org) {
if (org.app_key === this.currentOrg.app_key) return; // 已是当前组织不处理
this.currentOrg = org;
this.showOrgDialog = false;
this.initDingTalkLogin();
},
// 6. 钉钉扫码回调
async handleDingTalkLogin(event) {
console.log('收到扫码回调')
const corp_id = Cookies.get('corp_id')
const userid = Cookies.get('userid')
if (event.origin !== 'https://login.dingtalk.com') return;
const loginTmpCode = event.data;
// 跳转到后端,后端用loginTmpCode换取钉钉用户信息
const appid = this.currentOrg.app_key;
const state = encodeURIComponent(`${this.currentOrg.app_key}$${this.currentOrg.template_code}$${corp_id}$${userid}`)
const url = `https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=${appid}&response_type=code&scope=snsapi_login&state=${state}&redirect_uri=${this.redirectUri}&loginTmpCode=${loginTmpCode}`;
console.log(url,'回调 url')
this.DDTestUrl = url
window.location.href = url;
},
// 7. 钉钉扫码回调页面处理
async handleDingCallback() {
// 在这里处理钉钉扫码成功的回调
console.log('扫码成功')
const ddParams = getParams();
const corp_id = Cookies.get('corp_id')
if(ddParams.code=='error' && ddParams.msg){
this.$message.error(ddParams.msg)
return
}
if(ddParams.token && ddParams.token!='undefined'){
setToken(ddParams.token)
this.set_token(ddParams.token)
// 获取签名
await this.getSignature();
}else{
console.log('没有token')
window.location.href = window.location.origin +'/company_app/index.html?corp_id='+corp_id+'&msg=notoken'
}
if(ddParams.cser_id){
this.cacheCser(ddParams.cser_id,ddParams.cser_name)
}
},
refreshDingTalkQRCode() {
this.initDingTalkLogin();
},
},
}
</script>
<style lang="scss" scoped>
.current-org {
font-weight: bold;
margin-right: 5px;
}
.loginContent{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.qr-contain {
margin: 0 auto;
/* margin-top: 20px; */
width: 260px;
height: 260px;
position: relative;
overflow: hidden;
#dingTalkLoginContainer {
padding: 15px;
position: absolute;
left: 10px;
bottom: 0;
}
.refresh {
display: none;
text-align: center;
position: absolute;
width: 40px;
background: #fff;
height: 40px;
transform: translate(-50%,-50%);
left: 50%;
top: 50%;
i {
line-height: 40px;
font-size: 26px;
color: #00BF8A;
cursor: pointer;
}
}
&:hover {
.refresh {
display: block;
}
}
}
.loading {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(255,255,255,0.7);
display: flex;
align-items: center;
justify-content: center;
z-index: 20;
transition: opacity 0.3s;
}
.loading-spinner {
width: 40px;
height: 40px;
border: 4px solid #e0e0e0;
border-top: 4px solid #00BF8A;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
\ No newline at end of file
<template>
<div class="quickReply-content">
快捷回复
</div>
</template>
<script>
export default {
name: 'QuickReply',
}
</script>
<style lang="scss" scoped>
.quickReply-content{
width: 100%;
height: 100%;
background: #fff;
}
</style>
\ No newline at end of file
<template>
<div class="quickSend-content">
快捷发送
</div>
</template>
<script>
export default {
name: 'QuickSend',
}
</script>
<style lang="scss" scoped>
.quickSend-content{
width: 100%;
height: 100%;
background: #fff;
}
</style>
\ No newline at end of file
<template>
<h1>1231312312312312321</h1>
</template>
<script>
import * as ww from '@wecom/jssdk'
import { getSignature } from '@/api/user'
export default {
name: 'testWx',
data() {
return {
signData: {},
}
},
mounted() {
this.getSignature()
console.log(window.location.href,'window.location.href')
},
methods: {
async getSignature(){
console.log('获取签名',window.location.href)
const res = await getSignature({ corp_id: 'wweaefe716636df3d1', path: window.location.href });
if(res.status_code === 1){
this.signData = res.data
try{
this.registerWeComSDK();
}catch(err){
console.log(err,'初始化sdk 失败')
}
}
},
registerWeComSDK() {
ww.register({
corpId: 'wweaefe716636df3d1',
agentId: this.signData.agent_id,
jsApiList: ['getExternalUserInfo'],
getConfigSignature: () => Promise.resolve({
nonceStr: this.signData.nonce_str,
timestamp: this.signData.signature_time,
signature: this.signData.corp_signature,
}),
// 只用到应用的 api 可以只进行应用的签名
getAgentConfigSignature: () => Promise.resolve({
nonceStr: this.signData.nonce_str,
timestamp: this.signData.signature_time,
signature: this.signData.agent_signature,
}),
onAgentConfigSuccess: (res) => {
console.log('注册成功可以调用企微 js-sdk',res)
this.getCurExternalContact()
// 注册成功后不立即获取外部联系人,等钉钉扫码后再获取
},
onAgentConfigFail: (err) => {
console.log('注册失败不能使用企微js-sdk',err)
// 错误处理
}
});
},
getCurExternalContact() {
ww.getCurExternalContact({
success: (res) => {
if (res.err_msg === "getCurExternalContact:ok") {
console.log(res,'获取企微外部联系人')
}
},
fail: (err) => {
console.log(err,'获取企微外部联系人失败')
// 错误处理
}
});
},
}
}
</script>
\ No newline at end of file
<template>
<div class="info-tab-content">
<div
class="userDetailsPanel columnFlex"
>
<div class="content">
<div
v-if="change_appraisal"
style="
font-size: 28px;
color: red;
text-align: center;
margin-bottom: 20px;
line-height: 40px;
"
>
钓鱼号 禁止转端通知组长!
</div>
<div
v-else-if="gameUserInfo.exp_ip"
style="
font-size: 28px;
color: red;
text-align: center;
margin-bottom: 20px;
line-height: 40px;
"
>
高风险用户,禁止转端 !!!
</div>
<div class="item rowFlex">
<!-- 公共的信息 -->
<el-image
fit="fill"
draggable="false"
style="-webkit-user-drag: none"
:src="chatUserDetails.avatar"
class="tableImage"
></el-image>
<div class="columnFlex">
<div
class="rowFlex"
style="margin-bottom: 3px"
>
<p
class="text"
style="font-weight: 600"
>
{{ chatUserDetails.name }}
</p>
<span v-if="chatUserDetails.add_way_text" style="color: #09b159; margin-left: 10px">@{{ chatUserDetails.add_way_text }}</span>
</div>
<!-- 游戏模块特有 -->
<div
v-if="accountSelect && accountSelect !== ''"
style="margin-top: 3px"
>
<el-button-group>
<el-button size="mini" @click="zyouUnBindConfirm">解绑</el-button>
<el-button size="mini" @click="autoResetPassword">修改密码</el-button>
<el-button size="mini" @click="changePhoneClick">修改手机号</el-button>
<el-button v-if="!chatUserDetails.bind_cser" size="mini" @click="relationKfh">关联客服</el-button>
<el-button size="mini" v-if="false" @click="errorHandle">误操作</el-button>
</el-button-group>
</div>
</div>
</div>
<div class="item rowFlex columnCenter">
<div class="rowFlex columnCenter">
<span class="label" style="min-width: 45px;">备注:</span>
<p
v-if="!showInputRemark"
class="text"
style="max-width: 170px;"
>
{{
chatUserDetails.remark && chatUserDetails.remark != ""
? chatUserDetails.remark
: chatUserDetails.name
}}
</p>
</div>
<el-input
v-if="showInputRemark"
v-model="showInputRemarkValue"
class="showInputRemarkInput"
type="textarea"
@change="handleInputRemark"
@blur="showInputRemark = false"
></el-input>
<i class="el-icon-edit icon" style="font-size: 14px"
@click="editRemark"></i>
</div>
<div>
<!-- 自定义列 -->
<!-- <div v-if="false">
<div
v-for="(item, index) in chatUserDetails.self_defined_columns"
:key="index"
class="item rowFlex columnCenter"
>
<div class="rowFlex columnCenter">
<span class="label">{{ item.name }}</span>
<p
v-if="!showInput || inputIndex != index"
class="text"
>
{{ item.value }}
</p>
</div>
<el-input
v-if="showInput && inputIndex == index"
v-model="showInputValue"
style="width: 120px; margin-left: 10px"
@change="handleInput(item, index)"
@blur="showInput = false"
></el-input>
<i class="el-icon-edit icon" style="font-size: 14px"
@click="inputShow(item, index)"></i>
</div>
</div> -->
<!-- 游戏业务的账号信息 -->
<gameDetails
v-if="gameUserInfo.username"
:chat-user-details="chatUserDetails"
:game-user-info="gameUserInfo"
@changeAppraisal="changeAppraisal"
/>
<!-- 游戏标签 -->
<!-- <div
v-else-if="messageSource === 'company_work' && workerRouter !== 'novel'"
class="item rowFlex columnCenter spaceBetween tagsLost"
>
<div class="rowFlex">
<span class="label">关联标签:</span>
<div
v-if="
chatUserDetails.tag_group &&
chatUserDetails.tag_group.length > 0
"
class="tags rowFlex columnCenter flexWarp"
>
<div
v-for="(item, index) in chatUserDetails.tag_group"
:key="index"
class="tagsItem rowFlex columnCenter flexWarp"
>
<span
v-for="(items, indexs) in item.tag"
:key="indexs"
class="tag hidden"
>{{ items.name }}</span>
</div>
</div>
</div>
<svg-icon
icon-class="edit"
class="icon"
style="font-size: 14px"
@click="editTags"
/>
</div> -->
<!-- 共享信息 -->
<shareInfo :chat-user-details="chatUserDetails" />
</div>
</div>
</div>
<!-- 修改手机号 -->
<changePhone
:show.sync="changePhone"
:phone.sync="gameUserInfo.mobile"
title="修改手机号"
width="350px"
/>
</div>
</template>
<script>
import { mapState } from 'vuex'
import gameDetails from './gameInfo/gameUserInfo.vue'
import shareInfo from './shareInfo.vue'
import changePhone from './changePhone.vue'
import watchMember from '@/mixins/watchMember'
import { zyouUnBind,autoResetPassword,bindUserSelfAdd } from '@/api/game'
import { memberBindCser,editUser } from '@/api/works'
export default {
name: 'UserDetailsPanel',
components: {
gameDetails,
changePhone,
shareInfo
},
props: {
// 用户详情
chatUserDetails: {
type: Object,
default: () => ({})
},
},
data() {
return {
// 备注相关
showInputRemark: false,
showInputRemarkValue: '',
change_appraisal:false,
// 自定义列相关
showInput: false,
showInputValue: '',
inputIndex: -1,
changePhone:false
}
},
computed: {
...mapState('game', [
'accountSelect',
'gameUserInfo',
'bindGameUserList'
]),
...mapState('user', ['cser_info','cser_id','cser_name'])
},
mixins: [watchMember],
mounted() {
},
methods: {
memberChange() {
this.requestBindUser()
},
// 解绑确认
zyouUnBindConfirm() {
this.$confirm('确定要解绑当前账号么?', '确认提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
this.zyouUnBind()
})
.catch(() => {
this.$message({
type: 'info',
message: '已取消'
})
})
},
requestBindUser() {
const data = {
member_id: this.accountSelect
}
memberBindCser(data).then((res) => {
console.log(res.data.cser_name, 'cser_namecser_namecser_namecser_name')
if (res.data.cser_name) {
this.$set(this.chatUserDetails, 'bind_cser', res.data.cser_name)
} else {
this.$set(this.chatUserDetails, 'bind_cser', '')
}
})
},
zyouUnBind() {
const data = {
userid: this.selectUser.userid,
external_userid: this.chatUserDetails.external_userid,
member_id: this.accountSelect
}
zyouUnBind(data).then((res) => {
if (res.status_code == 1) {
this.$message.success(res.msg)
this.set_selectWindow()
}
})
},
// 修改密码 之前是客服手动设置密码 现在改成系统自动设置密码
autoResetPassword() {
this.$confirm('确认重置密码吗?密码重置后玩家将无法登录,请谨慎操作!', '重置密码', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(res => {
const data = {
member_id: this.accountSelect,
zq_user_name: this.cser_name
}
autoResetPassword(data).then((res) => {
if (res.status_code == 1) {
this.$message.success('密码重置成功')
}
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消'
})
})
},
// 修改手机号
changePhoneClick() {
this.changePhone = true
},
// 关联客服
relationKfh() {
const username = this.bindGameUserList.find(
(item) => item.value == this.accountSelect
)
const params = {
member_id: this.accountSelect,
user_id: this.cser_id,
user_name: this.cser_name,
username: username.username
}
bindUserSelfAdd(params).then((res) => {
if (res.status_code == 1) {
this.$set(this.chatUserDetails, 'bind_cser', 1)
this.$message.success(res.msg)
}
})
},
// 误操作处理
errorHandle() {
this.$emit('error-handle')
},
// 编辑备注
editRemark() {
this.showInputRemark = true
this.showInputRemarkValue = this.chatUserDetails.remark || this.chatUserDetails.name
this.$nextTick(() => {
// document.querySelector('.showInputRemarkInput input').focus()
})
},
// 处理备注输入
handleInputRemark(val) {
this.showInputRemark = false
this.chatUserDetails.remark = this.showInputRemarkValue
const data = {
userid: this.chatUserDetails.userid,
external_userid: this.chatUserDetails.external_userid,
remark: this.chatUserDetails.remark,
self_defined_columns: this.chatUserDetails.self_defined_columns,
tag_group: this.chatUserDetails.tag_group
}
this.editUserInfo(data)
},
editUserInfo(data) {
editUser(data).then((res) => {
if (res.status_code == 1) {
this.$message({
type: 'success',
message: res.msg
})
}
})
},
// 显示自定义列输入
inputShow(item, index) {
this.showInput = true
this.inputIndex = index
this.showInputValue = item.value
this.$nextTick(() => {
document.querySelectorAll('input')[0].focus()
})
},
// 处理自定义列输入
handleInput(item, index) {
this.$emit('update-custom-column', {
item,
index,
value: this.showInputValue
})
this.showInput = false
},
// 编辑标签
editTags() {
this.$emit('edit-tags')
},
// 处理评估变更
changeAppraisal(val) {
this.change_appraisal = val
}
}
}
</script>
<style lang="scss" scoped>
.info-tab-content{
width: 100%;
height: 100%;
background: #fff;
}
.userDetailsPanel {
width: 100%;
height: 100%;
background-color: #fff;
border-radius: 4px;
overflow: hidden;
margin-top: 20px;
.detailsTitle {
height: 50px;
padding: 0 20px;
border-bottom: 1px solid #eee;
p {
font-size: 16px;
font-weight: 600;
}
}
.content {
width: 100%;
height: 100%;
overflow-y: auto;
overflow-x: hidden;
.item {
margin-bottom: 15px;
position: relative;
.tableImage {
width: 40px;
height: 40px;
border-radius: 4px;
margin-right: 10px;
}
.label {
color: #999;
margin-right: 5px;
min-width: 60px;
}
.text {
color: #333;
word-break: break-all;
}
.noBind {
color: #00bf8a;
cursor: pointer;
margin-right: 10px;
}
.icon {
cursor: pointer;
margin-left: 10px;
color: #999;
display: none;
}
.tags {
max-width: 200px;
.tagsItem {
margin-bottom: 5px;
.tag {
background-color: #f5f5f5;
color: #666;
padding: 2px 8px;
border-radius: 2px;
margin-right: 5px;
margin-bottom: 5px;
max-width: 100px;
}
}
}
}
.item:hover .icon {
display: block;
}
.tagsLost {
align-items: flex-start;
}
.showInputRemarkInput {
width: 160px;
}
}
}
.hidden {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.rowFlex {
display: flex;
flex-direction: row;
}
.columnFlex {
display: flex;
flex-direction: column;
}
.columnCenter {
align-items: center;
}
.spaceBetween {
justify-content: space-between;
}
.flexWarp {
flex-wrap: wrap;
}
</style>
\ No newline at end of file
<template>
<div class="roleTab">
<el-tabs v-model="roleActive" @tab-click="handleClick">
<el-tab-pane label="角色信息" name="role">
<userInfo v-if="roleActive==='role'" />
</el-tab-pane>
<!-- <el-tab-pane label="举报记录" name="report">
<report v-show="roleActive==='report'" />
</el-tab-pane>
-->
<el-tab-pane label="申诉记录" name="approval">
<approval v-if="roleActive==='approval'" />
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import userInfo from './roleInfo/userInfo.vue'
// import report from './roleInfo/report.vue'
import approval from './roleInfo/approval.vue'
export default {
components: {
userInfo,
approval,
// report
},
props: {
// report_is_send: {
// type: Boolean,
// default: false
// }
},
data() {
return {
roleActive: 'role'
}
},
methods: {
handleClick(value) {
}
}
}
</script>
<style lang="scss" scoped>
.roleTab{
width: 100%;
height: 100%;
background: #fff;
}
</style>
\ No newline at end of file
<template>
<div class="details columnFlex">
<el-form
v-loading="loading"
class="content"
label-width="100px"
>
<div v-if="violationList.length > 0">
<div
v-for="(item, index) in violationList"
:key="index"
class="contentItem"
>
<el-form-item label="违规时间:">
<p>{{ item.violation_time }}</p>
</el-form-item>
<el-form-item label="违规操作:">
<p>{{ item.violation_type_name || "" }}</p>
</el-form-item>
<el-form-item label="封禁时间:">
<p>{{ item.create_time }}</p>
</el-form-item>
<el-form-item label="角色名称:">
<p>{{ item.server_name }} - {{ item.role_name }}</p>
</el-form-item>
<el-form-item label="封禁方式:">
<p :class="item.banned_time_type == 3 ? 'error' : ''">
{{ item.banned_type_text }}
</p>
</el-form-item>
<el-form-item label="是否允许申诉:">
<p class="error">{{ item.appeal_name }}</p>
</el-form-item>
<el-form-item
v-if="item.remake != ''"
label="详情:"
>
<!-- AI自动封禁 -->
<div
class="remarkType"
v-if="item.information_type === 6"
>
<p>
<span class="label">所属项目:</span><span>{{ item.newRemake.project || "" }}</span>
</p>
<p>
<span class="label">角色ID:</span><span>{{ item.newRemake.cp_role_id || "" }}</span>
</p>
<p>
<span class="label">名单类型:</span><span>{{ item.newRemake.list_type || "" }}</span>
</p>
<p>
<span class="label">当前命中:</span><span>{{ item.newRemake.current_hit || "" }}</span>
</p>
<p>
<span class="label">累计命中:</span><span>{{ item.newRemake.hit_total || "" }}</span>
</p>
<p>
<span class="label">释放时间:</span><span>{{ item.newRemake.release_time || "" }}</span>
</p>
<p>
<span class="label">操作用户:</span><span>{{ item.newRemake.handel_user || "" }}</span>
</p>
<p>
<span class="label">备注信息:</span><span>{{ item.newRemake.remark || "" }}</span>
</p>
</div>
<!-- 其他类型 -->
<div
class="remarkType"
v-else
>
<div
v-if="item.remake.indexOf('src=') !== -1"
class="remakeImage"
>
<p class="watchDetails">
<el-button
type="text"
icon="el-icon-view"
size="medium"
style="z-index: 1; position: relative; margin-left: 5px"
@click="showRemake(item.remake)"
>查看大图</el-button>
</p>
<p v-html="item.remake"></p>
</div>
<div
v-else
class="remakeImage"
>
<p v-html="item.remake"></p>
</div>
</div>
</el-form-item>
<div v-if="item && item.newRemake && item.newRemake.hit">
<div
class="title"
style="font-weight: 600; margin-bottom: 10px"
>
命中统计
</div>
<BiTable
:data="item.newRemake.hit"
size="medium"
:column="tableColums"
>
<template v-slot:time="{ row }">
<p>{{ $moment(row.time).format("YYYY-MM-DD HH:mm:ss") }}</p>
</template>
</BiTable>
</div>
</div>
</div>
<div
v-if="!loading && violationList.length == 0"
class="noContent rowFlex allCenter"
>
<noContent title="暂无数据" description="当前没有任何数据,请稍后再试或联系管理员" />
</div>
</el-form>
<el-dialog
title="查看大图"
:visible.sync="imageLayer"
width="50%"
append-to-body
fit="contain"
@close="imageLayer = false"
>
<div
v-html="imageSrc"
class="layerImage"
></div>
</el-dialog>
</div>
</template>
<script>
import { mapState } from "vuex";
import { violationList } from "@/api/game";
import noContent from "@/components/noContent.vue";
import { debounce } from '@/utils'
import watchMember from '@/mixins/watchMember'
export default {
components: {
noContent,
},
data() {
return {
imageSrc: [],
violationList: [],
tableColums: [
{
label: "文本内容",
prop: "content",
},
{
label: "命中类型",
prop: "type",
},
{
label: "关键字",
prop: "key",
},
{
label: "时间",
prop: "time",
width: 120,
slotScope: true
},
],
loading: false,
imageLayer: false,
};
},
computed: {
...mapState("game", ["accountSelect", "gameTabActive"]),
},
mixins: [watchMember],
mounted() {
this.requestViolationList();
},
methods: {
memberChange() {
this.requestViolationList()
},
handleRemark(remark) {
try {
const remarkObj = JSON.parse(JSON.parse(remark.replace(/\r\n\t/g, "")));
console.log(remarkObj, "remarkObj");
return remarkObj;
} catch (error) {
return remark;
}
},
showRemake(remake) {
this.imageSrc = remake;
this.imageLayer = true;
},
requestViolationList() {
const data = {
account_type: 1,
member_id: this.accountSelect,
};
this.loading = true;
violationList(data).then(
(res) => {
if (res.status_code == 1 && res.data.data.length > 0) {
this.violationList = res.data.data;
this.violationList.map((item) => {
if (item.information_type == 6) {
item.newRemake = this.handleRemark(item.remake);
}
});
} else {
this.violationList = [];
}
this.loading = false;
},
(err) => {
this.loading = false;
}
);
},
},
};
</script>
<style lang="scss">
.remakeImage {
img {
max-width: 200px;
height: auto;
border-radius: 5px;
margin-top: 10px;
}
}
.layerImage {
img {
max-width: 800px;
}
}
</style>
<style lang="scss" scoped>
.details {
width:100%;
height: calc(100vh - 150px);
background: #fff;
margin-left: 2px;
.content {
width: 100%;
padding: vw(20);
height: 100%;
overflow: auto;
}
.contentMain {
}
.contentItem {
border-bottom: 1px dashed #ebeef5;
margin-top: 10px;
}
.remarkType {
width: auto;
margin-top: 4px;
p {
line-height: 25px;
}
.label {
color: #99a3b4;
margin-right: 5px;
}
.value {
}
}
.error {
color: #ff5959;
}
.foulImage {
max-width: 300px;
height: auto;
}
::v-deep .el-collapse-item {
margin-bottom: 20px;
}
::v-deep .el-collapse-item__content {
padding-bottom: 10px;
}
::v-deep .el-collapse {
border: none;
}
::v-deep .el-collapse-item__header {
width: 100%;
height: 44px;
background: #f9faff;
color: #333333;
padding-left: 80px;
font-size: 14px;
font-weight: 400;
}
::v-deep .el-form-item {
margin-bottom: 10px;
}
}
.remakeDetails {
::v-deep img {
max-width: 200px;
max-height: 200px;
}
}
</style>
<template>
<el-drawer :lock-scroll="true" :title="title" :visible="show" :size="width" :append-to-body="body" @close="close">
<el-form ref="ruleForm" :model="webForm" label-width="80px" class="uploadLink">
<el-form-item label="手机号">
<el-input v-model="webForm.phone" type="text" maxlength="50" placeholder="请输入手机号"></el-input>
</el-form-item>
</el-form>
<span class="dialog-footer rowFlex">
<el-button class="btn" size="small" type="primary" @click="submit">保 存</el-button>
<el-button class="btn" size="small" @click="close">取 消</el-button>
</span>
</el-drawer>
</template>
<script type="text/javascript">
import { bindMobile } from '@/api/game'
import { mapState } from 'vuex'
export default {
components: {
},
props: ['show', 'width', 'title', 'body', 'phone'],
data() {
return {
webForm: {
phone: ''
}
}
},
computed: {
...mapState('game', ['accountSelect'])
},
watch: {
show(newVal, oldVal) {
if (newVal) {
// this.handleInfo()
this.webForm.phone = this.phone
}
}
},
mounted() {
},
methods: {
close() {
this.$emit('update:show', false)
},
submit() {
if (!/^1((3[0-9])|(4[1579])|(5[0-9])|(6[6])|(7[0-9])|(8[0-9])|(9[0-9]))\d{8}$/.test(this.webForm.phone)) {
this.$message.warning('请填写正确的手机号')
return false
}
const data = {
member_id: this.accountSelect,
mobile: this.webForm.phone
}
bindMobile(data).then((res) => {
if (res.status_code == 1) {
this.$message.success(res.msg)
}
})
this.$emit('update:phone', this.webForm.phone)
this.$emit('update:show', false)
this.$emit('update:phone', this.webForm.phone)
}
}
}
</script>
<style lang="scss" scoped>
.dialog-footer {
width: calc(100% - 20px);
height: 52px;
position: absolute;
right: 20px;
bottom: 20px;
padding-top: 20px;
border-top: 1px solid rgba(0, 0, 0, 0.06);
justify-content: flex-end;
.btn {
width: 84px;
height: 32px;
}
}
.createLink {
position: relative;
top: -8px;
left: 8px;
}
// 添加网页
.uploadLink {
padding:20px;
}
</style>
\ No newline at end of file
<template>
<div>
<div class="item rowFlex columnCenter spaceBetween zyouTag">
<div class="rowFlex columnCenter">
<span class="label">掌游标签:</span>
<i
:class="['el-icon-arrow-' + (showZyouTag ? 'down' : 'right'), 'tag-icon']"
@click="toggleZyouTag"
></i>
</div>
</div>
<!-- 掌游标签列表 -->
<div v-if="showZyouTag" class="zyou-tag-list">
<div v-for="(item, index) in roleLabelList" :key="index" class="tag-group">
<div class="tag-group-header">
<div class="tag-type-name">{{ item.label_type_name }}</div>
<i v-if="item.label_type ==2" class="el-icon-circle-plus" style="color: var(--el-color-primary)" @click="toggleAddTag(index)"></i>
</div>
<!-- 新增标签区域 -->
<div v-if="showAddTagIndex === index" class="add-tag-area">
<div class="add-tag-content">
<el-cascader
v-model="searchValue"
:options="searchOptions"
collapse-tags
filterable
:props="{
multiple: true,
value: 'label_id',
label: 'label_name',
children: 'children',
emitPath: false,
disabled: 'disabled',
}"
clearable
placeholder="请选择掌游标签"
class="tag-select"
@change="handleCascaderChange"
></el-cascader>
<div class="button-group">
<el-button type="text" size="small" @click="handleSelectChange(searchValue)">确定</el-button>
<el-button type="text" size="small" @click="toggleAddTag(-1)">取消</el-button>
</div>
</div>
</div>
<div class="tag-list">
<el-popover
v-for="tag in item.label"
:key="tag.id"
placement="top"
width="250px"
trigger="click"
@show="getTagCreateInfo(tag.id)"
>
<div style="height: 50px;">
<div v-if="tagInfo.create_user" class="tag-info-item">
<span class="tag-info-label">操作人:</span>
<span class="tag-info-value">{{ tagInfo.create_user }}</span>
</div>
<div v-if="tagInfo.create_time" class="tag-info-item">
<span class="tag-info-label">操作时间:</span>
<span class="tag-info-value">{{ tagInfo.create_time }}</span>
</div>
</div>
<el-tag slot="reference" class="tag-item">
<span v-if="tag.label_group_name">{{ tag.label_group_name || '' }} / </span>
<span>{{ tag.label_name || '' }}</span>
</el-tag>
</el-popover>
</div>
</div>
</div>
</div>
</template>
<script>
import { editRoleLabel, roleGetRoleLabel, roleLabelSearch, selectSearch, getRoleLabelCreate } from '@/api/game'
import { mapState,mapActions } from 'vuex'
import { debounce } from '@/utils'
export default {
name: 'ZyouTag',
props: {
accountSelect: {
type: [String, Number],
default: ''
},
gameUserInfo: {
type: Object,
default: () => ({})
}
},
data() {
return {
showZyouTag: false, // 控制标签显示隐藏
roleLabelList: [], // 角色标签列表
showAddTagIndex: -1, // 当前显示新增标签的索引
searchValue: '', // 搜索框的值
searchOptions: [], // 搜索选项
labelTypeList: [], // 标签类型列表
loading: false, // 加载状态
tagInfo: {} // 标签创建信息
}
},
computed: {
...mapState('user', ['cser_id','cser_name','corp_id','weixin_blongs_id_list']),
},
watch: {
accountSelect: {
handler(newVal) {
if (newVal) {
this.getRoleLabelList()
}
},
immediate: true
}
},
async mounted() {
await this.requestCompanyviewConfig({corp_id:this.corp_id})
this.getLabelType()
this.getRoleLabelList()
this.searchLabel('')
},
methods: {
...mapActions('user', ['requestCompanyviewConfig']),
// 获取标签类型
async getLabelType() {
try {
const res = await selectSearch({
type: 'label_type'
})
if (res.status_code === 1) {
console.log('getLabelType')
this.labelTypeList = res.data.data || []
}
} catch (error) {
console.error('获取标签类型失败:', error)
}
},
getRoleLabelList: debounce(function() {
this.getRoleLabelListFn()
}, 500),
// 获取角色标签列表
async getRoleLabelListFn() {
console.log('延迟')
if (!this.accountSelect) return
this.loading = true
try {
const weixin_blongs_id = this.weixin_blongs_id_list.map(item => item.value)
const res = await roleGetRoleLabel({
member_id: this.accountSelect,
weixin_blongs_id: weixin_blongs_id
})
if (res.status_code === 1 && res.data.data.length > 0) {
const labelData = res.data.data || []
const groupedLabels = {}
labelData.forEach(item => {
if (item.label && item.label.length > 0) {
item.label.forEach(label => {
label.label_type = Number(item.label_type)
})
}
})
// 初始化标签组
this.labelTypeList.forEach(type => {
groupedLabels[type.value] = {
label_type: type.value,
label_type_name: type.label,
label: []
}
})
// 分组标签数据
labelData.forEach(item => {
if (item.label && item.label.length > 0) {
const labelType = item.label[0].label_type
if (groupedLabels[labelType]) {
groupedLabels[labelType].label = item.label
}
}
})
// 转换为数组格式
this.roleLabelList = Object.values(groupedLabels)
console.log(this.roleLabelList, 'roleLabelList')
} else {
this.roleLabelList = this.labelTypeList.map(item => {
return {
label_type: item.value,
label_type_name: item.label,
label: []
}
})
}
} catch (error) {
console.error('获取角色标签列表失败:', error)
} finally {
this.loading = false
}
},
// 搜索标签
async searchLabel(query) {
try {
const weixin_blongs_id = this.weixin_blongs_id_list.map(item => item.value)
const res = await roleLabelSearch({
label_name: query.trim() || '',
weixin_blongs_id: weixin_blongs_id || [],
label_type: 2
})
if (res.status_code === 1) {
this.searchOptions = res.data.data || []
// 找出 label_group_id 相同的 然后 把 children 合并
const groupedItems = this.searchOptions.reduce((acc, curr) => {
const key = curr.label_group_id
if (!acc[key]) {
acc[key] = {
label_name: curr.label_group_name,
label_id: curr.label_group_id,
select_type: Number(curr.select_type),
children: []
}
}
// 将标签添加到对应标签组的children中
acc[key].children.push({
label_name: curr.label_name,
label_id: curr.id,
disabled: false // 默认不禁用
})
return acc
}, {})
// 处理单选标签组,为已选中项以外的选项添加disabled属性
Object.values(groupedItems).forEach(group => {
if (group.select_type === 1) {
// 如果是单选标签组,需要禁用其他选项
const selectedIds = Array.isArray(this.searchValue) ? this.searchValue : []
const hasSelectedInThisGroup = group.children.some(child =>
selectedIds.includes(child.label_id)
)
if (hasSelectedInThisGroup) {
group.children.forEach(child => {
// 如果当前选项不在已选中列表中,则禁用
if (!selectedIds.includes(child.label_id)) {
child.disabled = true
}
})
}
}
})
this.searchOptions = Object.values(groupedItems)
}
} catch (error) {
console.error('搜索标签失败:', error)
}
},
// 添加标签
async addLabel(selectedLabels) {
console.log(selectedLabels, 'selectedLabels')
const labelId = selectedLabels.map(label => label.label_id)
if (!this.accountSelect || !labelId) {
this.$message.error('请选择标签')
return
}
if (!this.gameUserInfo || !this.gameUserInfo.role_info || !this.gameUserInfo.role_info.role_id) {
this.$message.error('该账号未创角无法添加标签')
return
}
try {
const res = await editRoleLabel({
role_id: this.gameUserInfo.role_info.role_id || '',
member_id: this.accountSelect,
label_id: labelId,
user_id: this.cser_id,
user_name: this.cser_name,
role_name: this.gameUserInfo.role_info.role_name || '',
cp_role_id: this.gameUserInfo.role_info.cp_role_id || ''
})
if (res.status_code === 1) {
this.$message.success(res.msg)
this.searchValue = ''
this.showAddTagIndex = -1
// 暂时隐藏
// this.roleLabelList[1].label.push(...selectedLabels)
// 重置所有标签的禁用状态
this.searchOptions.forEach(group => {
if (group.children) {
group.children.forEach(child => {
child.disabled = false
})
}
})
// 刷新标签列表
setTimeout(() => {
this.getRoleLabelList()
}, 500)
}
} catch (error) {
console.error('添加标签失败:', error)
}
},
// 切换标签显示
toggleZyouTag() {
this.showZyouTag = !this.showZyouTag
},
// 切换新增标签区域显示
toggleAddTag(index) {
this.showAddTagIndex = this.showAddTagIndex === index ? -1 : index
if (this.showAddTagIndex === -1) {
this.searchValue = ''
// this.searchOptions = []
}
},
// 选择标签
handleSelectChange(value) {
if (value && Array.isArray(value) && value.length > 0) {
// 获取当前标签组的标签
const currentGroupLabels = this.roleLabelList.find(item => Number(item.label_type) === 2).label
// 获取所有选中标签的信息
const selectedLabels = []
// 遍历所有标签组
this.searchOptions.forEach(group => {
// 找出该组中被选中的标签
const selectedInGroup = group.children.filter(child =>
value.includes(child.label_id)
)
// 如果是单选标签组且选中了多个,只保留第一个
if (group.select_type === 1 && selectedInGroup.length > 1) {
this.$message.warning(`标签组"${group.label_name}"为单选,只能选择一个标签`)
// 只添加第一个选中的标签
selectedLabels.push(selectedInGroup[0])
} else {
// 多选标签组或单选标签组只选了一个,全部添加
selectedLabels.push(...selectedInGroup)
}
})
if (!selectedLabels || selectedLabels.length === 0) {
this.$message.warning('请选择有效的标签')
return
}
// 检查selectedLabels中的标签组是否与currentGroupLabels中的标签组重复
if (currentGroupLabels && currentGroupLabels.length > 0) {
const existingGroupIds = currentGroupLabels.map(label => label.label_group_id)
const hasConflict = selectedLabels.some(label =>
existingGroupIds.includes(label.label_group_id)
)
if (hasConflict) {
this.$message.warning('一标签组下只能选择一个标签')
return
}
this.addLabel(selectedLabels)
} else {
this.addLabel(selectedLabels)
}
} else {
this.$message.warning('请选择标签')
}
},
// 处理级联选择器选择变化
handleCascaderChange(value) {
// 每次选择变化时,重新处理searchOptions
// 重置所有选项的disabled状态
this.searchOptions.forEach(group => {
if (group.children) {
group.children.forEach(child => {
child.disabled = false
})
}
})
if (Array.isArray(value) && value.length > 0) {
// 检查是否有全选操作
const prevValue = [...this.searchValue || []]
// 找出所有单选标签组
const singleSelectGroups = this.searchOptions.filter(group => group.select_type === 1)
// 检查单选标签组是否有全选操作
for (const group of singleSelectGroups) {
// 获取当前组中的所有标签ID
const groupLabelIds = group.children.map(child => child.label_id)
// 检查当前组中选中的标签数量
const selectedInThisGroup = groupLabelIds.filter(id => value.includes(id))
// 如果选中的标签数量大于1,说明可能是全选操作
if (selectedInThisGroup.length > 1) {
// 提示用户只能选择一个标签
this.$message.warning(`标签组"${group.label_name}"为单选,只能选择一个标签`)
// 清空该组的选择
const newValue = value.filter(id => !groupLabelIds.includes(id))
// 更新选择值
this.searchValue = newValue
return
}
// 如果该单选标签组有选中的标签,则禁用其他标签
if (selectedInThisGroup.length === 1) {
group.children.forEach(child => {
if (!value.includes(child.label_id)) {
child.disabled = true
}
})
}
// 如果没有选中的标签,则不需要禁用任何标签,已经在前面重置了
}
}
// 如果没有选中任何标签,所有标签都应该是可选的,已经在前面重置了123
},
// 获取标签创建信息
async getTagCreateInfo(id) {
this.tagInfo = {}
try {
const res = await getRoleLabelCreate({
id: id
})
if (res.status_code === 1) {
this.tagInfo = res.data.data || {}
} else {
this.$message.error(res.msg || '获取标签信息失败')
}
} catch (error) {
console.error('获取标签创建信息失败:', error)
this.$message.error('获取标签信息失败')
}
}
}
}
</script>
<style lang="scss" scoped>
.item {
width: 100%;
height: auto;
font-size: 14px;
padding: 16px;
font-weight: 400;
color: #333333;
padding: 10px 0;
transition: all 0.5s;
position: relative;
cursor: pointer;
.label {
font-size: 14px;
color: #999999;
font-weight: 500;
margin-right: 8px;
}
.tag-icon {
cursor: pointer;
font-size: 14px;
color: #333333;
margin-right: 8px;
}
}
.zyou-tag-list {
.tag-group {
margin-bottom: 10px;
padding: 10px;
padding-top: 0;
width: 100%;
background: #F7F8FA;
border-radius: 4px;
&:last-child {
margin-bottom: 0;
}
.tag-group-header {
display: flex;
justify-content: space-between;
align-items: center;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
text-align: left;
padding-top:10px;
margin-bottom: 10px;
.tag-type-name {
font-size: 14px;
color: #323335;
font-weight: 500;
}
.el-icon-circle-plus{
font-size: 16px;
cursor: pointer;
color: #00bf8a !important;
}
}
.tag-list {
.el-tag {
font-size: 12px;
color: #323335;
background-color: #fff;
border-radius: 4px;
border: 1px solid #D6D9E0;
margin-bottom: 5px;
}
}
.add-tag-area {
margin: 10px 0;
background: #f5f7fa;
border-radius: 4px;
.add-tag-content {
gap: 12px;
.tag-select {
width: 100%;
}
.button-group {
display: flex;
justify-content: flex-end;
}
}
}
}
}
.tag-icon {
margin-left: 8px;
cursor: pointer;
color: #909399;
&:hover {
color: #409EFF;
}
}
.tag-info-item {
margin-bottom: 8px;
font-size: 12px;
.tag-info-label {
color: #909399;
margin-right: 2px;
}
.tag-info-value {
color: #333;
font-weight: 500;
}
}
</style>
\ No newline at end of file
<template>
<div class="gameUserDetails">
<!-- 智能标签 -->
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label" style="min-width:60px;">智能标签:</span>
<p class="text">
<el-tag v-for="(item,index) in chatUserDetails.intelligence_tag_group" :key="index" style="margin-right:5px;margin-bottom:5px;">{{ item.name }} </el-tag>
</p>
</div>
<el-popover
placement="top"
trigger="hover"
content="手动更新当前用户的智能标签,每个用户半个小时仅能更新一次"
>
<i
slot="reference"
class="el-icon-refresh refreshList"
:class="isRefresh?'refreshListActive':''"
@click="refreshTag"
></i>
</el-popover>
</div>
<ZyouTag :game-user-info="gameUserInfo" :account-select="accountSelect" />
<div v-if="accountSelect && accountSelect!=='' && gameUserInfo.username">
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">账号:</span>
<p class="text">{{ gameUserInfo.username }}</p> <span v-if="gameUserInfo.account_type==2" class="account_type"></span>
</div>
</div>
<!-- 充值金额 -->
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">充值金额:</span>
<p class="text">{{ gameUserInfo.real_recharge_total }}</p>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">是否易主:</span>
<p class="text">{{ change_user==1?'是':'否' }}</p>
<el-popconfirm
confirm-button-text="确定"
cancel-button-text="取消"
icon="el-icon-info"
title="是否切换易主状态"
@confirm="changeUserFn"
>
<!-- changeUser -->
<div slot="reference" class="rowFlex columnCenter changeUser">
<p>
<i class="el-icon-sort-down"></i>
</p>
<p>
<i class="el-icon-sort-up"></i>
</p>
</div>
</el-popconfirm>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">白名单:</span>
<p class="text">{{ change_name==1?'是':'否' }}</p>
<el-popconfirm
confirm-button-text="确定"
cancel-button-text="取消"
icon="el-icon-info"
title="是否切换白名单状态"
@confirm="changeNameFn"
>
<div slot="reference" class="rowFlex columnCenter changeUser">
<p>
<i class="el-icon-sort-down"></i>
</p>
<p>
<i class="el-icon-sort-up"></i>
</p>
</div>
</el-popconfirm>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">异常账号:</span>
<p class="text">{{ change_risk==1?'是':'否' }}</p>
<el-popconfirm
confirm-button-text="确定"
cancel-button-text="取消"
icon="el-icon-info"
title="是否切换账号异常状态"
@confirm="changeRiskFn"
>
<div v-if="change_risk==0" slot="reference" class="rowFlex columnCenter changeUser">
<p>
<i class="el-icon-sort-down"></i>
</p>
<p>
<i class="el-icon-sort-up"></i>
</p>
</div>
</el-popconfirm>
</div>
</div>
<div v-if="gameUserInfo.role_info && gameUserInfo.role_info.role_level " class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">等级:</span>
<p class="text">{{ gameUserInfo.role_info.role_level }}</p>
</div>
</div>
<div v-if="gameUserInfo.role_info && gameUserInfo.role_info.trans_check_status_text " class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">转端审核:</span>
<p class="text">{{ gameUserInfo.role_info.trans_check_status_text }}</p>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">近期是否被封禁:</span>
<p class="text">{{ gameUserInfo.is_banned==1?'是':'否' }}</p>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">真实姓名:</span>
<p class="text">{{ gameUserInfo.real_name }}</p>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">CP角色ID:</span>
<p v-if="gameUserInfo.role_info && gameUserInfo.role_info.cp_role_id" class="text">{{ gameUserInfo.role_info.cp_role_id }}</p>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">是否愿意转端:</span>
<p class="text">
<el-radio-group v-model="chatUserDetails.transferred" @change="toTransfer">
<el-radio :label="0"></el-radio>
<el-radio :label="1"></el-radio>
</el-radio-group>
</p>
</div>
</div>
<div class="item rowFlex columnCenter">
<div class="rowFlex columnCenter">
<span class="label">手机号:</span>
<p v-if="!showUserMobile" class="text">{{ gameUserInfo.mobile }}</p>
</div>
<el-input v-if="showUserMobile" v-model="newMobileValue" style="width: 120px; margin-left: 10px" @change="changeUserMobile" @blur="showUserMobile = false"></el-input>
<!-- 暂时禁止用户修改手机号 -->
<i class="el-icon-edit icon" style="font-size: 14px" @click="editUserMobile"></i>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">注册游戏:</span>
<p class="text">{{ gameUserInfo.reg_game_name }}</p>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">主游戏:</span>
<p class="text">{{ gameUserInfo.main_game_name }}</p>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">登录系统:</span>
<p class="text">{{ gameUserInfo.last_login_os }}</p>
</div>
</div>
<div v-if="gameUserInfo.service_wechat_number_info && gameUserInfo.service_wechat_number_info.length>0" class="item rowFlex columnCenter spaceBetween">
<div class="columnFlex " style="width:100%;">
<span class="label">客服微信号:</span>
<div v-for="(item,index) in gameUserInfo.service_wechat_number_info" :key="index" class="rowFlex columnCenter " style="margin-top:10px;width:100%;">
<p class="hidden wxName">{{ item.service_wechat_number_name }}({{ item.service_type_name }})</p>
<span class="bradge">{{ item.type_name }}</span>
<div class="colorStatus rowFlex columnCenter" style="margin-left: 10px;">
<span v-if="item.loss_status==1" class="fail">{{ item.loss_status_text }}</span>
</div>
</div>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">注册时间:</span>
<p class="text">{{ moment(gameUserInfo.reg_time * 1000).format('YYYY-MM-DD') }}</p>
</div>
</div>
</div>
</div>
</template>
<script>
import { bindMobile, getMemberLabel, editMemberLabel } from '@/api/game'
import { mapState, mapMutations } from 'vuex'
import { toTransfer, syncSessionIntelTag } from '@/api/works'
import moment from 'moment'
import ZyouTag from './ZyouTag.vue'
import { debounce } from '@/utils'
export default {
components: {
ZyouTag
},
props: ['gameUserInfo', 'chatUserDetails'],
data() {
return {
moment,
showUserMobile: false,
change_user: 0,
change_name: 0,
change_risk: 0,
change_appraisal: 0,
newMobileValue: '',
isRefresh: false,
showWxNumber: true
}
},
computed: {
...mapState('game', ['accountSelect'])
},
watch: {
accountSelect: {
handler:debounce(function(newVal, oldVal) {
if (newVal && newVal !== "" && newVal !== oldVal) {
this.getMemberLabel()
}
},200),
immediate: false
}
},
mounted() {
this.$nextTick(() => {
if (this.accountSelect && this.accountSelect !== '') {
this.getMemberLabel()
}
})
},
methods: {
getMemberLabel() {
const data = {
member_id: this.accountSelect,
label_type: [2, 3, 4, 6]
}
getMemberLabel(data).then(res => {
if (res?.data?.data?.length > 0) {
const change_user = res.data.data.find(item => item.label_type == 2)
const change_name = res.data.data.find(item => item.label_type == 3)
const change_risk = res.data.data.find(item => item.label_type == 4)// 风险用户
const change_appraisal = res.data.data.find(item => item.label_type == 6)// 石锤用户
this.change_user = change_user.label_value
this.change_name = change_name.label_value
this.change_risk = change_risk.label_value
this.change_appraisal = change_appraisal.label_value
this.$emit('changeAppraisal', this.change_appraisal)
} else {
this.change_user = 0
this.change_name = 0
this.change_risk = 0
this.change_appraisal = 0
this.$emit('changeAppraisal', this.change_appraisal)
}
})
},
// 白名单
changeNameFn() {
const data = {
member_id: this.accountSelect,
create_user: this.cser_name,
label_type: 3,
label_value: this.change_name == 1 ? 0 : 1
}
editMemberLabel(data).then((res) => {
if (res.status_code == 1) {
this.$message.success(res.msg)
this.change_name == 1 ? this.change_name = 0 : this.change_name = 1
}
this.$emit('update:show', false)
})
},
// 异常账号
changeRiskFn() {
const data = {
member_id: this.accountSelect,
create_user: this.cser_name,
label_type: 4,
label_value: this.change_risk == 0 ? 1 : 0
}
editMemberLabel(data).then((res) => {
if (res.status_code == 1) {
this.$message.success(res.msg)
this.change_risk == 1 ? this.change_risk = 0 : this.change_risk = 1
}
this.$emit('update:show', false)
})
},
changeUserFn() {
const data = {
member_id: this.accountSelect,
create_user: this.cser_name,
label_type: 2,
label_value: this.change_user == 1 ? 0 : 1
}
editMemberLabel(data).then((res) => {
if (res.status_code == 1) {
this.$message.success(res.msg)
this.change_user == 1 ? this.change_user = 0 : this.change_user = 1
}
this.$emit('update:show', false)
})
},
toTransfer() {
const data = {
external_userid: this.chatUserDetails.external_userid,
userid: this.chatUserDetails.userid,
transferred: this.chatUserDetails.transferred
}
toTransfer(data).then(res => {
if (res.status_code == 1) {
this.$message.success(res.msg)
}
})
},
// 修改用户手机号
changeUserMobile() {
if (!/^1((3[0-9])|(4[1579])|(5[0-9])|(6[6])|(7[0-9])|(8[0-9])|(9[0-9]))\d{8}$/.test(this.newMobileValue)) {
this.$message.warning('请填写正确的手机号')
return false
}
this.gameUserInfo.mobile = this.newMobileValue.substr(0, 3) + '****' + this.newMobileValue.substr(7)
this.showUserMobile = false
const data = {
member_id: this.accountSelect,
mobile: this.newMobileValue
}
bindMobile(data).then((res) => {
if (res.status_code == 1) {
this.$message.success(res.msg)
}
})
},
editUserMobile() {
this.showUserMobile = true
},
async refreshTag() {
this.isRefresh = true
const data = {
corp_id: this.chatUserDetails.corp_id,
userid: this.chatUserDetails.userid,
external_userid: this.chatUserDetails.external_userid
}
try {
const res = await syncSessionIntelTag(data)
if (res.status_code === 1) {
if (res.data.is_can_sync == 1) {
this.$message.success(res.msg)
this.$set(this.chatUserDetails, 'intelligence_tag_group', res.data.intel_tag)
} else {
this.$message.warning('每个用户半个小时仅能更新一次')
}
}
} catch (error) {
this.isRefresh = false
} finally {
this.isRefresh = false
}
}
}
}
</script>
<style lang="scss" scoped>
.gameUserDetails {
width: 100%;
.changeUser{
font-size: 18px;
transform: rotate(90deg);
color: #00bf8a;
margin-left: 10px;
margin-top: -3px;
:first-child{
margin-right: -5px;
}
}
.item {
width: 100%;
height: auto;
font-size: 14px;
font-weight: 400;
color: #333333;
padding: 10px 0;
transition: all 0.5s;
position: relative;
cursor: pointer;
.tableImage {
width: 40px;
height: 40px;
border-radius: 6px;
margin-right: vw(10);
}
.wxName{
max-width: 80%;
}
.bradge{
padding: 2px 5px;
border-radius: 3px;
background: #f4f4f5;
color: #909399;
margin-left: 10px;
}
.showInputRemarkInput {
width: vw(220);
margin-left: 10px;
}
.label {
color: #999999;
}
.text {
color: #333333;
margin-left: 3px;
word-break: break-all;
max-width: calc(100% - 20px);
}
.icon {
display: none;
position: absolute;
right: 0;
top: 12px;
}
.noBind {
width: 44px;
height: 22px;
border-radius: 4px;
border: 1px solid #00bf8a;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #00bf8a;
margin-left: 30px;
cursor: pointer;
}
.tags {
width: vw(300);
margin-left: 10px;
.tagsItem {
width: vw(300);
}
.tag {
height: 22px;
line-height: 22px;
padding: 0 8px;
background: #ffffff;
border-radius: 4px;
border: 1px solid rgba(0, 0, 0, 0.2);
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #333333;
margin-right: 10px;
margin-bottom: 10px;
}
}
}
.item:hover .icon {
display: block;
}
}
.refreshList {
color: #00bf8a;
cursor: pointer;
font-size: 18px;
}
.refreshListActive{
animation:rotate 0.5s linear infinite ;
}
@keyframes rotate {
0%{
transform: rotate(0deg);
}
100%{
transform: rotate(360deg);
}
}
</style>
\ No newline at end of file
<template>
<el-drawer
:lock-scroll="true"
title="玩家申诉"
:visible="show"
size="400px"
:append-to-body="true"
@close="close"
>
<div class="drawer-content">
<el-form
ref="appealForm"
:model="appealForm"
:rules="appealRules"
label-position="top"
class="appealForm"
label-width="100px"
>
<el-form-item
label="主游戏"
prop="main_game_id"
>
<mainGameSelect
label=""
:default-value="appealForm.main_game_id"
style="width: 100%"
width="100%"
@result="mainGameResult"
/>
</el-form-item>
<el-form-item label="">
<el-radio-group v-model="appealForm.role_id_type">
<el-radio label="cp_role_id">CP角色ID</el-radio>
<el-radio label="role_id">掌游角色ID</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="CP角色ID" prop="cp_role_id">
<el-input
v-model="appealForm.cp_role_id"
style="width: 100%"
placeholder="请输入CP角色ID"
@change="change_cp_role_id"
></el-input>
</el-form-item>
<el-form-item
label="角色名"
prop="role_name"
>
<el-input
v-model="appealForm.role_name"
placeholder="请先选择主游戏和输入CP角色ID"
disabled
></el-input>
</el-form-item>
<el-form-item
label="区服"
prop="server_name"
>
<el-input
v-model="appealForm.server_name"
placeholder="请先选择主游戏和输入CP角色ID"
disabled
></el-input>
</el-form-item>
<el-form-item
label="申诉类型"
prop="appeal_type"
>
<el-select
v-model="appealForm.appeal_type"
style="width:100%;"
clearable
placeholder="请选择"
>
<el-option
v-for="item in appeal_type_list"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item
label="详情"
prop="content"
style="margin-top:-10px;"
>
<textEditor
:remark.sync="appealForm.remark"
domid="appeal_content"
:contenteditable="true"
@resultReamrk="resultReamrk"
/>
</el-form-item>
</el-form>
<span class="dialog-footer rowFlex">
<el-button
class="btn"
type="primary"
:loading="loading"
@click="submit"
>确 定</el-button>
<el-button
class="btn"
@click="close"
>取 消</el-button>
</span>
</div>
</el-drawer>
</template>
<script type="text/javascript">
import textEditor from '@/components/textEditor.vue'
import { searchcondition, appealAdd } from '@/api/game'
import { mapState } from 'vuex'
import mainGameSelect from '@/components/mainGame.vue'
export default {
components: {
textEditor,
mainGameSelect
},
computed: {
...mapState('user', ['cser_id','cser_name'])
},
props: ['show', 'appealInfo'],
data() {
return {
appealRules: {
main_game_id: [
{ required: true, message: '请选择主游戏', trigger: 'change' }
],
cp_role_id: [
{ required: true, message: '请选择cp角色id', trigger: 'change' }
],
role_id: [
{ required: true, message: '请选择角色名', trigger: 'change' }
],
server_info: [
{ required: true, message: '请选择区服', trigger: 'change' }
],
appeal_type: [
{ required: true, message: '请选择违规操作', trigger: 'change' }
]
},
appealForm: {
main_game_id: '',
role_id_type: 'cp_role_id',
role_id: '',
cp_role_id: '',
appeal_type: '',
remark: '',
role_name: '',
server_name: '',
user_id: '',
user_name: ''
},
appeal_type_list: [],
loading: false,
serverNameList: []
}
},
mounted() {
this.searchcondition()
if (this.appealInfo && this.appealInfo.id) {
const {
appeal_type = '',
remark = '',
role_id = ''
} = this.appealInfo
this.appealForm.appeal_type = Number(appeal_type)
this.appealForm.remark = remark
}
},
methods: {
searchcondition() {
const data = {
type: 'dictionaries',
table_name: 'zs_appeal_request',
field_name: 'appeal_type'
}
searchcondition(data).then(res => {
this.appeal_type_list = res.data.data
})
},
async change_cp_role_id() {
if (
!!this.appealForm.cp_role_id &&
!!this.appealForm.main_game_id
) {
const loading = this.$message.warning('查找角色中,请稍等')
const res = await searchcondition({
type: 'role',
cp_role_id: this.appealForm.cp_role_id,
main_game_id: this.appealForm.main_game_id
})
if (res.status_code == 1 && res.data.data.length > 0) {
this.appealForm.role_id = res.data.data[0]
? res.data.data[0].value
: ''
this.appealForm.role_name = res.data.data[0]
? res.data.data[0].label
: ''
this.appealForm.server_name = res.data.data[0]
? res.data.data[0].server_name
: ''
loading.close()
} else {
this.$message.warning('角色信息不存在')
loading.close()
}
} else {
this.$message.warning('请先选择主游戏')
this.appealForm.cp_role_id = ''
}
},
mainGameResult(data) {
this.appealForm.main_game_id = data
this.appealForm.cp_role_id = ''
this.appealForm.role_id = ''
this.appealForm.role_name = ''
this.appealForm.server_name = ''
},
resultReamrk(text) {
// console.log(text, '最后编辑器的内容')
},
close() {
this.$emit('update:show', false)
},
submit() {
this.$refs['appealForm'].validate(async valid => {
if (valid) {
this.loading = true
await this.appealAdd()
} else {
return false
}
})
},
async appealAdd() {
const { role_id, appeal_type, remark, main_game_id, cp_role_id, role_name, server_name, role_id_type } = this.appealForm
const data = {
user_id: this.cser_id,
user_name: this.cser_name,
role_id,
appeal_type,
remark,
main_game_id,
cp_role_id,
role_name,
role_id_type,
server_name
}
try {
const res = await appealAdd(data)
if (res.status_code === 1) {
this.$message.success(res.msg)
this.close()
this.$emit('updateReportList')
}
this.loading = false
} catch (error) {
this.loading = false
}
setTimeout(() => {
this.loading = false
}, 2000)
}
}
}
</script>
<style lang="scss" scoped>
// ::v-deep .el-drawer {
// height: 100%;
// overflow: auto;
// overflow-x: hidden;
// }
.drawer-content {
width: 100%;
height: 100%;
overflow: auto;
padding: 20px;
padding-bottom: 100px;
margin-top: -20px;
}
.dialog-footer {
width: 100%;
height: auto;
position: absolute;
right: 0px;
bottom: 0px;
padding-right: 10px;
padding-top: 20px;
padding-bottom: 20px;
border-top: 1px solid rgba(0, 0, 0, 0.06);
justify-content: flex-end;
background: #fff;
.btn {
width: 84px;
height: 32px;
}
}
</style>
\ No newline at end of file
<template>
<div class="approval-role-list columnFlex">
<el-form ref="taskForm" :model="reportForm" class="taskForm" label-width="85px">
<el-form-item label="角色名称">
<el-input
v-model="reportForm.role_name"
style="width:95%;"
clearable
placeholder="请输入角色名称"
@change="filterChange"
>
</el-input>
</el-form-item>
<el-form-item label="审批状态">
<el-select
v-model="reportForm.approval_status"
style="width:95%;"
clearable
placeholder="请选择审批状态"
@change="filterChange"
>
<el-option v-for="item in approvalList" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="申请方式">
<el-select
v-model="reportForm.register_type"
style="width:95%;"
clearable
placeholder="请选择申请方式"
@change="filterChange"
>
<el-option
v-for="item in register_type_list"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="时间范围">
<BiDatePicker
v-model="reportForm.create_time"
style="width: 95%"
type="datetimerange"
format="yyyy-MM-dd HH:mm:ss"
:picker-option="pickerOptions"
value-format="yyyy-MM-dd HH:mm:ss"
:default-time="['00:00:00', '23:59:59']"
:clearable="false"
range-separator="~"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="createResult"
/>
</el-form-item>
</el-form>
<div
v-infinite-scroll="paperScroll"
:infinite-scroll-disabled="!isMoreRecord"
:infinite-scroll-immediate="false"
class="mailListScroll"
>
<!-- 举报申请 -->
<div class="scrollMain">
<div v-for="(item, index) in reportList" :key="index" class="reportContent" @click="appealProcess(item, index)">
<div class="reportItem rowFlex columnCenter spaceBetween">
<div class="reportItemLeft">
<p><span class="label">角色名称:</span><span class="value">{{ item.role_name }}</span></p>
<div class="rowFlex spaceBetween columnCenter">
<p>
<span class="label">累计充值:</span><span class="value">{{ formatNumber(item.recharge_total_amount) }}
</span>
</p>
</div>
<p>
<span class="label">近一周充值:</span><span class="value">{{ formatNumber(item.recharge_week_amount)
}}</span>
</p>
<p><span class="label">违规操作:</span><span class="value">{{ item.appeal_type_text }}</span></p>
</div>
<div class="reportItemRight columnFlex columnCenter">
<el-button
v-if="item.approval_status == 1 && (item.customer_id == userInfo.id)"
type="primary"
size="mini"
style="margin-bottom:15px;"
@click.stop="handleReport(item)"
>撤销</el-button>
<el-button
v-else-if="item.approval_status == 4"
type="primary"
size="mini"
style="margin-bottom:15px;"
@click.stop="resubmitApproval(item)"
>重新提交</el-button>
<img v-if="item.approval_status == 1" :src="shenpi1" class="icon" />
<img v-else-if="item.approval_status == 2" :src="shenpi2" class="icon" />
<img v-else-if="item.approval_status == 3" :src="shenpi3" class="icon" />
<img v-else-if="item.approval_status == 4" :src="shenpi4" class="icon" />
<img v-else-if="item.approval_status == 5" :src="shenpi5" class="icon" />
</div>
</div>
<!-- 审批进度 -->
<el-collapse-transition>
<div v-if="item.showStep" class="appealProcessList">
<el-steps direction="vertical" :active="item.current" finish-status="success">
<el-step
v-for="(items, indexs) in item.appealProcessList"
:key="'trans_item_' + indexs"
:title="items.node_name"
>
<template slot="description">
<div v-if="items" class="trans-follow-1 card-style">
<div class="follow-item">
<span class="follow-info-label label-font">
{{ items.node_sort !== '0' ? '审批人:' : '登记人:' }}
</span>
<span class="info-value value-font">
{{ Array.isArray(items.user_name) ? items.user_name[0] : items.user_name }}
</span>
<el-tooltip
v-if="Array.isArray(items.user_name) && items.user_name.length > 1"
class="item"
effect="dark"
:content="items.user_name.slice(1).join('、')"
placement="top"
>
<span class="info-value value-font info-value-color">
{{ `+${items.user_name.length - 1}` }}
</span>
</el-tooltip>
</div>
<div v-if="items.node_sort !== '0' || item.node_name === '系统'" class="follow-item">
<span class="follow-info-label label-font">
审批结果:
</span>
<span
class="info-value value-font"
:class="[items.current < indexs ? '' : switchStateTag(items.approval_result)]"
>
{{ items.current < indexs ? '' : items.approval_result_text }}
</span>
</div>
<div class="follow-item">
<span class="follow-info-label label-font">
{{ (items.node_sort !== '0' || items.node_name === '系统') ? '审批时间:' : '登记时间:' }}
</span>
<span class="info-value value-font">
{{ items.node_sort === '0' ? items.create_time : items.update_time }}
</span>
</div>
<div
v-if="(items.node_sort !== '0' || items.node_name === '系统') && items.approval_result==='2'"
class="follow-item"
>
<span class="follow-info-label label-font">
驳回原因:
</span>
<span class="info-value value-font">
{{ items.extra_attribution.remark }}
</span>
</div>
<!-- <div
v-if="items.node_sort === item.appealProcessList[item.appealProcessList.length - 1 ].node_sort+ '' && items.approval_result === '1' && items.node_sort !== '0'"
class="follow-item-remark follow-item"
>
<span class="follow-info-label label-font">
处理结果:
</span>
<span class="info-value value-font">
{{ items.extra_attribution.banned_text }}
</span>
</div> -->
<!-- 同步掌游的内容 -->
<div
v-if="(items.node_sort === '0' || (items.extra_attribution && items.extra_attribution.remark)) && items.node_name !== '系统'"
class="info-item-remark"
>
<div style="display: flex;">
<span class="info-label remark-label">详情:</span>
<span class="preview-btn" @click.stop="previewRemark(items.extra_attribution.remark)">
<i class="el-icon-view"></i>
点击查看大图
</span>
</div>
<div class="remark-value" v-html="formatImg(items.extra_attribution && items.extra_attribution.remark ? items.extra_attribution.remark : '')"></div>
</div>
</div>
</template>
</el-step>
</el-steps>
</div>
</el-collapse-transition>
</div>
</div>
</div>
<el-dialog :visible.sync="dialogRemarkVisible" append-to-body title="查看大图" custom-class="remake-dialog">
<div class="remake-box">
<div v-html="dialogRemake"></div>
</div>
</el-dialog>
<resubmitApproval
v-if="showResubmitApproval"
:show.sync="showResubmitApproval"
:appeal-info="appealInfo"
@updateReportList="filterChange"
/>
</div>
</template>
<script>
import { searchcondition, appealList, appealCancel, appealProcess } from '@/api/game'
import { mapState, mapMutations } from 'vuex'
import { removeDp, formatNumber } from '@/utils/index'
import resubmitApproval from './appeal.vue'
// 导入审批状态图标
import shenpi1 from '@/assets/icon/shenpi1.svg'
import shenpi2 from '@/assets/icon/shenpi2.svg'
import shenpi3 from '@/assets/icon/shenpi3.svg'
import shenpi4 from '@/assets/icon/shenpi4.svg'
import shenpi5 from '@/assets/icon/shenpi5.svg'
import noContent from "@/components/noContent.vue";
import { debounce } from '@/utils'
import watchMember from '@/mixins/watchMember'
export default {
computed: {
...mapState('game', ['accountSelect']),
...mapState('user', ['userInfo'])
},
components: {
resubmitApproval,
noContent
},
mixins: [watchMember],
data() {
return {
// 审批状态图标
shenpi1,
shenpi2,
shenpi3,
shenpi4,
shenpi5,
pickerOptions: {
disabledDate(time) {
const curDate = (new Date()).getTime()
const three = 90 * 24 * 3600 * 1000
const threeMonths = curDate - three
return time.getTime() > Date.now() || time.getTime() < threeMonths
}
},
reportForm: {
customer_id: '',
member_id: '',
role_id: '',
username: '',
role_name: '',
register_type: 1,
approval_status: '',
create_time: [],
create_time_start: '',
create_time_end: ''
},
appealInfo: {},
showResubmitApproval: false,
pageInfo: {
page: 1,
page_size: 20
},
reportList: [],
isMoreRecord: false,
approvalList: [],
register_type_list: [],
dialogRemarkVisible: false,
dialogRemake: '',
formatNumber: formatNumber,
taskTypeList: []
}
},
// 9111321331231903744
mounted() {
this.reportForm.create_time = [this.$moment().subtract(1, 'months').format('YYYY-MM-DD HH:mm:ss'), this.$moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')]
this.reportForm.create_time_start = this.$moment().subtract(1, 'months').format('YYYY-MM-DD HH:mm:ss')
this.reportForm.create_time_end = this.$moment().endOf('day').format('YYYY-MM-DD HH:mm:ss')
this.requstApprovalList()
this.request_register_type()
this.filterChange()
},
methods: {
memberChange() {
this.filterChange()
},
filterChange() {
this.pageInfo.page = 1
this.reportList = []
this.isMoreRecord = true
this.appealList()
},
createResult(data) {
if (data) {
this.reportForm.create_time_start = data[0]
this.reportForm.create_time_end = data[1]
} else {
this.reportForm.create_time_start = ''
this.reportForm.create_time_end = ''
}
this.filterChange()
},
async requstApprovalList() {
const data = {
type: 'dictionaries',
table_name: 'zs_refund_request',
field_name: 'approval_status'
}
const res = await searchcondition(data)
if (res.status_code === 1) {
this.approvalList = res.data.data
}
},
previewRemark(remark) {
this.dialogRemake = remark
this.dialogRemarkVisible = true
},
async appealProcess(item, index) {
console.log(item.current, 'item')
item.showStep = !item.showStep
if (item.appealProcessList.length === 0) {
const res = await appealProcess({ id: item.id })
item.appealProcessList = res.data.data
res.data.data.map((items) => {
if (items.approval_result !== '0' && items.approval_result !== '2') {
item.current += 1
}
})
this.$forceUpdate()
}
this.$forceUpdate()
},
async request_register_type() {
const data = {
type: 'dictionaries',
table_name: 'zs_report_request',
field_name: 'register_type'
}
const res = await searchcondition(data)
if (res.status_code === 1) {
this.register_type_list = res.data.data
}
},
paperScroll() {
this.requestNextPage()
},
requestNextPage(pageInfo) {
this.pageInfo.page++
this.appealList()
},
handleCurrentChange(val) {
this.pageInfo.page = val
},
switchStateTag(status) {
switch (status) {
case '0':
return 'unhandle'
case '1':
return 'handled'
case '2':
return 'sendFail'
}
},
formatImg(html) {
return html.replaceAll(/<img/g, '<img style="max-width:100px;"')
},
switchStateText(status) {
switch (status) {
case '0':
return '待审批'
case '1':
return '通过'
case '2':
return '驳回'
}
},
// 重新提交
resubmitApproval(item) {
this.appealInfo = item
this.showResubmitApproval = true
},
handleReport(item) {
this.$confirm('确定要撤销该申请么?', '确认提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
const data = {
id: item.id,
user_id: this.userInfo.id,
user_name: this.userInfo.username
}
appealCancel(data).then(res => {
if (res.status_code === 1) {
this.$message({
type: 'success',
message: '撤销成功!'
})
this.filterChange()
}
})
})
.catch(() => {
this.$message({
type: 'info',
message: '已取消'
})
})
},
// 申诉列表
async appealList() {
if (this.accountSelect === '') {
this.$message.warning('暂无关联的账号,请先去关联账号!')
return false
}
if (this.pageInfo.page == 1) {
this.reportList = []
}
const { username, role_name, approval_status, register_type, create_time_start, create_time_end } = this.reportForm
// const { id } = this.userInfo
const data = {
username,
role_name,
approval_status,
register_type,
create_time_start,
create_time_end,
member_id: this.accountSelect,
// customer_id: id,
...this.pageInfo
}
const res = await appealList(data)
if (this.pageInfo.page == 1) {
this.reportList = res.data.data
} else {
this.reportList = removeDp(this.reportList, res.data.data, 'id')
}
if (this.reportList.length > 0) {
this.reportList.map((item) => {
item.showStep = false
item.current = 0
item.appealProcessList = []
})
} else {
this.reportList = []
}
if (res.data.data.length < 20) {
this.isMoreRecord = false
} else {
this.isMoreRecord = true
}
}
}
}
</script>
<style lang="scss" scoped>
.approval-role-list {
width: 100%;
height: calc(100vh - 186px);
overflow: auto;
padding-top: 10px;
.taskForm {
::v-deep .el-form-item {
margin-bottom: 10px;
}
}
// 会话筛选
.filterChat {
width: 100%;
margin-top: 20px;
::v-deep .el-button {
margin-left: 6px;
margin-right: 0 !important;
}
.btnListScroll {
margin-bottom: 10px;
}
.chatIcon {
font-size: 20px;
margin-left: 5px;
margin-top: 10px;
cursor: pointer;
}
.itemActive {
background: #e1fff0;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #00bf8a;
border: none;
}
.btnList {
width: 100%;
margin-bottom: 10px;
overflow: auto;
.btnItem {
border: none;
background: #eef0f4;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #6e7073;
}
}
}
.mailListScroll {
width: 100%;
overflow-y: auto;
overflow-x: hidden;
display: flex;
flex: 1;
.scrollMain {
width: 100%;
height: auto;
margin-bottom: 40px;
.reportContent {
width: calc(100% - 10px);
}
//举报申请
.reportItem {
padding: 10px;
background: #f7f8fa;
margin-bottom: 10px;
position: relative;
cursor: pointer;
color: #333333;
font-size: 14px;
font-weight: 500;
p {
line-height: 25px;
}
.reportItemLeft {
width: 100%;
.label {
font-weight: 400;
font-size: 14px;
color: #86909c;
line-height: 20px;
margin-right: 10px;
}
.value {
font-weight: 400;
font-size: 14px;
color: #333333;
line-height: 20px;
text-align: left;
}
}
.reportItemRight {
height: 100%;
.icon {
font-size: 50px;
}
}
}
.chatListItem {
width: 100%;
height: 68px;
padding: 3px vw(20);
position: relative;
cursor: pointer;
color: #333333;
font-size: 14px;
font-weight: 500;
.left {
color: #333333;
font-size: 14px;
font-weight: 500;
}
.info,
.top {
font-size: 14px;
font-weight: 400;
}
.bottom {
font-size: 14px;
color: #999999;
}
.right {
font-size: 12px;
font-weight: 400;
}
}
}
.chatListItemActive {
background: #e4fff1 !important;
}
.chatListItem:hover {
background: #e4fff1 !important;
}
}
}
// 掌游的样式
::v-deep.el-step .el-step__line {
width: 1px;
}
::v-deep .el-step>.is-success {
color: #00bf8a;
border-color: #00bf8a;
.el-step__line {
background-color: #e5e6eb;
}
}
::v-deep .el-step__main>.is-success {
color: #00bf8a;
}
::v-deep .el-step>.is-process {
color: #00bf8a;
border-color: #00bf8a;
.el-step__line {
background-color: #e5e6eb;
}
}
::v-deep .el-step__main>.is-process {
color: #00bf8a;
}
.form-item-btn {
margin: 0 0 0 20px;
}
.audit-label {
font-size: 14px;
font-weight: 800;
margin: 0 0 10px 0;
}
.remark-label {
color: #949fb0;
font-size: 14px;
}
.preview-btn {
cursor: pointer;
font-size: 14px;
color: #00bf8a;
margin: 0 0 0 10px;
i {
margin: 0 5px 0 0;
}
}
.remark-value {
min-height: 100px;
margin: 10px 0 0 40px;
padding: 6px 12px;
border: 1px solid #d9d9d9;
border-radius: 4px;
cursor: not-allowed;
color: #333;
}
.flex-box {
display: flex;
.remark-lebel {
width: 50px;
text-align: right;
}
}
.refund-flow-drawer {
position: fixed;
top: 0;
right: 700px;
}
.btm-btn-box {
position: fixed;
bottom: 20px;
width: 560px;
height: 32px;
}
.audit-state {
width: 50px;
height: 50px;
position: absolute;
top: 50%;
right: 0;
transform: translateY(-50%);
z-index: 100;
.audit-state-stamp {
font-size: 50px;
}
}
.info-item {
width: 45%;
display: flex;
height: 18px;
margin: 0 0 12px 0;
}
.info-item-pic {
width: 100%;
min-height: 96px;
max-height: 192px;
display: flex;
.img-list {
width: 464px;
display: flex;
flex-wrap: wrap;
&-item {
width: 80px;
height: 80px;
border-radius: 4px;
overflow: hidden;
margin: 0 10px 10px 0;
position: relative;
.preview-pic {
width: 80px;
height: 80px;
background: rgba(0, 0, 0, 0.5);
position: absolute;
top: 0;
left: 0;
z-index: -1;
text-align: center;
line-height: 80px;
.preview-icon {
font-size: 16px;
color: #fff;
cursor: pointer;
}
}
.screenshot {
object-fit: center;
width: 80px;
height: 80px;
}
&:hover>.preview-pic {
z-index: 100;
}
}
}
}
.flex-btn {
display: flex;
justify-content: space-between;
}
.info-label {
// width: 90px;
// text-align: right;
display: block;
margin: 0 10px 0 0;
font-size: 14px;
color: #949fb0;
}
.info-value {
display: block;
font-size: 14px;
color: #333;
}
.card-style {
background: #f2f2f7;
border-radius: 4px;
}
.trans-follow-1 {
width: vw(300);
min-height: fit-content;
margin: 6px 0 12px 0;
padding: 12px 12px 2px 12px;
position: relative;
.collapse-btn {
position: absolute;
top: 20px;
right: 15px;
}
.follow-item-remark {
width: 100%;
line-height: 20px;
margin: 0 0 12px 0;
}
.info-value-color {
color: #00bf8a;
margin-left: 5px;
}
}
.follow-item {
min-height: 20px;
line-height: 20px;
margin: 0 0 12px 0;
display: flex;
.label-left {
width: 90px;
text-align: right;
}
}
.left-label {
width: 60px;
}
.follow-info-label {
width: fit-content;
text-align: left;
display: inline-block;
margin: 0 10px 0 0;
}
.info-value {
font-size: 14px;
color: #333;
}
.label-font {
font-size: 14px;
color: #949fb0;
}
.info-item-remark {
width: 100%;
padding: 0 0 12px 0;
line-height: 20px;
.info-label {
display: block;
}
.info-value {
display: block;
width: 440px;
}
}
.appealProcessList {
margin-bottom: 20px;
margin-top: 20px;
}
</style>
\ No newline at end of file
<template>
<div class="reportList">
<el-form
ref="taskForm"
:model="reportForm"
class="taskForm"
label-width="85px"
>
<el-form-item label="角色名称">
<el-input
v-model="reportForm.role_name"
style="width:95%;"
clearable
placeholder="请输入角色名称"
@change="filterChange"
>
</el-input>
</el-form-item>
<el-form-item label="审批状态">
<el-select
v-model="reportForm.approval_status"
style="width:95%;"
clearable
placeholder="请选择审批状态"
@change="filterChange"
>
<el-option
v-for="item in approvalList"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="申请方式">
<el-select
v-model="reportForm.register_type"
style="width:95%;"
clearable
placeholder="请选择申请方式"
@change="filterChange"
>
<el-option
v-for="item in register_type_list"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
</el-form>
<div
v-infinite-scroll="paperScroll"
:infinite-scroll-disabled="!isMoreRecord"
:infinite-scroll-immediate="false"
class="mailListScroll"
>
<!-- 举报申请 -->
<div class="scrollMain">
<div
v-for="(item, index) in reportList"
:key="index"
class="reportContent"
@click="reportProcess(item, index)"
>
<div class="reportItem rowFlex spaceBetween columnCenter">
<div class="reportItemLeft">
<p><span class="label">角色名称:</span><span class="value">{{ item.role_name }}</span></p>
<p>
<span class="label">累计充值:</span><span class="value">{{ formatNumber(item.recharge_total_amount) }}
</span>
</p>
<p>
<span class="label">近一周充值:</span><span class="value">{{ formatNumber(item.recharge_week_amount)
}}</span>
</p>
<p><span class="label">违规操作:</span><span class="value">{{ item.violation_type_text }}</span></p>
</div>
<div class="reportItemRight columnFlex columnCenter">
<!-- 撤销 当item.create_user_id == zq_user_id 的时候才可以撤销 只能撤销自己提交的审批 -->
<el-button
v-if="item.approval_status == 1 && (item.create_user_id == userInfo.id)"
type="primary"
size="mini"
@click.stop="handleReport(item)"
>撤销</el-button>
<!-- 审批 只有待审批状态可以并且申请方式是玩家登记的时候才有这个 -->
<el-button
v-if="item.approval_status == 1 && reportForm.register_type == 2 && (item.customer_id == userInfo.id)"
type="primary"
size="mini"
@click.stop="resubmitReportApproval(item)"
>审批</el-button>
<!-- 重新提交 -->
<el-button
v-else-if="item.approval_status == 4"
type="primary"
size="mini"
@click.stop="resubmitReport(item)"
>重新提交</el-button>
<img
v-if="item.approval_status == 1"
:src="shenpi1"
class="icon"
/>
<img
v-else-if="item.approval_status == 2"
:src="shenpi2"
class="icon"
/>
<img
v-else-if="item.approval_status == 3"
:src="shenpi3"
class="icon"
/>
<img
v-else-if="item.approval_status == 4"
:src="shenpi4"
class="icon"
/>
<img
v-else-if="item.approval_status == 5"
:src="shenpi5"
class="icon"
/>
</div>
</div>
<!-- 审批进度 -->
<el-collapse-transition>
<div
v-if="item.showStep"
class="reportProcessList"
>
<el-steps
direction="vertical"
:active="item.current"
finish-status="success"
>
<el-step
v-for="(items, indexs) in item.reportProcessList"
:key="'trans_item_' + indexs"
:title="items.node_name"
>
<template slot="description">
<div
v-if="items"
class="trans-follow-1 card-style"
>
<div class="follow-item">
<span class="follow-info-label label-font">
{{ items.node_sort !== '0' ? '审批人:' : '登记人:' }}
</span>
<span class="info-value value-font">
{{ Array.isArray(items.user_name) ? items.user_name[0] : items.user_name }}
</span>
<el-tooltip
v-if="Array.isArray(items.user_name) && items.user_name.length > 1"
class="item"
effect="dark"
:content="items.user_name.slice(1).join('、')"
placement="top"
>
<span class="info-value value-font info-value-color">
{{ `+${items.user_name.length - 1}` }}
</span>
</el-tooltip>
</div>
<div
v-if="items.node_sort !== '0' || items.node_name === '系统'"
class="follow-item"
>
<span class="follow-info-label label-font">
审批结果:
</span>
<span
class="info-value value-font"
:class="[items.current < indexs? '' : switchStateTag(items.approval_result)]"
>
{{ items.current < indexs ? '' : items.approval_result_text }}
</span>
</div>
<div class="follow-item">
<span class="follow-info-label label-font">
{{ items.node_sort !== '0' || items.node_name === '系统' ? '审批时间:' : '登记时间:' }}
</span>
<span class="info-value value-font">
{{ items.node_sort === '0' ? items.create_time : items.update_time }}
</span>
</div>
<div
v-if="(items.node_sort !== '0' || items.node_name === '系统') && items.approval_result==='2'"
class="follow-item"
>
<span class="follow-info-label label-font">
驳回原因:
</span>
<span class="info-value value-font">
{{ items.extra_attribution.remark }}
</span>
</div>
<div
v-if="items.node_sort === item.reportProcessList[item.reportProcessList.length - 1 ].node_sort+ '' && items.approval_result === '1' && items.node_sort !== '0'"
class="follow-item-remark follow-item"
>
<span class="follow-info-label label-font">
处理结果:
</span>
<span class="info-value value-font">
{{ items.extra_attribution.banned_text }}
</span>
</div>
<div
v-if="items.node_sort === '0' && items.node_name !== '系统'"
class="info-item-remark"
>
<div style="display: flex;">
<span class="info-label remark-label">详情:</span>
<span
class="preview-btn"
@click.stop="previewRemark(items.extra_attribution.remark)"
>
<i class="el-icon-view"></i>
点击查看大图
</span>
</div>
<div
class="remark-value"
v-html="formatImg(items.extra_attribution && items.extra_attribution.remark ? items.extra_attribution.remark : '')"
></div>
</div>
</div>
</template>
</el-step>
</el-steps>
</div>
</el-collapse-transition>
</div>
</div>
</div>
<el-dialog
:visible.sync="dialogRemarkVisible"
append-to-body
title="查看大图"
custom-class="remake-dialog"
>
<div class="remake-box">
<div v-html="dialogRemake"></div>
</div>
</el-dialog>
<!-- 重新提交 -->
<resubmitReport
v-if="showResubmitReport"
:report-info="reportInfo"
:show.sync="showResubmitReport"
@updateReportList="filterChange"
/>
<!-- 审批 -->
<approvalTask
v-if="isApproval"
:show.sync="isApproval"
:report-info="reportInfo"
@updateReportList="filterChange"
/>
</div>
</template>
<script>
import { searchcondition, reportIndex, reportCancel, reportProcess } from '@/api/game'
import { mapState, mapMutations } from 'vuex'
import { removeDp, formatNumber } from '@/utils/index'
import resubmitReport from '../layer/report.vue'
import approvalTask from '../layer/approvalTask.vue'
// 导入审批状态图标
import shenpi1 from '@/assets/icon/shenpi1.svg'
import shenpi2 from '@/assets/icon/shenpi2.svg'
import shenpi3 from '@/assets/icon/shenpi3.svg'
import shenpi4 from '@/assets/icon/shenpi4.svg'
import shenpi5 from '@/assets/icon/shenpi5.svg'
export default {
computed: {
...mapState('game', ['accountSelect', 'report_is_send']),
...mapState('user', ['userInfo'])
},
components: {
resubmitReport,
approvalTask
},
data() {
return {
// 审批状态图标
shenpi1,
shenpi2,
shenpi3,
shenpi4,
shenpi5,
reportForm: {
customer_id: '',
member_id: '',
role_id: '',
username: '',
role_name: '',
register_type: 1,
approval_status: ''
},
isApproval: false,
register_type_list: [
{ value: 2, label: '玩家登记' },
{ value: 1, label: '客服登记' }
],
reportInfo: {},
pageInfo: {
page: 1,
page_size: 20
},
showResubmitReport: false,
reportList: [],
isMoreRecord: false,
approvalList: [],
dialogRemarkVisible: false,
dialogRemake: '',
formatNumber: formatNumber,
taskTypeList: []
}
},
watch: {
// 监听到变化
report_is_send(newVal, oldVal) {
console.log('变化了')
this.reportForm.register_type = 2
this.reportForm.approval_status = 1
this.filterChange()
}
},
mounted() {
// this.request_register_type()
this.requstApprovalList()
this.filterChange()
},
methods: {
resubmitReport(item) {
this.reportInfo = item
this.showResubmitReport = true
},
// 审批
resubmitReportApproval(item) {
this.reportInfo = item
this.isApproval = true
},
filterChange() {
this.pageInfo.page = 1
this.reportList = []
this.isMoreRecord = true
this.reportIndex()
},
async requstApprovalList() {
const data = {
type: 'dictionaries',
table_name: 'zs_refund_request',
field_name: 'approval_status'
}
const res = await searchcondition(data)
if (res.status_code === 1) {
this.approvalList = res.data.data
}
},
async request_register_type() {
const data = {
type: 'dictionaries',
table_name: 'zs_report_request',
field_name: 'register_type'
}
const res = await searchcondition(data)
if (res.status_code === 1) {
this.register_type_list = res.data.data
}
},
previewRemark(remark) {
this.dialogRemake = remark
this.dialogRemarkVisible = true
},
async reportProcess(item, index) {
console.log(item.current, 'item')
item.showStep = !item.showStep
if (item.reportProcessList.length === 0) {
const res = await reportProcess({ id: item.id })
item.reportProcessList = res.data.data
res.data.data.map((items) => {
if (items.approval_result !== '0' && items.approval_result !== '2') {
item.current += 1
}
})
this.$forceUpdate()
}
this.$forceUpdate()
},
paperScroll() {
this.requestNextPage()
},
requestNextPage(pageInfo) {
this.pageInfo.page++
this.reportIndex()
},
handleCurrentChange(val) {
this.pageInfo.page = val
},
switchStateTag(status) {
switch (status) {
case '0':
return 'unhandle'
case '1':
return 'handled'
case '2':
return 'sendFail'
}
},
formatImg(html) {
return html.replaceAll(/<img/g, '<img style="max-width:100px;"')
},
switchStateText(status) {
switch (status) {
case '0':
return '待审批'
case '1':
return '通过'
case '2':
return '驳回'
}
},
handleReport(item) {
this.$confirm('确定要撤销该申请么?', '确认提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
console.log(1231)
const data = {
id: item.id,
user_id: this.userInfo.id,
user_name: this.userInfo.username
}
reportCancel(data).then(res => {
if (res.status_code === 1) {
this.$message({
type: 'success',
message: '撤销成功!'
})
this.filterChange()
}
})
})
.catch(() => {
this.$message({
type: 'info',
message: '已取消'
})
})
},
// 举报列表
async reportIndex() {
if (this.accountSelect === '') {
this.$message.warning('暂无关联的账号,请先去关联账号!')
return false
}
if (this.pageInfo.page == 1) {
this.reportList = []
}
const { username, role_name, approval_status, register_type } = this.reportForm
// const { id } = this.userInfo
const data = {
username,
role_name,
approval_status,
// customer_id: id,
member_id: this.accountSelect,
register_type,
...this.pageInfo
}
const res = await reportIndex(data)
if (this.pageInfo.page == 1) {
this.reportList = res.data.data
} else {
this.reportList = removeDp(this.reportList, res.data.data, 'id')
}
if (this.reportList.length > 0) {
this.reportList.map((item) => {
item.showStep = false
item.current = 0
item.reportProcessList = []
})
} else {
this.reportList = []
}
if (res.data.data.length < 20) {
this.isMoreRecord = false
} else {
this.isMoreRecord = true
}
if (res.data.data.length < 20) {
this.isMoreRecord = false
} else {
this.isMoreRecord = true
}
}
}
}
</script>
<style lang="scss" scoped>
.reportList {
width: 100%;
height: calc(100% - 60px);
overflow: auto;
.taskForm {
::v-deep .el-form-item {
margin-bottom: 10px;
}
}
// 会话筛选
.filterChat {
width: 100%;
margin-top: 20px;
::v-deep .el-button {
margin-left: 6px;
margin-right: 0 !important;
}
.btnListScroll {
margin-bottom: 10px;
}
.chatIcon {
font-size: 20px;
margin-left: 5px;
margin-top: 10px;
cursor: pointer;
}
.itemActive {
background: #e1fff0;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #00bf8a;
border: none;
}
.btnList {
width: 100%;
margin-bottom: 10px;
overflow: auto;
.btnItem {
border: none;
background: #eef0f4;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #6e7073;
}
}
}
.mailListScroll {
width: 100%;
height: calc(100vh - 220px);
overflow-y: auto;
overflow-x: hidden;
.scrollMain {
width: 100%;
height: auto;
margin-bottom: 40px;
.reportContent {
width: calc(100% - 10px);
}
//举报申请
.reportItem {
padding: 10px;
background: #f7f8fa;
margin-bottom: 10px;
position: relative;
cursor: pointer;
color: #333333;
font-size: 14px;
font-weight: 500;
p {
line-height: 25px;
}
.reportItemLeft {
width: 100%;
.label {
font-weight: 400;
font-size: 14px;
color: #86909c;
line-height: 20px;
margin-right: 10px;
}
.value {
font-weight: 400;
font-size: 14px;
color: #333333;
line-height: 20px;
text-align: left;
}
}
.reportItemRight {
height: 100%;
.icon {
font-size: 50px;
}
}
}
.chatListItem {
width: 100%;
height: 68px;
padding: 3px vw(20);
position: relative;
cursor: pointer;
color: #333333;
font-size: 14px;
font-weight: 500;
.left {
color: #333333;
font-size: 14px;
font-weight: 500;
}
.info,
.top {
font-size: 14px;
font-weight: 400;
}
.bottom {
font-size: 14px;
color: #999999;
}
.right {
font-size: 12px;
font-weight: 400;
}
}
}
.chatListItemActive {
background: #e4fff1 !important;
}
.chatListItem:hover {
background: #e4fff1 !important;
}
}
}
// 掌游的样式
::v-deep.el-step .el-step__line {
width: 1px;
}
::v-deep .el-step > .is-success {
color: #00bf8a;
border-color: #00bf8a;
.el-step__line {
background-color: #e5e6eb;
}
}
::v-deep .el-step__main > .is-success {
color: #00bf8a;
}
::v-deep .el-step > .is-process {
color: #00bf8a;
border-color: #00bf8a;
.el-step__line {
background-color: #e5e6eb;
}
}
::v-deep .el-step__main > .is-process {
color: #00bf8a;
}
.form-item-btn {
margin: 0 0 0 20px;
}
.audit-label {
font-size: 14px;
font-weight: 800;
margin: 0 0 10px 0;
}
.remark-label {
color: #949fb0;
font-size: 14px;
}
.preview-btn {
cursor: pointer;
font-size: 14px;
color: #00bf8a;
margin: 0 0 0 10px;
i {
margin: 0 5px 0 0;
}
}
.remark-value {
min-height: 100px;
margin: 10px 0 0 40px;
padding: 6px 12px;
border: 1px solid #d9d9d9;
border-radius: 4px;
cursor: not-allowed;
color: #333;
}
.flex-box {
display: flex;
.remark-lebel {
width: 50px;
text-align: right;
}
}
.refund-flow-drawer {
position: fixed;
top: 0;
right: 700px;
}
.btm-btn-box {
position: fixed;
bottom: 20px;
width: 560px;
height: 32px;
}
.audit-state {
width: 50px;
height: 50px;
position: absolute;
top: 50%;
right: 0;
transform: translateY(-50%);
z-index: 100;
.audit-state-stamp {
font-size: 50px;
}
}
.info-item {
width: 45%;
display: flex;
height: 18px;
margin: 0 0 12px 0;
}
.info-item-pic {
width: 100%;
min-height: 96px;
max-height: 192px;
display: flex;
.img-list {
width: 464px;
display: flex;
flex-wrap: wrap;
&-item {
width: 80px;
height: 80px;
border-radius: 4px;
overflow: hidden;
margin: 0 10px 10px 0;
position: relative;
.preview-pic {
width: 80px;
height: 80px;
background: rgba(0, 0, 0, 0.5);
position: absolute;
top: 0;
left: 0;
z-index: -1;
text-align: center;
line-height: 80px;
.preview-icon {
font-size: 16px;
color: #fff;
cursor: pointer;
}
}
.screenshot {
object-fit: center;
width: 80px;
height: 80px;
}
&:hover > .preview-pic {
z-index: 100;
}
}
}
}
.flex-btn {
display: flex;
justify-content: space-between;
}
.info-label {
// width: 90px;
// text-align: right;
display: block;
margin: 0 10px 0 0;
font-size: 14px;
color: #949fb0;
}
.info-value {
display: block;
font-size: 14px;
color: #333;
}
.card-style {
background: #f2f2f7;
border-radius: 4px;
}
.trans-follow-1 {
width: vw(300);
min-height: fit-content;
margin: 6px 0 12px 0;
padding: 12px 12px 2px 12px;
position: relative;
.collapse-btn {
position: absolute;
top: 20px;
right: 15px;
}
.follow-item-remark {
width: 100%;
line-height: 20px;
margin: 0 0 12px 0;
}
.info-value-color {
color: #00bf8a;
margin-left: 5px;
}
}
.follow-item {
min-height: 20px;
line-height: 20px;
margin: 0 0 12px 0;
display: flex;
.label-left {
width: 90px;
text-align: right;
}
}
.left-label {
width: 60px;
}
.follow-info-label {
white-space: nowrap;
text-align: left;
margin: 0 10px 0 0;
}
.info-value {
font-size: 14px;
color: #333;
}
.label-font {
font-size: 14px;
color: #949fb0;
}
.info-item-remark {
width: 100%;
padding: 0 0 12px 0;
line-height: 20px;
.info-label {
display: block;
}
.info-value {
display: block;
width: 440px;
}
}
.reportProcessList {
margin-bottom: 20px;
margin-top: 20px;
}
</style>
\ No newline at end of file
<template>
<div class="details-user-info-role columnFlex">
<div
v-loading="loading"
class="detailsContent"
>
<div v-if="roleList.length>0">
<p class="textInfo">角色充值金额信息会有5-10分钟延迟,请以订单信息为准</p>
<el-collapse
v-model="collapseActive"
@change="handleChange"
>
<div
v-for="(items,indexs) in roleList"
:key="indexs"
class="contentItem"
>
<div class="title"></div>
<el-collapse-item :name="items.id">
<template slot="title">
<div class="collapseTitle rowFlex columnCenter spaceBetween">
<p class="hidden">
{{ items.role_name }} - {{ items.server_name }} - {{ items.recharge_total?items.recharge_total+'元':'0元' }}
</p>
<el-button
type="primary"
size="mini"
class="collapseTitleBtn"
@click.stop="appealLayer(items)"
>申诉</el-button>
</div>
</template>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">区服:</span>
<p class="text">{{ items.server_name }}</p>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">合区区服:</span>
<p class="text">{{ items.merge_server_name }}</p>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">角色名称:</span>
<p class="text">{{ items.role_name }}</p>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">等级:</span>
<p class="text">{{ items.role_level }}</p>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">战力:</span>
<p class="text">{{ items.combat_num }}</p>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">充值金额:</span>
<p class="text">{{ items.recharge_total }}</p>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">转端审核:</span>
<p class="text">{{ items.trans_status_name || '无' }}</p>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">CP角色ID:</span>
<p class="text">{{ items.cp_role_id }}</p>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">最近活跃时间:</span>
<p class="text">{{ $moment( items.last_login_time * 1000).format('YYYY-MM-DD HH:mm:ss') }}</p>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">创建时间:</span>
<p class="text">{{ $moment( items.create_time * 1000).format('YYYY-MM-DD HH:mm:ss') }}</p>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">创角天数:</span>
<p class="text">{{ items.create_role_day }}天</p>
</div>
</div>
</el-collapse-item>
</div>
</el-collapse>
</div>
<div
v-else-if="!loading && roleList.length==0"
class="noContent rowFlex allCenter"
>
<noContent title="暂无数据" description="当前没有任何数据,请稍后再试或联系管理员" />
</div>
</div>
<appeal
v-if="showAppeal"
:show.sync="showAppeal"
:appeal-info="appealInfo"
/>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex'
import { getRoleHoLo } from '@/api/game'
import noContent from '@/components/noContent.vue'
import appeal from './appeal.vue'
import watchMember from '@/mixins/watchMember'
export default {
components: {
noContent,
appeal
},
data() {
return {
collapseActive: [],
roleList: [],
nowTime: '',
loading: false,
showAppeal: false,
appealInfo: {},
pageInfo: {
page_size: 100,
page: 1,
total: 0
},
infoList: []
}
},
computed: {
...mapState('game', ['accountSelect'])
},
mixins: [watchMember],
mounted() {
this.requestRoleList()
this.nowTime = new Date().getTime()
},
methods: {
handleChange() {
},
memberChange() {
this.requestRoleList()
},
// 申诉
appealLayer(item) {
this.appealInfo = item
this.showAppeal = true
},
requestRoleList() {
if (this.accountSelect === '') {
this.$message.warning('暂无关联的账号,请先去关联账号!')
return false
}
this.loading = true
const data = {
api_search_name: '',
member_id: this.accountSelect,
search_type: 'list',
...this.pageInfo
}
getRoleHoLo(data).then(res => {
this.loading = false
if (res.status_code == 1) {
if (res.data.data.length > 0) {
this.roleList = res.data.data.sort((a, b) => { return Number(b.recharge_total) - Number(a.recharge_total) })
} else {
this.roleList = []
}
}
}, err => {
this.loading = false
})
}
}
}
</script>
<style lang="scss" scoped>
.details-user-info-role {
width: 100%;
height: 100%;
background: #fff;
margin-left: 2px;
.detailsTitle {
width: 100%;
padding: 0 vw(20);
height: 60px;
font-size: 18px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
border-bottom: 1px solid #ebeef5;
border-left: 1px solid #ebeef5;
p {
color: #333333;
}
}
.detailsContent {
width: 100%;
height: calc(100vh - 186px);
overflow: auto;
.textInfo {
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #999999;
font-size: 12px;
margin-bottom: 10px;
margin-top: 10px;
}
.contentItem {
position: relative;
.title {
position: absolute;
left: 10px;
top: 14px;
font-size: 14px;
color: #999999;
}
.collapseTitle {
width: 90%;
}
}
.item {
width: 100%;
height: auto;
font-size: 14px;
font-weight: 400;
color: #333333;
padding: 5px 0;
transition: all 0.5s;
position: relative;
padding-left: 10px;
cursor: pointer;
.tableImage {
width: 40px;
height: 40px;
border-radius: 6px;
margin-right: vw(10);
}
.label {
color: #999999;
}
.text {
color: #333333;
margin-left: 10px;
word-break: break-all;
max-width: 80%;
}
.icon {
display: none;
position: absolute;
right: 0;
top: 12px;
}
.tags {
width: vw(300);
margin-left: 10px;
.tagsItem {
width: vw(300);
}
.tag {
height: 22px;
line-height: 22px;
padding: 0 8px;
background: #ffffff;
border-radius: 4px;
border: 1px solid rgba(0, 0, 0, 0.2);
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #333333;
margin-right: 10px;
margin-bottom: 10px;
}
}
}
.item:hover .icon {
display: block;
}
}
::v-deep .el-collapse-item {
margin-bottom: 20px;
}
::v-deep .el-collapse-item__content {
padding-bottom: 10px;
}
::v-deep .el-collapse {
border: none;
}
::v-deep .el-collapse-item__header {
width: 100%;
height: 44px;
background: #f9faff;
color: #333333;
padding-left: 10px;
font-size: 14px;
font-weight: 400;
}
}
</style>
\ No newline at end of file
<template>
<div class="newPage">
<!-- 共享信息 -->
<div v-if="userList.length > 0" class="item columnFlex spaceBetween">
<!-- <div class="rowFlex columnCenter">
<span class="label">共享信息:</span>
<i style="margin-left: 10px; font-size: 20px; color: #0ac358; cursor: pointer" class="el-icon-circle-plus-outline" type="primary" @click="addGroupText"></i>
</div> -->
<div v-for="(i,k) in userList" :key="k" class="userList rowFlex ">
<p class="label hidden">{{ i.zq_user_name }} -- {{ i.name }}</p>
<div style="margin-bottom:10px;" class="columnFlex ">
<div v-for="(item,index) in i.text" :key="index+'1'" class="keyWordsItem rowFlex columnCenter">
<el-input v-model="item.text" type="textarea" :disabled="chatUserDetails.userid !== i.userid || i.zq_user_id!== userInfo.id" placeholder="请输入共享信息" @change="inputBlur(k,index)"> </el-input>
<div v-if="chatUserDetails.userid == i.userid && i.zq_user_id=== userInfo.id">
<i v-if="index==0" style="margin-left:10px;font-size:20px;color:#0AC358;cursor: pointer;" class="el-icon-circle-plus-outline" type="primary" @click="addInputItem(k,index)"></i>
<i v-else style="margin-left:10px;font-size:20px;color:#0AC358;cursor: pointer;" class="el-icon-remove-outline" type="primary" @click="removeInput(k,index)"></i>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { shareInfoUpsert, shareInfoDel } from '@/api/works'
import { mapState } from 'vuex'
export default {
name: 'ShareInfo',
props: ['chatUserDetails'],
data() {
return {
inputList: [],
userList: []
}
},
computed: {
...mapState('user', ['userInfo'])
},
watch: {
chatUserDetails(newVal, oldVal) {
this.handleUserList()
}
},
mounted() {
this.handleUserList()
},
methods: {
handleUserList() {
if (this.chatUserDetails.share_info && this.chatUserDetails.share_info.length > 0) {
const item = this.chatUserDetails.share_info.find(item => item.userid === this.chatUserDetails.userid && item.zq_user_id === this.userInfo.id)
if (!item) {
this.userList = [...this.chatUserDetails.share_info, { zq_user_name: this.userInfo.username, zq_user_id: this.userInfo.id, userid: this.chatUserDetails.userid, name: this.chatUserDetails?.user?.name || '', text: [{ id: '', text: '' }] }]
} else {
this.userList = this.chatUserDetails.share_info
}
} else {
this.userList = [{ zq_user_name: this.userInfo.username, zq_user_id: this.userInfo.id, userid: this.chatUserDetails.userid, name: this.chatUserDetails?.user?.name || '', text: [{ id: '', text: '' }] }]
}
},
addGroupText() {
if (this.userList.length > 0) {
const user = this.userList.find(item => {
if (this.chatUserDetails.user.name === item.zq_user_name) {
return item
}
})
if (user !== -1) {
this.$message.warning(user.zq_user_name + '共享信息已存在')
} else {
this.userList.push({ zq_user_name: this.chatUserDetails.user.name, text: [{ _id: '', text: '' }] })
}
} else {
this.userList.push({ zq_user_name: this.chatUserDetails.user.name, text: [{ _id: '', text: '' }] })
}
},
shareInfoUpsert(_id, text) {
if (text && text.trim() == '') {
this.$message.warning('请输入内容')
return false
}
const data = {
_id: _id || '',
userid: this.chatUserDetails.userid,
external_userid: this.chatUserDetails.external_userid,
text: text.trim()
}
shareInfoUpsert(data).then(res => {
if (res.status_code == 1) {
this.$message.success('保存成功')
}
})
},
inputBlur(k, index) {
// 修改信息
this.shareInfoUpsert(this.userList[k]?.text[index]._id, this.userList[k]?.text[index].text)
},
removeInput(k, index) {
if (this.userList[k]?.text[index]?._id !== '') {
this.shareInfoDel({ _id: this.userList[k].text[index]._id, userid: this.chatUserDetails.userid })
// 请求删除接口
} else {
}
this.userList[k].text.splice(index, 1)
},
// 删除共享信息
shareInfoDel(data) {
shareInfoDel(data).then(res => {
if (res.status_code == 1) {
this.$message.success(res.msg)
}
})
},
// 添加时间点
addInputItem(index) {
this.userList[index].text.push({ _id: '', text: '' })
this.inputList.push({ text: '' })
}
}
}
</script>
<style lang="scss" scoped>
.newPage {
width: 100%;
height: auto;
.item {
width: 100%;
height: auto;
font-size: 14px;
font-weight: 400;
color: #333333;
padding: 10px 0;
transition: all 0.5s;
position: relative;
cursor: pointer;
.tableImage {
width: 40px;
height: 40px;
border-radius: 6px;
margin-right: vw(10);
}
.showInputRemarkInput {
width: vw(220);
margin-left: 10px;
}
.label {
color: #999999;
width: vw(125);
}
.text {
color: #333333;
margin-left: 10px;
word-break: break-all;
max-width: 100%;
}
.icon {
display: none;
position: absolute;
right: 0;
top: 12px;
}
.noBind {
width: 44px;
height: 22px;
border-radius: 4px;
border: 1px solid #00bf8a;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #00bf8a;
margin-left: 30px;
cursor: pointer;
}
.tags {
width: vw(300);
margin-left: 10px;
.tagsItem {
width: vw(300);
}
.tag {
height: 22px;
line-height: 22px;
padding: 0 8px;
background: #ffffff;
border-radius: 4px;
border: 1px solid rgba(0, 0, 0, 0.2);
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #333333;
margin-right: 10px;
margin-bottom: 10px;
}
}
}
.item:hover .icon {
display: block;
}
.userList{
width: 100%;
height: auto;
margin-top: 20px;
.label{
margin-right: 10px;
margin-top: 8px;
}
.keyWordsItem{
margin-bottom: 20px;
}
}
}
</style>
\ No newline at end of file
<template>
<div class="userInfo-content">
<!-- 用 el-tabs 有三个 tab 分别是 客户资料 角色信息 违规记录 用 v-for 循环 -->
<el-tabs v-model="activeTab" >
<el-tab-pane label="客户资料" name="userInfo">
<Info v-if="activeTab === 'userInfo'" :chatUserDetails="chatUserInfo"/>
</el-tab-pane>
<el-tab-pane label="角色信息" name="roleInfo">
<RoleInfo v-if="activeTab === 'roleInfo'"/>
</el-tab-pane>
<el-tab-pane label="违规记录" name="violationRecord">
<ViolationRecord v-if="activeTab === 'violationRecord'"/>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import Info from './components/Info.vue'
import RoleInfo from './components/RoleInfo.vue'
import ViolationRecord from './components/ViolationRecord.vue'
import { mapState,mapMutations } from 'vuex'
import Cookies from 'js-cookie'
export default {
name: 'UserInfo',
components:{
Info,
RoleInfo,
ViolationRecord
},
mounted() {
},
computed: {
...mapState('game', ['chatUserInfo']),
},
data() {
return {
activeTab:'userInfo',
tabList:[
{
name:'客户资料',
value:'userInfo'
},
{
name:'角色信息',
value:'roleInfo'
},
{
name:'违规记录',
value:'violationRecord'
}
]
}
},
created(){
// 初始化 vuex 中的值
this.initVuexValue()
},
methods:{
...mapMutations('game',['set_chatUserInfo']),
...mapMutations('user',['set_userid','set_corp_id','set_token','set_cser_info','set_cser_id','set_cser_name']),
initVuexValue(){
this.set_userid(Cookies.get('userid'))
this.set_corp_id(Cookies.get('corp_id'))
this.set_token(Cookies.get('token'))
this.set_cser_id(Cookies.get('cser_id'))
this.set_cser_name(Cookies.get('cser_name'))
const cser_info = Cookies.get('cser_info')
console.log(Cookies.get('cser_id'),'cser_info',Cookies.get('cser_name'))
cser_info?this.set_cser_info(JSON.parse(cser_info)):this.set_cser_info({})
}
}
}
</script>
<style lang="scss" scoped>
.userInfo-content{
width: 100%;
height: 100%;
background: #fff;
}
</style>
{
"global": {
"$--color-primary": "#1B95F8",
"$--color-info": "#7B88A9",
"$--background-color-base": "#01305F",
"$--color-white": "#1B3651",
"$--color-black": "#012447",
"$--color-text-primary": "#FFFFFF",
"$--color-text-regular": "#F9F9F9",
"$--color-text-placeholder": "#E4E2E2",
"$--color-text-secondary": "#EEEEEE",
"$--border-color-base": "#2590F9",
"$--border-color-light": "#388DE0",
"$--border-color-lighter": "#58A9F5",
"$--border-color-extra-light": "#86B3F9"
},
"local": {}
}
\ No newline at end of file
...@@ -9,6 +9,7 @@ module.exports = defineConfig({ ...@@ -9,6 +9,7 @@ module.exports = defineConfig({
transpileDependencies: true, transpileDependencies: true,
outputDir: 'company_app', outputDir: 'company_app',
devServer: { devServer: {
historyApiFallback: true, // 解决404问题
open: false, open: false,
client: { client: {
overlay: { overlay: {
...@@ -31,6 +32,7 @@ module.exports = defineConfig({ ...@@ -31,6 +32,7 @@ module.exports = defineConfig({
} }
}, },
configureWebpack: { configureWebpack: {
name:'企微侧边栏',
// provide the app's title in webpack's name field, so that // provide the app's title in webpack's name field, so that
// it can be accessed in index.html to inject the correct title. // it can be accessed in index.html to inject the correct title.
resolve: { resolve: {
...@@ -49,8 +51,27 @@ module.exports = defineConfig({ ...@@ -49,8 +51,27 @@ module.exports = defineConfig({
outputStyle: 'expanded' outputStyle: 'expanded'
}, },
additionalData: ` additionalData: `
@import "@/styles/global.scss"; @use "@/styles/variables.scss";
` `
},
postcss: {
// postcssOptions: {
// plugins: [
// require("postcss-plugin-px2rem")({
// rootValue: 37.5, //换算基数,
// // unitPrecision: 5, //允许REM单位增长到的十进制数字。
// //propWhiteList: [], //默认值是一个空数组,这意味着禁用白名单并启用所有属性。
// propBlackList: ["border"], //黑名单
// exclude: /(node_module)/, //默认false,可以(reg)利用正则表达式排除某些文件夹的方法。默认值为false,即该项目中所有的px均会被转换为rem
// //(以上exclude配置,如/node_modules|pc/i 排除node_modules文件夹以及所有名为pc的文件夹下的,所有文件的px转换)
// selectorBlackList: ['van-', 'el-'], //要忽略并保留为px的选择器。此处举例:van-为vant-UI的前缀,el-为element-UI的前缀
// // ignoreIdentifier: false, //(boolean/string)忽略单个属性的方法,启用ignoreidentifier后,replace将自动设置为true。
// // replace: true, // (布尔值)替换包含REM的规则,而不是添加回退。
// mediaQuery: false, //(布尔值)允许在媒体查询中转换px。
// minPixelValue: 2, //设置要替换的最小像素值(2px会被转rem)。 默认 0
// }),
// ]
// }
} }
} }
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论