细节优化
This commit is contained in:
parent
0b8ccd4602
commit
064961019c
|
@ -9,6 +9,14 @@ export function listApp(query) {
|
|||
})
|
||||
}
|
||||
|
||||
// 所有APP列表
|
||||
export function listAllApp() {
|
||||
return request({
|
||||
url: '/ss/app/all',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询APP信息列表
|
||||
export function listAppByIds(ids) {
|
||||
return request({
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
<template>
|
||||
<el-link v-if="userType === UserType.ADMIN" type="primary" @click="handleClick" :disabled="id == null">{{name | defaultValue}}</el-link>
|
||||
<el-link v-if="userType === UserType.ADMIN" :type="linkType" @click="handleClick" :disabled="id == null">{{name | defaultValue}}</el-link>
|
||||
<span v-else >{{name | defaultValue}}</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import { UserType } from '@/utils/constants'
|
||||
import { UserRiskTag } from '@/utils/constants'
|
||||
|
||||
export default {
|
||||
name: 'UserLink',
|
||||
|
@ -17,13 +18,32 @@ export default {
|
|||
name: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
riskTag: {
|
||||
type: String,
|
||||
default: UserRiskTag.NORMAL
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
UserType() {
|
||||
return UserType
|
||||
},
|
||||
...mapGetters(['userType'])
|
||||
...mapGetters(['userType']),
|
||||
// 根据风控标签设置链接类型
|
||||
linkType() {
|
||||
switch(this.riskTag) {
|
||||
case UserRiskTag.NORMAL:
|
||||
return 'primary'
|
||||
case UserRiskTag.TRUST:
|
||||
return 'success'
|
||||
case UserRiskTag.SUSPICIOUS:
|
||||
return 'warning'
|
||||
case UserRiskTag.RISK:
|
||||
return 'danger'
|
||||
default:
|
||||
return 'primary'
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleClick() {
|
||||
|
|
|
@ -23,6 +23,56 @@ import "quill/dist/quill.core.css";
|
|||
import "quill/dist/quill.snow.css";
|
||||
import "quill/dist/quill.bubble.css";
|
||||
import { getToken } from "@/utils/auth";
|
||||
import axios from 'axios';
|
||||
|
||||
// 自定义图片处理模块
|
||||
class ImageHandler {
|
||||
constructor(quill) {
|
||||
this.quill = quill;
|
||||
this.handlePaste = this.handlePaste.bind(this);
|
||||
this.quill.root.addEventListener('paste', this.handlePaste);
|
||||
}
|
||||
|
||||
handlePaste(e) {
|
||||
const clipboardData = e.clipboardData;
|
||||
if (!clipboardData || !clipboardData.items) return;
|
||||
|
||||
const items = clipboardData.items;
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (items[i].type.indexOf('image') !== -1) {
|
||||
e.preventDefault();
|
||||
const file = items[i].getAsFile();
|
||||
this.upload(file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
upload(file) {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
|
||||
axios.post(process.env.VUE_APP_BASE_API + "/common/upload", formData, {
|
||||
headers: {
|
||||
Authorization: "Bearer " + getToken(),
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
}).then(response => {
|
||||
const res = response.data;
|
||||
if (res.code === 200) {
|
||||
const range = this.quill.getSelection(true);
|
||||
this.quill.insertEmbed(range.index, 'image', res.url);
|
||||
} else {
|
||||
this.$message.error('图片上传失败');
|
||||
}
|
||||
}).catch(() => {
|
||||
this.$message.error('图片上传失败');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 注册自定义模块
|
||||
Quill.register('modules/imageHandler', ImageHandler);
|
||||
|
||||
export default {
|
||||
name: "Editor",
|
||||
|
@ -60,7 +110,7 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
uploadUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
|
||||
uploadUrl: process.env.VUE_APP_BASE_API + "/common/upload",
|
||||
headers: {
|
||||
Authorization: "Bearer " + getToken()
|
||||
},
|
||||
|
@ -71,23 +121,27 @@ export default {
|
|||
bounds: document.body,
|
||||
debug: "warn",
|
||||
modules: {
|
||||
// 工具栏配置
|
||||
toolbar: [
|
||||
["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线
|
||||
["blockquote", "code-block"], // 引用 代码块
|
||||
[{ list: "ordered" }, { list: "bullet" }], // 有序、无序列表
|
||||
[{ indent: "-1" }, { indent: "+1" }], // 缩进
|
||||
[{ size: ["small", false, "large", "huge"] }], // 字体大小
|
||||
[{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题
|
||||
[{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色
|
||||
[{ align: [] }], // 对齐方式
|
||||
["clean"], // 清除文本格式
|
||||
["link", "image", "video"] // 链接、图片、视频
|
||||
["bold", "italic", "underline", "strike"],
|
||||
["blockquote", "code-block"],
|
||||
[{ list: "ordered" }, { list: "bullet" }],
|
||||
[{ indent: "-1" }, { indent: "+1" }],
|
||||
[{ size: ["small", false, "large", "huge"] }],
|
||||
[{ header: [1, 2, 3, 4, 5, 6, false] }],
|
||||
[{ color: [] }, { background: [] }],
|
||||
[{ align: [] }],
|
||||
["clean"],
|
||||
["link", "image", "video"]
|
||||
],
|
||||
clipboard: {
|
||||
matchVisual: false,
|
||||
matchers: []
|
||||
},
|
||||
imageHandler: true
|
||||
},
|
||||
placeholder: "请输入内容",
|
||||
readOnly: this.readOnly,
|
||||
},
|
||||
readOnly: this.readOnly
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -117,27 +171,50 @@ export default {
|
|||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
// 使用 MutationObserver 监听内容变化
|
||||
if (this.$refs.editor) {
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
mutations.forEach((mutation) => {
|
||||
if (mutation.type === 'childList' || mutation.type === 'characterData') {
|
||||
this.$nextTick(() => {
|
||||
const html = this.$refs.editor.children[0].innerHTML;
|
||||
if (html !== this.currentValue) {
|
||||
this.currentValue = html;
|
||||
this.$emit("input", html);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
observer.observe(this.$refs.editor.children[0], {
|
||||
childList: true,
|
||||
characterData: true,
|
||||
subtree: true
|
||||
});
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
// 清理 MutationObserver
|
||||
if (this._observer) {
|
||||
this._observer.disconnect();
|
||||
}
|
||||
this.Quill = null;
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
const editor = this.$refs.editor;
|
||||
this.Quill = new Quill(editor, this.options);
|
||||
|
||||
// 如果设置了上传地址则自定义图片上传事件
|
||||
if (this.type == 'url') {
|
||||
let toolbar = this.Quill.getModule("toolbar");
|
||||
toolbar.addHandler("image", (value) => {
|
||||
if (value) {
|
||||
this.$refs.upload.$children[0].$refs.input.click();
|
||||
} else {
|
||||
this.quill.format("image", false);
|
||||
}
|
||||
toolbar.addHandler("image", () => {
|
||||
this.$refs.upload.$children[0].$refs.input.click();
|
||||
});
|
||||
}
|
||||
this.Quill.pasteHTML(this.currentValue);
|
||||
this.Quill.on("text-change", (delta, oldDelta, source) => {
|
||||
|
||||
this.Quill.on('text-change', (delta, oldDelta, source) => {
|
||||
const html = this.$refs.editor.children[0].innerHTML;
|
||||
const text = this.Quill.getText();
|
||||
const quill = this.Quill;
|
||||
|
@ -145,15 +222,6 @@ export default {
|
|||
this.$emit("input", html);
|
||||
this.$emit("on-change", { html, text, quill });
|
||||
});
|
||||
this.Quill.on("text-change", (delta, oldDelta, source) => {
|
||||
this.$emit("on-text-change", delta, oldDelta, source);
|
||||
});
|
||||
this.Quill.on("selection-change", (range, oldRange, source) => {
|
||||
this.$emit("on-selection-change", range, oldRange, source);
|
||||
});
|
||||
this.Quill.on("editor-change", (eventName, ...args) => {
|
||||
this.$emit("on-editor-change", eventName, ...args);
|
||||
});
|
||||
},
|
||||
// 上传前校检格式和大小
|
||||
handleBeforeUpload(file) {
|
||||
|
@ -192,6 +260,20 @@ export default {
|
|||
handleUploadError() {
|
||||
this.$message.error("图片插入失败");
|
||||
},
|
||||
// 添加 base64 转 Blob 的辅助方法
|
||||
base64ToBlob(base64) {
|
||||
return new Promise((resolve) => {
|
||||
const arr = base64.split(',');
|
||||
const mime = arr[0].match(/:(.*?);/)[1];
|
||||
const bstr = atob(arr[1]);
|
||||
let n = bstr.length;
|
||||
const u8arr = new Uint8Array(n);
|
||||
while (n--) {
|
||||
u8arr[n] = bstr.charCodeAt(n);
|
||||
}
|
||||
resolve(new Blob([u8arr], { type: mime }));
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -341,3 +341,12 @@ export const VipOrderStatus = {
|
|||
SUCCESS: "2", // 支付成功
|
||||
CANCEL: "3", // 已取消
|
||||
}
|
||||
|
||||
// 用户风控标签
|
||||
export const UserRiskTag = {
|
||||
NORMAL: "1", // 正常
|
||||
TRUST: "2", // 信任
|
||||
SUSPICIOUS: "3", // 可疑
|
||||
RISK: "4", // 风险
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
// 获取微信小程序外链
|
||||
import {tansParams} from "@/utils/ruoyi";
|
||||
import { tansParams } from "@/utils/ruoyi";
|
||||
|
||||
export function getWxSchemeUrl(path, query) {
|
||||
return `${process.env.VUE_APP_WX_DEVICE_URL}&path=${path}&query=${encodeURIComponent(query)}`;
|
||||
}
|
||||
|
||||
export function getWxIndexUrl(query) {
|
||||
let url = `https://kg.chuantewulian.cn/w`;
|
||||
export function getWxIndexUrl(url, query) {
|
||||
if (query != null ) {
|
||||
if (query instanceof Object) {
|
||||
query = tansParams(query).slice(0, -1);
|
||||
|
@ -19,8 +18,7 @@ export function getWxIndexUrl(query) {
|
|||
}
|
||||
|
||||
// 获取合伙人外链
|
||||
export function getStaffUrl(query) {
|
||||
let url = `https://kg.chuangtewl.com/h`;
|
||||
export function getStaffUrl(url, query) {
|
||||
if (query != null ) {
|
||||
if (query instanceof Object) {
|
||||
query = tansParams(query).slice(0, -1);
|
||||
|
|
|
@ -124,46 +124,56 @@
|
|||
<!-- 添加或修改APP信息对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="6em">
|
||||
<el-form-item label="应用名称" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入应用名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="应用类型" prop="type">
|
||||
<el-select v-model="form.type" placeholder="请选择应用类型" style="width: 100%">
|
||||
<el-option v-for="item of dict.type.app_type" :key="item.value" :label="item.label" :value="item.value"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-row>
|
||||
<form-col :span="span" label="应用名称" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入应用名称" />
|
||||
</form-col>
|
||||
<form-col :span="span" label="应用类型" prop="type">
|
||||
<el-select v-model="form.type" placeholder="请选择应用类型" style="width: 100%">
|
||||
<el-option v-for="item of dict.type.app_type" :key="item.value" :label="item.label" :value="item.value"/>
|
||||
</el-select>
|
||||
</form-col>
|
||||
|
||||
<!-- 微信配置 -->
|
||||
<template v-if="form.type === AppType.WECHAT">
|
||||
<el-form-item label="应用ID" prop="config.appId">
|
||||
<el-input v-model="form.config.appId" placeholder="请输入应用ID" />
|
||||
</el-form-item>
|
||||
<el-form-item label="应用秘钥" prop="config.appSecret">
|
||||
<el-input v-model="form.config.appSecret" placeholder="请输入应用秘钥" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<!-- 支付宝配置 -->
|
||||
<template v-else-if="form.type === AppType.ALI_PAY">
|
||||
<form-col :span="24" label="应用ID" prop="config.appId">
|
||||
<!-- 微信配置 -->
|
||||
<template v-if="form.type === AppType.WECHAT">
|
||||
<form-col :span="span" label="应用ID" prop="config.appId">
|
||||
<el-input v-model="form.config.appId" placeholder="请输入应用ID" />
|
||||
</form-col>
|
||||
<form-col :span="span" label="应用秘钥" prop="config.appSecret">
|
||||
<el-input v-model="form.config.appSecret" placeholder="请输入应用秘钥" />
|
||||
</form-col>
|
||||
</template>
|
||||
|
||||
<!-- 支付宝配置 -->
|
||||
<template v-else-if="form.type === AppType.ALI_PAY">
|
||||
<form-col :span="span" label="应用ID" prop="config.appId">
|
||||
<el-input v-model="form.config.appId" placeholder="请输入应用ID" />
|
||||
</form-col>
|
||||
<form-col :span="span" label="应用私钥" prop="config.privateKey">
|
||||
<el-input v-model="form.config.privateKey" placeholder="请输入应用私钥" type="textarea" />
|
||||
</form-col>
|
||||
<form-col :span="span" label="应用公钥证书地址" prop="config.appCertPath" label-width="9em">
|
||||
<el-input v-model="form.config.appCertPath" placeholder="请输入应用公钥证书地址" />
|
||||
</form-col>
|
||||
<form-col :span="span" label="支付宝公钥证书地址" prop="config.alipayCertPath" label-width="10em">
|
||||
<el-input v-model="form.config.alipayCertPath" placeholder="请输入支付宝公钥证书地址" />
|
||||
</form-col>
|
||||
<form-col :span="span" label="支付宝根证书地址" prop="config.alipayRootCertPath" label-width="9em">
|
||||
<el-input v-model="form.config.alipayRootCertPath" placeholder="请输入支付宝根证书地址" />
|
||||
</form-col>
|
||||
<form-col :span="span" label="AES秘钥" prop="config.aesPrivateKey">
|
||||
<el-input v-model="form.config.aesPrivateKey" placeholder="请输入AES秘钥" />
|
||||
</form-col>
|
||||
</template>
|
||||
|
||||
<form-col :span="span" label="SN前缀" prop="snPrefix">
|
||||
<el-input v-model="form.snPrefix" placeholder="请输入SN前缀" />
|
||||
</form-col>
|
||||
<form-col :span="24" label="应用私钥" prop="config.privateKey">
|
||||
<el-input v-model="form.config.privateKey" placeholder="请输入应用私钥" type="textarea" />
|
||||
<form-col :span="span" label="合伙人前缀" prop="staffPrefix">
|
||||
<el-input v-model="form.staffPrefix" placeholder="请输入合伙人前缀" />
|
||||
</form-col>
|
||||
<form-col :span="24" label="应用公钥证书地址" prop="config.appCertPath" label-width="9em">
|
||||
<el-input v-model="form.config.appCertPath" placeholder="请输入应用公钥证书地址" />
|
||||
</form-col>
|
||||
<form-col :span="24" label="支付宝公钥证书地址" prop="config.alipayCertPath" label-width="10em">
|
||||
<el-input v-model="form.config.alipayCertPath" placeholder="请输入支付宝公钥证书地址" />
|
||||
</form-col>
|
||||
<form-col :span="24" label="支付宝根证书地址" prop="config.alipayRootCertPath" label-width="9em">
|
||||
<el-input v-model="form.config.alipayRootCertPath" placeholder="请输入支付宝根证书地址" />
|
||||
</form-col>
|
||||
<form-col :span="24" label="AES秘钥" prop="config.aesPrivateKey">
|
||||
<el-input v-model="form.config.aesPrivateKey" placeholder="请输入AES秘钥" />
|
||||
</form-col>
|
||||
</template>
|
||||
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
|
@ -190,12 +200,15 @@ export default {
|
|||
dicts: ['app_type'],
|
||||
data() {
|
||||
return {
|
||||
span: 24,
|
||||
AppType,
|
||||
// 字段列表
|
||||
columns: [
|
||||
{key: 'id', visible: true, label: 'ID', minWidth: null, sortable: true, overflow: false, align: 'center', width: "80"},
|
||||
{key: 'name', visible: true, label: '应用名称', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'type', visible: true, label: '应用类型', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'snPrefix', visible: true, label: 'SN前缀', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'staffPrefix', visible: true, label: '合伙人前缀', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'createTime', visible: true, label: '创建时间', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
],
|
||||
// 排序方式
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
<dict-tag :options="dict.type.risk_type" :value="d.row[column.key]"/>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'userId'">
|
||||
<user-link :id="d.row.userId" :name="d.row.userName" />
|
||||
<user-link :id="d.row.userId" :name="d.row.userName" :risk-tag="d.row.userRiskTag"/>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'verifyStatus'">
|
||||
<dict-tag :value="d.row.verifyStatus" :options="dict.type.risk_info_status"/>
|
||||
|
|
|
@ -101,7 +101,7 @@
|
|||
<dict-tag :options="dict.type.risk_info_status" :value="d.row[column.key]"/>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'userName'">
|
||||
<user-link :id="d.row.userId" :name="d.row.userName"/>
|
||||
<user-link :id="d.row.userId" :name="d.row.userName" :risk-tag="d.row.userRiskTag"/>
|
||||
</template>
|
||||
<template v-else-if="['idCardFront', 'idCardBack', 'idCardHand', 'businessLicence'].includes(column.key)">
|
||||
<image-preview :src="d.row[column.key]" :width="50" :height="50"/>
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
</template>
|
||||
<template v-else-if="column.key === 'userId'">
|
||||
<user-link v-if="d.row.userId != null" :id="d.row.userId" :name="d.row.userName"/>
|
||||
<template v-else>
|
||||
<!-- <template v-else>
|
||||
<el-popover
|
||||
placement="top"
|
||||
width="180"
|
||||
|
@ -86,7 +86,7 @@
|
|||
</div>
|
||||
<el-button slot="reference" type="text" icon="el-icon-picture">绑定二维码</el-button>
|
||||
</el-popover>
|
||||
</template>
|
||||
</template> -->
|
||||
</template>
|
||||
<template v-else-if="column.key === 'storeName'">
|
||||
<store-link :id="d.row.storeId" :name="d.row.storeName"/>
|
||||
|
|
74
src/views/system/device/components/DeviceSn.vue
Normal file
74
src/views/system/device/components/DeviceSn.vue
Normal file
|
@ -0,0 +1,74 @@
|
|||
<template>
|
||||
<el-popover
|
||||
placement="top"
|
||||
width="400"
|
||||
trigger="hover">
|
||||
<div class="qr-code-box">
|
||||
<el-tabs tab-position="left">
|
||||
<template v-for="app in appList" >
|
||||
<el-tab-pane :key="app.id" :label="app.name" v-if="app.snPrefix != null">
|
||||
<qr-code :text="qrCodeText(app.snPrefix)" :width="150" :height="150" />
|
||||
<div>{{sn | defaultValue}}</div>
|
||||
</el-tab-pane>
|
||||
</template>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<template #reference>
|
||||
<slot>
|
||||
<el-button type="text" icon="el-icon-picture">查看</el-button>
|
||||
</slot>
|
||||
</template>
|
||||
</el-popover>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getWxIndexUrl } from '@/utils/wx';
|
||||
import { listAllApp } from '@/api/ss/app';
|
||||
import QrCode from '@/components/QrCode/index.vue'
|
||||
export default {
|
||||
name: 'DeviceSn',
|
||||
components: {
|
||||
QrCode
|
||||
},
|
||||
props: {
|
||||
sn: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
appList: [], // APP信息列表
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 二维码文本
|
||||
qrCodeText() {
|
||||
return (url) => {
|
||||
if (url == null) {
|
||||
return "";
|
||||
}
|
||||
return getWxIndexUrl(url, { s: this.sn});
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.getAppList();
|
||||
},
|
||||
methods: {
|
||||
// 获取APP信息列表
|
||||
getAppList() {
|
||||
listAllApp().then(res => {
|
||||
this.appList = res.data;
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.qr-code-box {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
|
@ -8,20 +8,6 @@
|
|||
<image-preview v-else :src="scope.row.customPicture" :width="50" :height="50"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="二维码" align="center" width="80">
|
||||
<template slot-scope="d">
|
||||
<el-popover
|
||||
placement="top"
|
||||
width="180"
|
||||
trigger="hover">
|
||||
<div class="qr-code-box">
|
||||
<qr-code :text="qrCodeText(d.row)" :width="150" :height="150" />
|
||||
<div>{{d.row.deviceNo | defaultValue}}</div>
|
||||
</div>
|
||||
<el-button slot="reference" type="text" icon="el-icon-picture">查看</el-button>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="MAC-1" align="center" prop="mac" min-width="100" v-if="isAdmin">
|
||||
<device-link slot-scope="d" :text="d.row.mac" :id="d.row.deviceId"/>
|
||||
</el-table-column>
|
||||
|
@ -125,12 +111,6 @@ export default {
|
|||
DeviceServiceMode() {
|
||||
return DeviceServiceMode
|
||||
},
|
||||
// 二维码文本
|
||||
qrCodeText() {
|
||||
return (device) => {
|
||||
return getWxIndexUrl({ s: device.deviceNo});
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
isEmpty,
|
||||
|
@ -143,8 +123,5 @@ export default {
|
|||
</script>
|
||||
|
||||
<style scoped>
|
||||
.qr-code-box {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
|
@ -28,16 +28,9 @@
|
|||
<el-button size="small" plain type="warning" icon="el-icon-switch-button" v-if="!isOpen" @click="handleSwitch(true)">强制开启</el-button>
|
||||
<el-button size="small" plain type="warning" icon="el-icon-switch-button" v-if="isOpen" @click="handleSwitch(false)">强制关闭</el-button>
|
||||
<el-button size="small" plain icon="el-icon-refresh" @click="refreshIot(deviceId, true, DeviceOnlineType.COMMAND)">刷新设备信息</el-button>
|
||||
<el-popover
|
||||
placement="left"
|
||||
width="180"
|
||||
trigger="click">
|
||||
<div class="qr-code-box">
|
||||
<qr-code :text="qrCodeText(deviceData)" :width="150" :height="150" />
|
||||
<div>{{deviceData.deviceNo | defaultValue}}</div>
|
||||
</div>
|
||||
<el-button size="small" slot="reference" type="primary" icon="el-icon-picture" style="margin-left: 0.5em">设备二维码</el-button>
|
||||
</el-popover>
|
||||
<device-sn :sn="deviceData.deviceNo">
|
||||
<el-button size="small" type="primary" icon="el-icon-picture" style="margin-left: 0.5em">设备二维码</el-button>
|
||||
</device-sn>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
|
@ -368,6 +361,7 @@ import LineField from '@/components/LineField/index.vue'
|
|||
import DeviceSetWifiDialog from '@/views/system/device/components/DeviceSetWifiDialog.vue'
|
||||
import CommandLog from "@/views/ss/commandLog/index.vue";
|
||||
import DotStatus from '@/components/DotStatus/index.vue'
|
||||
import DeviceSn from '@/views/system/device/components/DeviceSn.vue'
|
||||
|
||||
export default {
|
||||
name: 'Device/:deviceId',
|
||||
|
@ -384,7 +378,7 @@ export default {
|
|||
UserLink,
|
||||
StoreLink,
|
||||
RecordTime,
|
||||
Suit, ResetRecord, BindRecord, ReadingRecord, MeterRecordReport, QrCode, RechargeRecord, LineChart, DotStatus},
|
||||
Suit, ResetRecord, BindRecord, ReadingRecord, MeterRecordReport, QrCode, RechargeRecord, LineChart, DotStatus, DeviceSn},
|
||||
data() {
|
||||
return {
|
||||
showSetWifi: false,
|
||||
|
|
|
@ -183,10 +183,10 @@
|
|||
<model-select v-model="form.modelId" :show-value.sync="form.model" @submit="onSubmitModel"/>
|
||||
</form-col>
|
||||
<form-col :span="span" label="MAC-1" prop="mac">
|
||||
<el-input v-model="form.mac" placeholder="请输入设备MAC-1" :disabled="isEdit"/>
|
||||
<el-input v-model="form.mac" placeholder="请输入设备MAC-1"/>
|
||||
</form-col>
|
||||
<form-col :span="span" label="MAC-2" prop="mac2">
|
||||
<el-input v-model="form.mac2" placeholder="请输入设备MAC-2" :disabled="isEdit"/>
|
||||
<el-input v-model="form.mac2" placeholder="请输入设备MAC-2"/>
|
||||
</form-col>
|
||||
<form-col :span="span" label="SN" prop="deviceNo">
|
||||
<el-input v-model="form.deviceNo" placeholder="请输入设备SN" />
|
||||
|
@ -277,6 +277,7 @@ import { $serviceType, $view } from '@/utils/mixins'
|
|||
import ModelSimpleSelect from '@/components/Business/Model/ModelSimpleSelect.vue'
|
||||
import { DeviceServiceMode, SmUserType } from '@/utils/constants'
|
||||
import DeviceTable from '@/views/system/device/components/DeviceTable.vue'
|
||||
import { listAllApp } from '@/api/ss/app';
|
||||
|
||||
export default {
|
||||
name: "Device",
|
||||
|
|
|
@ -147,16 +147,16 @@
|
|||
<recharge-link :bill-id="d.row.billId" :text="d.row.billNo"/>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'userName'">
|
||||
<user-link :id="d.row.userId" :name="d.row.userName"/><br/>
|
||||
<user-link :id="d.row.userId" :name="d.row.userMobile"/>
|
||||
<user-link :id="d.row.userId" :name="d.row.userName" :risk-tag="d.row.userRiskTag"/><br/>
|
||||
<user-link :id="d.row.userId" :name="d.row.userMobile" :risk-tag="d.row.userRiskTag"/>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'deviceName'">
|
||||
<device-link :id="d.row.deviceId" :text="d.row.deviceName"/><br/>
|
||||
<device-link :id="d.row.deviceId" :text="d.row.deviceNo"/>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'mchName'">
|
||||
<user-link :id="d.row.mchId" :name="d.row.mchName"/><br/>
|
||||
<user-link :id="d.row.mchId" :name="d.row.mchMobile"/>
|
||||
<user-link :id="d.row.mchId" :name="d.row.mchName" :risk-tag="d.row.mchRiskTag"/><br/>
|
||||
<user-link :id="d.row.mchId" :name="d.row.mchMobile" :risk-tag="d.row.mchRiskTag"/>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'storeId'">
|
||||
<store-link :id="d.row.storeId" :name="d.row.storeName"/>
|
||||
|
|
|
@ -133,7 +133,7 @@
|
|||
<el-card class="box-card">
|
||||
<el-descriptions title="支付方信息" :column="1">
|
||||
<el-descriptions-item label="用户名称">
|
||||
<user-link :id="detail.userId" :name="detail.userName"/>
|
||||
<user-link :id="detail.userId" :name="detail.userName" :risk-tag="detail.userRiskTag"/>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="支付渠道">
|
||||
{{detail.channelName | defaultValue}}
|
||||
|
@ -145,10 +145,10 @@
|
|||
<el-card class="box-card">
|
||||
<el-descriptions title="收款方信息" :column="1">
|
||||
<el-descriptions-item label="代理商" v-if="DeviceServiceMode.AGENT === detail.deviceServiceMode">
|
||||
<user-link :id="detail.agentId" :name="detail.agentMobile"/>
|
||||
<user-link :id="detail.agentId" :name="detail.agentMobile" :risk-tag="detail.agentRiskTag"/>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="商户">
|
||||
<user-link :id="detail.mchId" :name="detail.mchName"/>
|
||||
<user-link :id="detail.mchId" :name="detail.mchName" :risk-tag="detail.mchRiskTag"/>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="商户手机号">{{detail.mchMobile | defaultValue}}</el-descriptions-item>
|
||||
<el-descriptions-item label="店铺名称">
|
||||
|
|
|
@ -64,6 +64,11 @@
|
|||
</el-row>
|
||||
<el-row>
|
||||
<group-title title="风控配置"/>
|
||||
<form-col :span="span" label="风控标签" prop="riskTag" label-width="6em" tip="请选择风控标签">
|
||||
<el-select v-model="form.riskTag" placeholder="请选择风控标签" clearable style="width: 100%">
|
||||
<el-option v-for="item of dict.type.user_risk_tag" :key="item.value" :label="item.label" :value="item.value"/>
|
||||
</el-select>
|
||||
</form-col>
|
||||
<form-col :span="span" label="充值延迟到账" prop="arrivalDelay" label-width="7em" tip="开启后,该用户的收益将延迟到账">
|
||||
<el-input v-model="form.arrivalDelay" placeholder="请输入到账延迟时长">
|
||||
<template #append>小时</template>
|
||||
|
@ -102,7 +107,7 @@
|
|||
|
||||
<script>
|
||||
import { addSmUser, getSmUser, updateSmUser } from '@/api/system/smUser'
|
||||
import { SmUserType } from '@/utils/constants'
|
||||
import { SmUserType, UserRiskTag } from '@/utils/constants'
|
||||
import { $withdrawServiceType } from '@/utils/mixins'
|
||||
import ChannelInput from '@/components/Business/Channel/ChannelInput.vue'
|
||||
import AppInput from '@/components/Business/App/AppInput.vue'
|
||||
|
@ -111,7 +116,7 @@ import GroupTitle from '@/components/GroupTitle/index.vue'
|
|||
export default {
|
||||
name: "UserFormDialog",
|
||||
mixins: [$withdrawServiceType],
|
||||
dicts: ['sm_user_status', 'sm_user_type', 'sys_user_sex', 'service_type', 'withdraw_service_type'],
|
||||
dicts: ['sm_user_status', 'sm_user_type', 'sys_user_sex', 'service_type', 'withdraw_service_type', 'user_risk_tag'],
|
||||
components: { ChannelInput, AppInput, GroupTitle },
|
||||
props: {
|
||||
show: {
|
||||
|
@ -148,6 +153,9 @@ export default {
|
|||
agentServiceRate: [
|
||||
{ required: true, message: '请输入代理服务费', trigger: 'change' }
|
||||
],
|
||||
riskTag: [
|
||||
{ required: true, message: '请选择风控标签', trigger: 'change' }
|
||||
],
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -186,7 +194,8 @@ export default {
|
|||
channelIds: [],
|
||||
showBillMobile: false,
|
||||
showBillMobilePrice: 0,
|
||||
enabledRenew: true
|
||||
enabledRenew: true,
|
||||
riskTag: UserRiskTag.NORMAL
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.$refs.form && this.$refs.form.clearValidate()
|
||||
|
|
|
@ -33,10 +33,8 @@
|
|||
<el-avatar :size="64" :src="detail.avatar"></el-avatar>
|
||||
<el-row type="flex" class="name-box">
|
||||
<span class="user-name">{{ detail.realOrUserName }}</span>
|
||||
<dict-tag
|
||||
:value="detail.type"
|
||||
:options="dict.type.sm_user_type"
|
||||
/>
|
||||
<dict-tag :value="detail.riskTag" :options="dict.type.user_risk_tag" />
|
||||
<dict-tag :value="detail.type" :options="dict.type.sm_user_type" />
|
||||
</el-row>
|
||||
<div class="phone-number">{{ !isEmpty(detail.phonenumber) ? detail.phonenumber : '未绑定手机' }}</div>
|
||||
</div>
|
||||
|
@ -45,6 +43,9 @@
|
|||
<el-descriptions-item label="充值服务费">
|
||||
{{ detail.realServiceRate | money | defaultValue }} %
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="VIP服务费">
|
||||
{{ detail.vipServiceRate | money | defaultValue }} %
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="代理服务费">
|
||||
{{ detail.agentServiceRate | money | defaultValue }} %
|
||||
</el-descriptions-item>
|
||||
|
@ -67,7 +68,6 @@
|
|||
</template>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="所属应用">{{ detail.appName | dv }}</el-descriptions-item>
|
||||
<el-descriptions-item label="实名认证">
|
||||
<boolean-tag :value="detail.isReal" size="small" />
|
||||
<el-link
|
||||
|
@ -89,8 +89,9 @@
|
|||
<el-descriptions-item label="实名手机">
|
||||
{{ detail.realPhone | defaultValue }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="注册时间">{{ detail.createTime | dv }}</el-descriptions-item>
|
||||
<el-descriptions-item label="所属应用">{{ detail.appName | dv }}</el-descriptions-item>
|
||||
<el-descriptions-item label="开放平台ID" :span="2">{{ detail.wxOpenId | dv }}</el-descriptions-item>
|
||||
<el-descriptions-item label="注册时间" :span="2">{{ detail.createTime | dv }}</el-descriptions-item>
|
||||
<el-descriptions-item label="备注" :span="2">{{detail.remark | defaultValue}}</el-descriptions-item>
|
||||
<el-descriptions-item label="专属渠道" :span="2">
|
||||
<el-tag type="success" v-for="item in detail.channelList" :key="item.channelId" size="mini">{{ item.name }}</el-tag>
|
||||
|
@ -184,6 +185,12 @@
|
|||
<el-tab-pane label="店铺列表" lazy>
|
||||
<store :query="{ userId: detail.userId }" :view="views.user" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="合伙人列表" lazy>
|
||||
<store-staff :query="{ mchId: detail.userId }" :view="views.user" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="合伙店铺" lazy>
|
||||
<store-staff :query="{ userId: detail.userId }" :view="views.user" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="套餐列表" lazy>
|
||||
<suit :query="{ userId: detail.userId }" :view="views.user" />
|
||||
</el-tab-pane>
|
||||
|
@ -227,10 +234,7 @@
|
|||
<real-name :query="{ userId: detail.userId }" :view="views.user" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="绑定记录" lazy>
|
||||
<bind-record
|
||||
:query="{ userId: detail.userId }"
|
||||
:view="views.user"
|
||||
/>
|
||||
<bind-record :query="{ userId: detail.userId }" :view="views.user"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="收款账户" lazy>
|
||||
<account :query="{ userId: detail.userId }" :view="views.user" />
|
||||
|
@ -286,10 +290,12 @@ import RiskInfo from '@/views/ss/riskInfo/index.vue'
|
|||
import BindRecord from '@/views/system/bindRecord/index.vue'
|
||||
import UserFormDialog from '@/views/system/smUser/components/UserFormDialog.vue'
|
||||
import {isEmpty} from '@/utils/index'
|
||||
import StoreStaff from '@/views/ss/storeStaff/index.vue'
|
||||
|
||||
export default {
|
||||
name: 'User/:userId',
|
||||
mixins: [$view, $serviceType],
|
||||
dicts: ['sm_user_type', 'service_type', 'withdraw_service_type'],
|
||||
dicts: ['sm_user_type', 'service_type', 'withdraw_service_type', 'user_risk_tag'],
|
||||
components: {
|
||||
BindRecord,
|
||||
RiskInfo,
|
||||
|
@ -312,7 +318,8 @@ export default {
|
|||
UserAccount,
|
||||
UserDevice,
|
||||
LineChart,
|
||||
UserFormDialog
|
||||
UserFormDialog,
|
||||
StoreStaff
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
|
@ -62,6 +62,11 @@
|
|||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="风控标签" prop="riskTag" v-if="isShow('realOrUserName')">
|
||||
<el-select v-model="queryParams.riskTag" placeholder="请选择风控标签" clearable @change="handleQuery">
|
||||
<el-option v-for="item of dict.type.user_risk_tag" :key="item.value" :label="item.label" :value="item.value"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
|
@ -122,7 +127,7 @@
|
|||
<user-link :id="d.row.userId" :name="d.row.phonenumber"/>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'realOrUserName'">
|
||||
<user-link :id="d.row.userId" :name="d.row.realOrUserName"/>
|
||||
<user-link :id="d.row.userId" :name="d.row.realOrUserName" :risk-tag="d.row.riskTag"/>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'storeCount'">
|
||||
{{d.row.storeCount | defaultValue}} 家
|
||||
|
@ -254,7 +259,7 @@ export default {
|
|||
name: "SmUser",
|
||||
mixins: [$showColumns, $serviceType, $withdrawServiceType],
|
||||
components: { BooleanTag, UserConfigDialog, UserLink, UserFormDialog },
|
||||
dicts: ['sm_user_status', 'sm_user_type', 'sys_user_sex', 'service_type', 'withdraw_service_type'],
|
||||
dicts: ['sm_user_status', 'sm_user_type', 'sys_user_sex', 'service_type', 'withdraw_service_type', 'user_risk_tag'],
|
||||
computed: {
|
||||
SmUserType() {
|
||||
return SmUserType
|
||||
|
|
Loading…
Reference in New Issue
Block a user