parent
5eca01278b
commit
59e73fa83e
@ -0,0 +1,649 @@ |
||||
<template> |
||||
<el-main> |
||||
<el-dialog :close-on-click-modal="false" :destroy-on-close="true" :title="title" |
||||
:visible.sync="dialogReceiverVisible" width="780px"> |
||||
|
||||
<el-form ref="recevierform" :model="addreceiverinfo" |
||||
label-width="80px" style="margin:0 auto;"> |
||||
|
||||
|
||||
<el-form-item label="姓名"> |
||||
<el-input v-model="addreceiverinfo.receiver_name"/> |
||||
</el-form-item> |
||||
|
||||
<el-form-item label="邮箱"> |
||||
<el-input v-model="addreceiverinfo.email"/> |
||||
</el-form-item> |
||||
|
||||
|
||||
<!-- <el-form-item v-if="captcha.captcha_image" style="height: 40px" >--> |
||||
<!-- <el-row style="height: 40px">--> |
||||
<!-- <el-col :span="16">--> |
||||
<!-- <el-input v-model="addreceiverinfo.verify_code" clearable maxlength="6"--> |
||||
<!-- placeholder="请输入验证码" @keyup.enter.native="onSubmit"/>--> |
||||
<!-- </el-col>--> |
||||
<!-- <el-col :span="8">--> |
||||
<!-- <el-image--> |
||||
<!-- :src="captcha.captcha_image"--> |
||||
<!-- fit="contain"--> |
||||
<!-- style="margin:0 4px;border-radius:4px;cursor:pointer;height: 40px" @click="get_auth_code">--> |
||||
<!-- </el-image>--> |
||||
<!-- </el-col>--> |
||||
<!-- </el-row>--> |
||||
<!-- </el-form-item>--> |
||||
|
||||
<!-- <el-form-item>--> |
||||
<!-- <el-row>--> |
||||
<!-- <el-col :span="16">--> |
||||
<!-- <el-input v-model="addreceiverinfo.seicode" clearable--> |
||||
<!-- placeholder="邮箱验证码" prefix-icon="el-icon-mobile"/>--> |
||||
<!-- </el-col>--> |
||||
<!-- <el-col :span="8">--> |
||||
<!-- <el-button plain style="margin:0 4px;border-radius:4px;cursor:pointer;height: 40px" type="info"--> |
||||
<!-- @click="onGetCode">获取验证码--> |
||||
<!-- </el-button>--> |
||||
<!-- </el-col>--> |
||||
<!-- </el-row>--> |
||||
<!-- </el-form-item>--> |
||||
|
||||
<!-- <el-form-item>--> |
||||
<!-- <div id="captcha" ref="captcha"></div>--> |
||||
<!-- </el-form-item>--> |
||||
|
||||
|
||||
<el-form-item label="微信"> |
||||
<el-tag v-if="addreceiverinfo.wxopenid && addreceiverinfo.wxopenid.length > 6"> |
||||
{{ addreceiverinfo.wxopenid }} |
||||
</el-tag> |
||||
<el-popover v-else |
||||
v-model="wx_visible" |
||||
placement="top" |
||||
title="打开微信扫一扫进行绑定" |
||||
trigger="manual"> |
||||
<div> |
||||
<el-image :src="wx_login_qr_url" style="width: 176px;height: 166px"/> |
||||
</div> |
||||
<el-button slot="reference" size="small" @click="wxLogin">绑定微信</el-button> |
||||
</el-popover> |
||||
</el-form-item> |
||||
|
||||
<el-form-item label="备注"> |
||||
<el-input v-model="addreceiverinfo.description"/> |
||||
</el-form-item> |
||||
|
||||
<el-button @click="saveReceiver">保存</el-button> |
||||
<el-button @click="cancelReceiver">取消</el-button> |
||||
</el-form> |
||||
</el-dialog> |
||||
|
||||
|
||||
<el-dialog :close-on-click-modal="false" :destroy-on-close="true" :visible.sync="dialogChangeReceiverVisible" |
||||
title="修改消息接收人"> |
||||
|
||||
<div style="text-align: left;margin-bottom: 10px"> |
||||
<div style="margin-bottom: 10px"> |
||||
<el-tag type="warning">提醒:如果以下消息接收人的信息有变更,请到“消息接收人管理”中进行修改。</el-tag> |
||||
</div> |
||||
消息类型:{{ notifyConfigMsg.message_type }} - {{ notifyConfigMsg.config_name }} |
||||
</div> |
||||
<el-table |
||||
ref="multipleTable" |
||||
:data="receiver_info_lists" |
||||
border |
||||
stripe |
||||
style="width: 100%" |
||||
@selection-change="handleSelectionChange"> |
||||
<el-table-column |
||||
type="selection" |
||||
width="55"> |
||||
</el-table-column> |
||||
<el-table-column |
||||
align="center" |
||||
fixed |
||||
label="姓名" |
||||
prop="receiver_name" |
||||
width="100"> |
||||
</el-table-column> |
||||
<el-table-column |
||||
align="center" |
||||
label="邮箱" |
||||
prop="email" |
||||
width="200"> |
||||
</el-table-column> |
||||
<el-table-column |
||||
align="center" |
||||
label="微信" |
||||
prop="domain_name" |
||||
width="260"> |
||||
<template slot-scope="scope"> |
||||
<el-popover v-if="scope.row.weixin.openid" placement="top" trigger="hover"> |
||||
<div style="float: right;margin-top: 10px"> |
||||
<el-image :src="scope.row.weixin.head_img_url" style="width: 80px;height: 80px"/> |
||||
</div> |
||||
<p>昵称: {{ scope.row.weixin.nickname }}</p> |
||||
<p>性别: {{ scope.row.weixin.sex|sex_filter }}</p> |
||||
<p>住址: {{ scope.row.weixin.address }}</p> |
||||
<p>微信ID: {{ scope.row.weixin.openid }}</p> |
||||
<div slot="reference" class="name-wrapper"> |
||||
<el-tag>{{ scope.row.weixin.openid }}</el-tag> |
||||
</div> |
||||
</el-popover> |
||||
<el-tag v-else> /</el-tag> |
||||
</template> |
||||
</el-table-column> |
||||
|
||||
<el-table-column |
||||
align="center" |
||||
label="备注" |
||||
prop="description"> |
||||
</el-table-column> |
||||
|
||||
</el-table> |
||||
<div style="text-align: left;margin-bottom: 10px;margin-top: 10px"> |
||||
<el-button plain size="small" type="primary" @click="addRecevier"> |
||||
新增消息接收人 |
||||
</el-button> |
||||
</div> |
||||
<span slot="footer"> |
||||
<el-button @click="updateConfig(undefined)">保存</el-button> |
||||
<el-button @click="dialogChangeReceiverVisible=false">取消</el-button> |
||||
</span> |
||||
|
||||
</el-dialog> |
||||
|
||||
|
||||
<el-tabs v-model="activeName" tab-position="top" type="border-card" @tab-click="handleClick"> |
||||
|
||||
<el-tab-pane label="基本接收管理" name="config"> |
||||
|
||||
<el-table |
||||
:data="[{name:'消息类型',email:'邮件通知',weixin:'微信通知',user:'消息接收人'}]" |
||||
:show-header="false" |
||||
border |
||||
stripe |
||||
style="width: 100%"> |
||||
<el-table-column |
||||
align="center" |
||||
prop="name" |
||||
width="200"> |
||||
</el-table-column> |
||||
<el-table-column |
||||
align="center" |
||||
prop="email" |
||||
width="200"> |
||||
</el-table-column> |
||||
<el-table-column |
||||
align="center" |
||||
prop="weixin" |
||||
width="200"> |
||||
</el-table-column> |
||||
<el-table-column |
||||
align="center" |
||||
prop="user"> |
||||
</el-table-column> |
||||
</el-table> |
||||
|
||||
<el-collapse v-model="activeConfig"> |
||||
<el-collapse-item v-for="info in message_type_choices" :key="info.id" :disabled="info.disabled" |
||||
:name="info.id"> |
||||
<template slot="title"> |
||||
<div style="width: 200px"> |
||||
<h2>{{ info.name }}</h2> |
||||
</div> |
||||
</template> |
||||
<el-table |
||||
:data="info.data" |
||||
:show-header="false" |
||||
border |
||||
stripe |
||||
style="width: 100%"> |
||||
<el-table-column |
||||
align="center" |
||||
fixed |
||||
prop="config_name" |
||||
width="200"> |
||||
</el-table-column> |
||||
<el-table-column |
||||
align="center" |
||||
fixed |
||||
prop="enable_email" |
||||
width="200"> |
||||
<template slot-scope="scope"> |
||||
<el-checkbox v-model="scope.row.enable_email" @change="updateConfig(scope.row)">邮件</el-checkbox> |
||||
</template> |
||||
</el-table-column> |
||||
|
||||
<el-table-column |
||||
align="center" |
||||
fixed |
||||
prop="enable_weixin" |
||||
width="200"> |
||||
<template slot-scope="scope"> |
||||
<el-checkbox v-model="scope.row.enable_weixin" @change="updateConfig(scope.row)">微信</el-checkbox> |
||||
</template> |
||||
</el-table-column> |
||||
|
||||
<el-table-column |
||||
align="center" |
||||
fixed |
||||
prop="senders"> |
||||
<template slot-scope="scope"> |
||||
<el-tag v-for="user in scope.row.senders" :key="user.id" style="margin-right: 3px" type="info"> |
||||
{{ user.receiver_name }} |
||||
</el-tag> |
||||
<el-tag type="success"> |
||||
<el-link :underline="false" type="success" @click="changeNotifyConfig(scope.row)">修改</el-link> |
||||
</el-tag> |
||||
</template> |
||||
</el-table-column> |
||||
|
||||
</el-table> |
||||
</el-collapse-item> |
||||
</el-collapse> |
||||
</el-tab-pane> |
||||
<el-tab-pane label="消息接收人管理" name="receiver"> |
||||
|
||||
<div style="float: right;margin-bottom: 10px"> |
||||
|
||||
<el-button plain type="primary" @click="addRecevier"> |
||||
新增消息接收人 |
||||
</el-button> |
||||
|
||||
</div> |
||||
<el-table |
||||
v-loading="loading" |
||||
:data="receiver_info_lists" |
||||
border |
||||
stripe |
||||
style="width: 100%"> |
||||
|
||||
<el-table-column |
||||
align="center" |
||||
fixed |
||||
label="姓名" |
||||
prop="receiver_name" |
||||
width="100"> |
||||
</el-table-column> |
||||
<el-table-column |
||||
align="center" |
||||
label="邮箱" |
||||
prop="email" |
||||
width="200"> |
||||
</el-table-column> |
||||
<el-table-column |
||||
align="center" |
||||
label="微信" |
||||
prop="domain_name"> |
||||
<template slot-scope="scope"> |
||||
<el-popover v-if="scope.row.weixin.openid" placement="top" trigger="hover"> |
||||
<div style="float: right;margin-top: 10px"> |
||||
<el-image :src="scope.row.weixin.head_img_url" style="width: 80px;height: 80px"/> |
||||
</div> |
||||
<p>昵称: {{ scope.row.weixin.nickname }}</p> |
||||
<p>性别: {{ scope.row.weixin.sex|sex_filter }}</p> |
||||
<p>住址: {{ scope.row.weixin.address }}</p> |
||||
<p>微信ID: {{ scope.row.weixin.openid }}</p> |
||||
<div slot="reference" class="name-wrapper"> |
||||
<el-tag>{{ scope.row.weixin.openid }}</el-tag> |
||||
</div> |
||||
</el-popover> |
||||
<el-tag v-else> /</el-tag> |
||||
</template> |
||||
</el-table-column> |
||||
|
||||
|
||||
<el-table-column |
||||
:formatter="formatter" |
||||
align="center" |
||||
label="添加时间" |
||||
prop="create_time" |
||||
width="170"> |
||||
</el-table-column> |
||||
<el-table-column |
||||
align="center" |
||||
label="备注" |
||||
prop="description"> |
||||
</el-table-column> |
||||
<el-table-column |
||||
align="center" |
||||
label="操作" |
||||
width="120"> |
||||
<template slot-scope="scope"> |
||||
<!-- <el-button size="small" type="text" @click="editReceiver(scope.row)">编辑</el-button>--> |
||||
<el-button size="small" type="text" @click="deleteReceiver(scope.row)">删除</el-button> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
</el-tab-pane> |
||||
|
||||
<el-tab-pane label="阈值设置" name="threshold" style="text-align: center"> |
||||
<el-tag style="margin: 20px 0"> 低于阈值设置,将会出发报警,若您配置了消息接收,将会将报警信息推送至关联的接收人</el-tag> |
||||
<div style="margin: auto;width: 700px;height: 100%"> |
||||
<el-form ref="form" :model="threshold" label-width="180px"> |
||||
<el-form-item label="下载次数不足阈值设置"> |
||||
<el-input-number v-model="threshold.notify_available_downloads" :min="0" |
||||
style="width: 300px;margin: 0 20px"></el-input-number> |
||||
<el-button @click="notifyThreshold('update')">保存修改</el-button> |
||||
</el-form-item> |
||||
|
||||
<el-form-item label="签名次数不足阈值设置"> |
||||
<el-input-number v-model="threshold.notify_available_signs" :min="0" |
||||
style="width: 300px;margin: 0 20px"></el-input-number> |
||||
<el-button @click="notifyThreshold('update')">保存修改</el-button> |
||||
</el-form-item> |
||||
</el-form> |
||||
</div> |
||||
|
||||
</el-tab-pane> |
||||
</el-tabs> |
||||
|
||||
</el-main> |
||||
</template> |
||||
|
||||
<script> |
||||
import {notifyConfigInfo, notifyReceiverInfo, wxBindFun, wxLoginFun} from "@/restful"; |
||||
import {getUserInfoFun} from "@/utils"; |
||||
import {getRandomStr} from "@/utils/base/utils"; |
||||
|
||||
export default { |
||||
name: "FirUserNotify", |
||||
data() { |
||||
return { |
||||
dialogReceiverVisible: false, |
||||
captcha: {"captcha_image": '', "captcha_key": '', "length": 8}, |
||||
wx_visible: false, |
||||
wx_login_qr_url: '', |
||||
unique_key: '', |
||||
userinfo: {}, |
||||
addreceiverinfo: {description: '', wxopenid: '', email: '', receiver_name: ''}, |
||||
message_type_choices: [], |
||||
activeConfig: [], |
||||
dialogChangeReceiverVisible: false, |
||||
notifyConfigSelection: [], |
||||
notifyConfigMsg: {}, |
||||
title: '', |
||||
isedit: false, |
||||
activeName: 'config', |
||||
receiver_info_lists: [], |
||||
loading: false, |
||||
threshold: {} |
||||
} |
||||
}, methods: { |
||||
addRecevier() { |
||||
this.addreceiverinfo = {description: '', wxopenid: '', email: '', receiver_name: ''} |
||||
this.dialogReceiverVisible = true |
||||
this.title = '新增消息接收人' |
||||
}, |
||||
editReceiver(receiver) { |
||||
this.title = '编辑 ' + receiver.receiver_name + ' 消息接收人' |
||||
this.isedit = true |
||||
this.addreceiverinfo = receiver |
||||
this.dialogReceiverVisible = true |
||||
}, |
||||
updateConfig(config = undefined) { |
||||
let data = {} |
||||
if (config) { |
||||
data = { |
||||
'config': config.id, |
||||
'enable_email': config.enable_email, |
||||
'enable_weixin': config.enable_weixin, |
||||
'm_type': config.message_type |
||||
} |
||||
} else { |
||||
let receiver_ids = [] |
||||
for (let receiver of this.notifyConfigSelection) { |
||||
receiver_ids.push(receiver.id) |
||||
} |
||||
data = {'config': this.notifyConfigMsg.id, 'receiver': receiver_ids, 'm_type': this.notifyConfigMsg.m_type} |
||||
} |
||||
|
||||
notifyConfigInfo(data => { |
||||
if (data.code === 1000) { |
||||
this.$message.success('保存成功') |
||||
if (!config) { |
||||
this.dialogChangeReceiverVisible = false; |
||||
} |
||||
this.notifyConfigInfoFun(); |
||||
} else { |
||||
this.$message.error('保存失败,' + data.msg); |
||||
} |
||||
}, {"methods": 'PUT', "data": data}); |
||||
}, |
||||
changeNotifyConfig(info) { |
||||
let params = {"config": info.id, "message_type": info.m_type} |
||||
this.dialogChangeReceiverVisible = true; |
||||
notifyReceiverInfo(data => { |
||||
if (data.code === 1000) { |
||||
this.receiver_info_lists = data.data; |
||||
this.notifyConfigMsg = data.config |
||||
// eslint-disable-next-line no-unused-vars |
||||
this.$nextTick(res => { |
||||
data.data.forEach(row => { |
||||
for (let sender of data.senders) { |
||||
if (sender.sender === row.id) { |
||||
this.$refs.multipleTable.toggleRowSelection(row); |
||||
} |
||||
} |
||||
}); |
||||
}) |
||||
} else { |
||||
this.$message.error('获取失败,' + data); |
||||
} |
||||
this.loading = false; |
||||
}, {"methods": 'GET', "data": params}); |
||||
|
||||
}, |
||||
handleSelectionChange(val) { |
||||
this.notifyConfigSelection = val; |
||||
}, |
||||
// eslint-disable-next-line no-unused-vars |
||||
handleClick(tab, event) { |
||||
this.get_data_from_tabname(tab.name); |
||||
}, |
||||
cancelReceiver() { |
||||
this.dialogReceiverVisible = false; |
||||
this.addreceiverinfo = {description: '', wxopenid: '', email: '', receiver_name: ''} |
||||
}, |
||||
saveReceiver() { |
||||
notifyReceiverInfo(data => { |
||||
if (data.code === 1000) { |
||||
this.$message.success('操作成功'); |
||||
this.dialogReceiverVisible = false; |
||||
if (this.dialogChangeReceiverVisible) { |
||||
this.changeNotifyConfig(this.notifyConfigMsg) |
||||
} else { |
||||
this.get_data_from_tabname(this.activeName); |
||||
} |
||||
} else { |
||||
this.$message.error('操作失败,' + data.msg); |
||||
} |
||||
}, {"methods": 'POST', 'data': this.addreceiverinfo}); |
||||
}, |
||||
deleteReceiver(sinfo) { |
||||
|
||||
this.$confirm(`将要删除接收人 ${sinfo.receiver_name}, 是否继续?`, '警告', { |
||||
confirmButtonText: '确定', |
||||
cancelButtonText: '取消', |
||||
type: 'warning' |
||||
}).then(() => { |
||||
notifyReceiverInfo(data => { |
||||
if (data.code === 1000) { |
||||
this.$message.success('删除成功'); |
||||
this.notifyReceiverInfoFun(); |
||||
} |
||||
}, {"methods": 'DELETE', 'data': {'id': sinfo.id}}) |
||||
}).catch(() => { |
||||
this.$message({ |
||||
type: 'info', |
||||
message: '已取消删除' |
||||
}); |
||||
}); |
||||
|
||||
}, |
||||
|
||||
notifyReceiverInfoFun() { |
||||
this.loading = true; |
||||
notifyReceiverInfo(data => { |
||||
if (data.code === 1000) { |
||||
this.receiver_info_lists = data.data; |
||||
} else { |
||||
this.$message.error('获取失败,' + data); |
||||
} |
||||
this.loading = false; |
||||
}, {"methods": 'GET'}); |
||||
}, |
||||
setActiveConfig(message_type_choices) { |
||||
let activeConfig = [] |
||||
for (let i of message_type_choices) { |
||||
activeConfig.push(i.id) |
||||
} |
||||
this.activeConfig = activeConfig; |
||||
}, |
||||
notifyConfigInfoFun() { |
||||
this.loading = true; |
||||
notifyConfigInfo(data => { |
||||
if (data.code === 1000) { |
||||
this.receiver_info_lists = data.data; |
||||
this.message_type_choices = data.message_type_choices; |
||||
this.setActiveConfig(this.message_type_choices); |
||||
} else { |
||||
this.$message.error('获取失败,' + data); |
||||
} |
||||
this.loading = false; |
||||
}, {"methods": 'GET'}); |
||||
}, |
||||
notifyThreshold(act) { |
||||
notifyConfigInfo(data => { |
||||
if (data.code === 1000) { |
||||
this.threshold = data.data |
||||
if (act !== 'get') { |
||||
this.$message.success('保存成功') |
||||
} |
||||
} else { |
||||
this.$message.error('获取失败,' + data); |
||||
} |
||||
this.loading = false; |
||||
}, {"methods": 'POST', 'data': {'act': act, 'threshold': this.threshold}}); |
||||
}, |
||||
|
||||
loop_get_wx_info(wx_login_ticket, c_count = 1, unique_key = getRandomStr()) { |
||||
if (wx_login_ticket && wx_login_ticket.length < 3) { |
||||
this.$message.error("获取登陆码失败,请稍后再试"); |
||||
return |
||||
} |
||||
if (!this.wx_visible) { |
||||
return; |
||||
} |
||||
wxLoginFun(data => { |
||||
c_count += 1; |
||||
if (c_count > 30) { |
||||
return; |
||||
} |
||||
if (data.code === 1000) { |
||||
if (this.userinfo.uid === data.data.uid) { |
||||
if (data.data.to_user) { |
||||
this.addreceiverinfo.wxopenid = data.data.to_user |
||||
} |
||||
this.$message.success("绑定成功"); |
||||
this.wx_visible = false; |
||||
} |
||||
} else if (data.code === 1005) { |
||||
this.$message({ |
||||
message: data.msg, |
||||
type: 'error', |
||||
duration: 30000 |
||||
}); |
||||
} else if (data.code === 1004) { |
||||
this.loop_flag = false; |
||||
} else if (data.code === 1006) { |
||||
return this.loop_get_wx_info(wx_login_ticket, c_count, unique_key) |
||||
} |
||||
}, { |
||||
"methods": "POST", |
||||
data: {"ticket": wx_login_ticket, "unique_key": unique_key} |
||||
}) |
||||
}, |
||||
wxLogin() { |
||||
this.wx_visible = !this.wx_visible; |
||||
this.wx_login_qr_url = ''; |
||||
if (this.wx_visible) { |
||||
wxBindFun(data => { |
||||
if (data.code === 1000) { |
||||
this.wx_login_qr_url = data.data.qr; |
||||
this.loop_get_wx_info(data.data.ticket); |
||||
} else { |
||||
this.$message.error(data.msg); |
||||
this.wx_visible = false; |
||||
} |
||||
}, { |
||||
"methods": "POST", "data": {"unique_key": this.unique_key, "w_type": 'notify'} |
||||
}) |
||||
} |
||||
}, |
||||
|
||||
// eslint-disable-next-line no-unused-vars |
||||
formatter(row, column) { |
||||
let stime = row.create_time; |
||||
if (stime) { |
||||
stime = stime.split(".")[0].split("T"); |
||||
return stime[0] + " " + stime[1] |
||||
} else |
||||
return ''; |
||||
}, |
||||
// eslint-disable-next-line no-unused-vars |
||||
get_data_from_tabname(tabname, data = {}) { |
||||
this.$router.push({"name": 'FirUserNotify', params: {act: tabname}}); |
||||
if (tabname === "config") { |
||||
this.notifyConfigInfoFun(); |
||||
} else if (tabname === "receiver") { |
||||
this.notifyReceiverInfoFun(); |
||||
} else if (tabname === "threshold") { |
||||
this.notifyThreshold('get'); |
||||
} |
||||
}, |
||||
}, mounted() { |
||||
getUserInfoFun(this); |
||||
this.userinfo = this.$store.state.userinfo; |
||||
this.unique_key = getRandomStr(); |
||||
if (this.$route.params.act) { |
||||
let activeName = this.$route.params.act; |
||||
let activeName_list = ["config", "receiver", "threshold"]; |
||||
for (let index in activeName_list) { |
||||
if (activeName_list[index] === activeName) { |
||||
this.activeName = activeName; |
||||
this.get_data_from_tabname(activeName); |
||||
return |
||||
} |
||||
} |
||||
} |
||||
this.get_data_from_tabname(this.activeName); |
||||
}, filters: { |
||||
sex_filter: function (x) { |
||||
let ret = '未知'; |
||||
if (x === 1) { |
||||
ret = '男' |
||||
} else if (x === 2) { |
||||
ret = '女' |
||||
} |
||||
return ret; |
||||
}, |
||||
}, watch: { |
||||
'$store.state.userinfo': function () { |
||||
this.userinfo = this.$store.state.userinfo; |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
.el-main { |
||||
text-align: center; |
||||
margin: 20px auto 100px; |
||||
width: 1166px; |
||||
position: relative; |
||||
padding-bottom: 1px; |
||||
color: #9b9b9b; |
||||
-webkit-font-smoothing: antialiased; |
||||
border-radius: 1%; |
||||
} |
||||
</style> |
@ -0,0 +1,75 @@ |
||||
# Generated by Django 3.2.3 on 2022-03-26 18:47 |
||||
|
||||
import django.db.models.deletion |
||||
from django.conf import settings |
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
dependencies = [ |
||||
('api', '0003_appbundleidblacklist'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='thirdwechatuserinfo', |
||||
name='enable_login', |
||||
field=models.BooleanField(default=0, verbose_name='是否允许登录'), |
||||
), |
||||
migrations.AddField( |
||||
model_name='thirdwechatuserinfo', |
||||
name='enable_notify', |
||||
field=models.BooleanField(default=0, verbose_name='是否允许推送消息'), |
||||
), |
||||
migrations.AddField( |
||||
model_name='userinfo', |
||||
name='notify_available_downloads', |
||||
field=models.IntegerField(blank=True, default=0, null=True, verbose_name='下载余额不足通知'), |
||||
), |
||||
migrations.AddField( |
||||
model_name='userinfo', |
||||
name='notify_available_signs', |
||||
field=models.IntegerField(blank=True, default=0, null=True, verbose_name='签名余额不足通知'), |
||||
), |
||||
migrations.CreateModel( |
||||
name='NotifyReceiver', |
||||
fields=[ |
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
('receiver_name', models.CharField(max_length=128, unique=True, verbose_name='姓名')), |
||||
('email', models.EmailField(blank=True, max_length=255, null=True, verbose_name='邮箱')), |
||||
('description', models.CharField(blank=True, default='', max_length=256, verbose_name='备注')), |
||||
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='添加时间')), |
||||
('user_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, |
||||
verbose_name='用户ID')), |
||||
('weixin', |
||||
models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='api.thirdwechatuserinfo', |
||||
verbose_name='微信ID')), |
||||
], |
||||
options={ |
||||
'verbose_name': '信息接收配置', |
||||
'verbose_name_plural': '信息接收配置', |
||||
'unique_together': {('user_id', 'email'), ('user_id', 'weixin')}, |
||||
}, |
||||
), |
||||
migrations.CreateModel( |
||||
name='NotifyConfig', |
||||
fields=[ |
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
('config_name', models.CharField(max_length=128, unique=True, verbose_name='通知名称')), |
||||
('message_type', models.SmallIntegerField( |
||||
choices=[(0, '签名余额不足'), (1, '下载次数不足'), (2, '应用签名限额'), (3, '应用签名失败'), (4, '充值到账提醒'), (5, '优惠活动通知'), |
||||
(6, '证书到期消息')], default=5, verbose_name='消息类型')), |
||||
('enable_weixin', models.BooleanField(default=True, verbose_name='是否启用该配置项')), |
||||
('enable_email', models.BooleanField(default=True, verbose_name='是否启用该配置项')), |
||||
('description', models.CharField(blank=True, default='', max_length=256, verbose_name='备注')), |
||||
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='添加时间')), |
||||
('sender', models.ManyToManyField(to='api.NotifyReceiver', verbose_name='通知接受者方式')), |
||||
('user_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, |
||||
verbose_name='用户ID')), |
||||
], |
||||
options={ |
||||
'verbose_name': '信息接收配置', |
||||
'verbose_name_plural': '信息接收配置', |
||||
}, |
||||
), |
||||
] |
@ -0,0 +1,175 @@ |
||||
#!/usr/bin/env python |
||||
# -*- coding:utf-8 -*- |
||||
# project: fir_ser |
||||
# filename: notify |
||||
# author: liuyu |
||||
# data: 2022/3/25 |
||||
|
||||
|
||||
import logging |
||||
|
||||
from rest_framework.response import Response |
||||
from rest_framework.views import APIView |
||||
|
||||
from api.models import NotifyReceiver, ThirdWeChatUserInfo, NotifyConfig, UserInfo |
||||
from api.utils.modelutils import PageNumber |
||||
from api.utils.response import BaseResponse |
||||
from api.utils.serializer import NotifyReceiverSerializer, NotifyConfigSerializer |
||||
from common.base.baseutils import get_choices_dict, get_choices_name_from_key |
||||
from common.core.auth import ExpiringTokenAuthentication |
||||
|
||||
logger = logging.getLogger(__name__) |
||||
|
||||
|
||||
class NotifyConfigView(APIView): |
||||
authentication_classes = [ExpiringTokenAuthentication, ] |
||||
|
||||
def get(self, request): |
||||
res = BaseResponse() |
||||
config_pk = request.query_params.get('pk') |
||||
|
||||
obj_lists = NotifyConfig.objects.filter(user_id=request.user).order_by('message_type').order_by("-create_time") |
||||
if config_pk: |
||||
obj_lists = obj_lists.filter(pk=config_pk).first() |
||||
info = NotifyConfigSerializer(obj_lists) |
||||
res.data = info.data |
||||
return Response(res.dict) |
||||
|
||||
info = NotifyConfigSerializer(obj_lists.all(), many=True).data |
||||
res.count = obj_lists.count() |
||||
message_type_choices = get_choices_dict(NotifyConfig.message_type_choices) |
||||
for message_info in message_type_choices: |
||||
message_info['data'] = [] |
||||
for notify_config_info in info: |
||||
if notify_config_info['message_type'] == message_info['id']: |
||||
message_info['data'].append(notify_config_info) |
||||
if len(message_info['data']) == 0: |
||||
data_info = NotifyConfigSerializer(NotifyConfig.objects.filter(pk=-1).first()).data |
||||
data_info['config_name'] = message_info['name'] |
||||
data_info['message_type'] = message_info['id'] |
||||
data_info['m_type'] = message_info['id'] |
||||
data_info['id'] = -1 |
||||
message_info['data'].append(data_info) |
||||
res.message_type_choices = message_type_choices |
||||
return Response(res.dict) |
||||
|
||||
def post(self, request): |
||||
res = BaseResponse() |
||||
data = request.data |
||||
act = data.get('act', '') |
||||
if act and act != 'get': |
||||
threshold = data.get('threshold', {}) |
||||
if threshold: |
||||
notify_available_downloads = threshold.get('notify_available_downloads') |
||||
notify_available_signs = threshold.get('notify_available_signs') |
||||
|
||||
if notify_available_downloads is not None: |
||||
request.user.notify_available_downloads = notify_available_downloads |
||||
if notify_available_signs is not None: |
||||
request.user.notify_available_signs = notify_available_signs |
||||
if notify_available_downloads is not None or notify_available_signs is not None: |
||||
request.user.save(update_fields=['notify_available_downloads', 'notify_available_signs']) |
||||
|
||||
res.data = UserInfo.objects.filter(pk=request.user.pk).values('notify_available_downloads', |
||||
'notify_available_signs').first() |
||||
return Response(res.dict) |
||||
|
||||
def put(self, request): |
||||
res = BaseResponse() |
||||
data = request.data |
||||
config_pk = data.get('config') |
||||
receiver_ids = data.get('receiver') |
||||
enable_email = data.get('enable_email') |
||||
enable_weixin = data.get('enable_weixin') |
||||
m_type = data.get('m_type') |
||||
if config_pk and config_pk == -1 and m_type is not None: |
||||
notify_config_obj = NotifyConfig.objects.filter(user_id=request.user, message_type=int(m_type)).filter() |
||||
if not notify_config_obj: |
||||
notify_config_obj = NotifyConfig.objects.create(user_id=request.user, message_type=int(m_type), |
||||
config_name=get_choices_name_from_key( |
||||
NotifyConfig.message_type_choices, int(m_type))) |
||||
else: |
||||
notify_config_obj = NotifyConfig.objects.filter(user_id=request.user, pk=config_pk).first() |
||||
if notify_config_obj: |
||||
if isinstance(receiver_ids, list): |
||||
notify_config_obj.sender.set( |
||||
NotifyReceiver.objects.filter(user_id=request.user, pk__in=receiver_ids).all()) |
||||
if enable_weixin is not None: |
||||
notify_config_obj.enable_weixin = enable_weixin |
||||
if enable_email is not None: |
||||
notify_config_obj.enable_email = enable_email |
||||
if enable_weixin is not None or enable_email is not None: |
||||
notify_config_obj.save(update_fields=['enable_email', 'enable_weixin']) |
||||
|
||||
return Response(res.dict) |
||||
|
||||
|
||||
class NotifyReceiverView(APIView): |
||||
authentication_classes = [ExpiringTokenAuthentication, ] |
||||
|
||||
def get(self, request): |
||||
res = BaseResponse() |
||||
config_pk = request.query_params.get('config') |
||||
message_type = request.query_params.get('message_type') |
||||
|
||||
obj_lists = NotifyReceiver.objects.filter(user_id=request.user) |
||||
|
||||
config_obj_lists = NotifyConfig.objects.filter(user_id=request.user) |
||||
if config_pk and config_pk != '-1': |
||||
res.senders = config_obj_lists.values('sender').filter(pk=config_pk).all() |
||||
config_obj = config_obj_lists.filter(pk=config_pk).first() |
||||
if config_obj: |
||||
res.config = {'config_name': config_obj.config_name, |
||||
'id': config_obj.pk, 'm_type': config_obj.message_type, |
||||
'message_type': config_obj.get_message_type_display()} |
||||
if config_pk and config_pk == '-1' and message_type is not None: |
||||
res.senders = config_obj_lists.values('sender').filter(pk=config_pk).all() |
||||
config_name = get_choices_name_from_key(NotifyConfig.message_type_choices, int(message_type)) |
||||
res.config = {'config_name': config_name, 'id': -1, 'message_type': config_name, |
||||
'm_type': message_type} |
||||
|
||||
page_obj = PageNumber() |
||||
obj_info_serializer = page_obj.paginate_queryset(queryset=obj_lists.order_by("-create_time"), |
||||
request=request, |
||||
view=self) |
||||
info = NotifyReceiverSerializer(obj_info_serializer, many=True, ) |
||||
res.data = info.data |
||||
res.count = obj_lists.count() |
||||
return Response(res.dict) |
||||
|
||||
def post(self, request): |
||||
res = BaseResponse() |
||||
data = request.data |
||||
receiver_name = data.get('receiver_name') |
||||
description = data.get('description') |
||||
wxopenid = data.get('wxopenid') |
||||
email = data.get('email') |
||||
if receiver_name: |
||||
data_info = { |
||||
'receiver_name': receiver_name, |
||||
'description': description, |
||||
} |
||||
wx_obj = None |
||||
if wxopenid: |
||||
wx_obj = ThirdWeChatUserInfo.objects.filter(user_id=request.user, openid=wxopenid).first() |
||||
if wx_obj: |
||||
data_info['weixin'] = wx_obj |
||||
if email: |
||||
data_info['email'] = email |
||||
try: |
||||
NotifyReceiver.objects.create(user_id=request.user, **data_info) |
||||
if wx_obj: |
||||
wx_obj.enable_notify = True |
||||
wx_obj.save(update_fields=['enable_notify']) |
||||
except Exception as e: |
||||
logger.error(f"{request.user} notify receiver add failed . data:{data} Exception:{e}") |
||||
res.code = 1001 |
||||
res.msg = '数据有误或者已经存在该接收人信息' |
||||
return Response(res.dict) |
||||
|
||||
def delete(self, request): |
||||
res = BaseResponse() |
||||
pk = request.query_params.get('id') |
||||
if pk: |
||||
NotifyReceiver.objects.filter(user_id=request.user, pk=pk).delete() |
||||
return Response(res.dict) |
@ -0,0 +1,78 @@ |
||||
#!/usr/bin/env python |
||||
# -*- coding:utf-8 -*- |
||||
# project: fir_ser |
||||
# filename: notify |
||||
# author: liuyu |
||||
# data: 2022/3/26 |
||||
import logging |
||||
|
||||
from api.utils.modelutils import get_notify_wx_queryset |
||||
from common.base.baseutils import get_format_time |
||||
from common.core.sysconfig import Config |
||||
from common.libs.mp.wechat import WxTemplateMsg |
||||
from common.notify.utils import notify_by_email |
||||
|
||||
logger = logging.getLogger(__name__) |
||||
|
||||
|
||||
def pay_success_notify(user_obj, order_obj): |
||||
""" |
||||
4, '充值到账提醒' |
||||
:param user_obj: |
||||
:param order_obj: |
||||
:return: |
||||
""" |
||||
message_type = 4 |
||||
|
||||
title = f'{order_obj.actual_download_times} 下载次数' |
||||
if order_obj.actual_download_gift_times > 0: |
||||
title = f'{title} 【赠送 {order_obj.actual_download_gift_times}】' |
||||
msg = f"用户 {user_obj.first_name} 您好,{order_obj.description}。您购买了 {title}。感谢有你!" |
||||
for wx_user_obj in get_notify_wx_queryset(user_obj, message_type): |
||||
res = WxTemplateMsg(wx_user_obj.openid, wx_user_obj.nickname).pay_success_msg( |
||||
title, |
||||
f'{str(order_obj.actual_amount / 100)} 元', |
||||
order_obj.get_payment_type_display(), |
||||
order_obj.pay_time.strftime("%Y/%m/%d %H:%M:%S"), |
||||
order_obj.order_number, order_obj.description) |
||||
logger.info(f'user_obj {user_obj} weixin notify pay success result: {res}') |
||||
|
||||
notify_by_email(user_obj, message_type, msg) |
||||
|
||||
|
||||
def sign_failed_notify(user_obj, developer_obj, app_obj): |
||||
""" |
||||
3, '应用签名失败' |
||||
:return: |
||||
""" |
||||
message_type = 3 |
||||
now_time = get_format_time().replace('_', ' ') |
||||
|
||||
msg = Config.MSG_ERROR_DEVELOPER % ( |
||||
developer_obj.user_id.first_name, app_obj.name, |
||||
now_time, developer_obj.issuer_id) |
||||
|
||||
for wx_user_obj in get_notify_wx_queryset(user_obj, message_type): |
||||
res = WxTemplateMsg(wx_user_obj.openid, wx_user_obj.nickname).operate_failed_msg( |
||||
user_obj.first_name, f'应用 {app_obj.name} 签名失败了', |
||||
f'开发者{developer_obj.issuer_id} 状态 {developer_obj.get_status_dispaly()}', now_time, '请登录后台查看具体信息') |
||||
logger.info(f'user_obj {user_obj} weixin notify pay success result: {res}') |
||||
|
||||
notify_by_email(user_obj, message_type, msg) |
||||
|
||||
|
||||
def sign_unavailable_developer(user_obj, app_obj): |
||||
""" |
||||
3, '应用签名失败' |
||||
:return: |
||||
""" |
||||
message_type = 3 |
||||
now_time = get_format_time().replace('_', ' ') |
||||
msg = Config.MSG_NOT_EXIST_DEVELOPER % (user_obj.first_name, now_time, app_obj.name) |
||||
for wx_user_obj in get_notify_wx_queryset(user_obj, message_type): |
||||
res = WxTemplateMsg(wx_user_obj.openid, wx_user_obj.nickname).operate_failed_msg( |
||||
user_obj.first_name, f'应用 {app_obj.name} 签名失败了', |
||||
f'苹果开发者总设备量已经超限', now_time, '添加新的苹果开发者或者修改开发者设备数量') |
||||
logger.info(f'user_obj {user_obj} weixin notify pay success result: {res}') |
||||
|
||||
notify_by_email(user_obj, message_type, msg) |
@ -0,0 +1,131 @@ |
||||
#!/usr/bin/env python |
||||
# -*- coding:utf-8 -*- |
||||
# project: fir_ser |
||||
# filename: ntasks |
||||
# author: liuyu |
||||
# data: 2022/3/26 |
||||
import datetime |
||||
import logging |
||||
|
||||
from api.utils.modelutils import get_notify_wx_queryset |
||||
from common.base.magic import magic_wrapper, magic_notify |
||||
from common.cache.storage import NotifyLoopCache |
||||
from common.core.sysconfig import Config |
||||
from common.libs.mp.wechat import WxTemplateMsg |
||||
from common.notify.utils import notify_by_email |
||||
from xsign.models import AppIOSDeveloperInfo |
||||
from xsign.utils.modelutils import get_developer_devices |
||||
|
||||
logger = logging.getLogger(__name__) |
||||
|
||||
|
||||
def download_times_not_enough(user_obj): |
||||
""" |
||||
1, '下载次数不足' |
||||
:param user_obj: |
||||
:return: |
||||
""" |
||||
message_type = 1 |
||||
msg = f"您当前账户下载次数仅剩 {user_obj.download_times},已超过您设置的阈值 {user_obj.notify_available_downloads},为了避免业务使用,望您尽快充值!" |
||||
for wx_user_obj in get_notify_wx_queryset(user_obj, message_type): |
||||
res = WxTemplateMsg(wx_user_obj.openid, wx_user_obj.nickname).download_times_not_enough_msg( |
||||
user_obj.first_name, user_obj.download_times, msg) |
||||
logger.info(f'user_obj {user_obj} download times not enough result: {res}') |
||||
notify_by_email(user_obj, message_type, msg) |
||||
|
||||
|
||||
def apple_developer_devices_not_enough(user_obj, device_count): |
||||
""" |
||||
0, '签名余额不足' |
||||
:param user_obj: |
||||
:return: |
||||
""" |
||||
message_type = 0 |
||||
msg = f"您当前账户超级签名可用设备仅剩 {device_count},已超过您设置的阈值 {user_obj.notify_available_signs},为了避免业务使用,望您尽快添加苹果开发者!" |
||||
for wx_user_obj in get_notify_wx_queryset(user_obj, message_type): |
||||
res = WxTemplateMsg(wx_user_obj.openid, wx_user_obj.nickname).apple_developer_devices_not_enough_msg( |
||||
user_obj.first_name, device_count, msg) |
||||
logger.info(f'user_obj {user_obj} sign devices not enough result: {res}') |
||||
notify_by_email(user_obj, message_type, msg) |
||||
|
||||
|
||||
def apple_developer_cert_expired(user_obj, developer_queryset): |
||||
""" |
||||
6, '证书到期消息' |
||||
:param developer_queryset: |
||||
:param user_obj: |
||||
:return: |
||||
""" |
||||
message_type = 6 |
||||
developer_count = developer_queryset.count() |
||||
developer_obj = developer_queryset.first() |
||||
expired_time = developer_obj.cert_expire_time.strftime("%Y年%m月%d") |
||||
if developer_count == 1: |
||||
issuer_id = developer_obj.issuer_id |
||||
cert_id = developer_obj.certid |
||||
msg = f"用户 {user_obj.first_name} 您好,您苹果开发者 {issuer_id} ,证书 {cert_id} 即将到期,到期时间 {expired_time},为了保证您开发者可用,请您尽快更新开发者证书,感谢您的关注" |
||||
else: |
||||
issuer_id = f'{developer_obj.issuer_id} 等 {developer_count} 个开发者ID' |
||||
cert_id = f'{developer_obj.certid} 等 {developer_count} 个证书ID' |
||||
msg = f"用户 {user_obj.first_name} 您好,您苹果开发者 {issuer_id} ,证书 {cert_id} 即将到期,到期时间 {expired_time},为了保证您开发者可用,请您尽快更新开发者证书,感谢您的关注 " |
||||
|
||||
for wx_user_obj in get_notify_wx_queryset(user_obj, message_type): |
||||
res = WxTemplateMsg(wx_user_obj.openid, wx_user_obj.nickname).cert_expired_msg(issuer_id, |
||||
cert_id, |
||||
expired_time) |
||||
logger.info(f'user_obj {user_obj} apple developer cert expired result: {res}') |
||||
|
||||
notify_by_email(user_obj, message_type, msg) |
||||
|
||||
|
||||
def check_user_download_times(user_obj, days=None): |
||||
if days is None: |
||||
days = [0, 3, 7] |
||||
if user_obj.notify_available_downloads == 0 or user_obj.notify_available_downloads < user_obj.download_times: |
||||
return |
||||
notify_rules = [ |
||||
{ |
||||
'func': magic_wrapper(lambda obj: obj.download_times < obj.notify_available_downloads, user_obj), |
||||
'notify': days, |
||||
'cache': NotifyLoopCache(user_obj.uid, 'download_times'), |
||||
'notify_func': [magic_wrapper(download_times_not_enough, user_obj)] |
||||
} |
||||
] |
||||
magic_notify(notify_rules) |
||||
|
||||
|
||||
def check_apple_developer_devices(user_obj, days=None): |
||||
if days is None: |
||||
days = [0, 3, 7] |
||||
developer_used_info = get_developer_devices(AppIOSDeveloperInfo.objects.filter(user_id=user_obj)) |
||||
device_count = developer_used_info.get('can_sign_number', 0) |
||||
if user_obj.notify_available_signs == 0 or user_obj.notify_available_signs < device_count: |
||||
return |
||||
notify_rules = [ |
||||
{ |
||||
'func': magic_wrapper(lambda obj: device_count < obj.notify_available_downloads, user_obj), |
||||
'notify': days, |
||||
'cache': NotifyLoopCache(user_obj.uid, 'sign_device_times'), |
||||
'notify_func': [magic_wrapper(apple_developer_devices_not_enough, user_obj, device_count)] |
||||
} |
||||
] |
||||
magic_notify(notify_rules) |
||||
|
||||
|
||||
def check_apple_developer_cert(user_obj, expire_day=7): |
||||
expire_time = datetime.datetime.now() + datetime.timedelta(days=expire_day) |
||||
developer_queryset = AppIOSDeveloperInfo.objects.filter(user_id=user_obj, status__in=Config.DEVELOPER_USE_STATUS, |
||||
cert_expire_time__lte=expire_time).order_by( |
||||
'cert_expire_time') |
||||
if developer_queryset.count() == 0: |
||||
return |
||||
|
||||
notify_rules = [ |
||||
{ |
||||
'func': magic_wrapper(lambda obj: obj.download_times < obj.notify_available_downloads, user_obj), |
||||
'notify': [0, 3, 7], |
||||
'cache': NotifyLoopCache(user_obj.uid, 'developer_cert'), |
||||
'notify_func': [magic_wrapper(apple_developer_cert_expired, user_obj, developer_queryset)] |
||||
} |
||||
] |
||||
magic_notify(notify_rules) |
@ -0,0 +1,19 @@ |
||||
#!/usr/bin/env python |
||||
# -*- coding:utf-8 -*- |
||||
# project: fir_ser |
||||
# filename: wx |
||||
# author: liuyu |
||||
# data: 2022/3/23 |
||||
import logging |
||||
|
||||
from api.utils.modelutils import get_notify_email_queryset |
||||
from common.utils.sendmsg import get_sender_email_token |
||||
|
||||
logger = logging.getLogger(__name__) |
||||
|
||||
|
||||
def notify_by_email(user_obj, message_type, msg): |
||||
for notify_email in get_notify_email_queryset(user_obj, message_type): |
||||
email = notify_email.get('email') |
||||
if email: |
||||
get_sender_email_token('email', email, 'msg', f'您好,{user_obj.first_name},{msg}') |
Loading…
Reference in new issue