<template> <a-spin :spinning="this.$store.state.spinning"> <div class="AccountManagement"> <div class="searchBox"> <div class="choosePeople" @click="choosePeople" style="width: 120px">选择成员</div> <a-input placeholder="输入卡号" v-model="searchSource.cardNum" style="width: 120px"/> <a-select placeholder="卡片状态" style="width: 120px;margin-right: 20px;" :allowClear="true" @change="selectHandleChangeCard"> <a-select-option value="ACTIVE">已绑卡</a-select-option> <a-select-option value="NOT_EXIST">未绑卡</a-select-option> <a-select-option value="UNACTIVE">已冻结</a-select-option> </a-select> <a-select placeholder="账户状态" defaultValue="ACTIVE" style="width: 120px;margin-right: 20px;" :allowClear="true" @change="selectHandleChangeAccount"> <a-select-option value="ACTIVE">正常</a-select-option> <a-select-option value="LOG_OFF">已注销</a-select-option> <a-select-option value="SETTLEMENT">已结现</a-select-option> </a-select> <a-button type="primary" @click="search()">查询</a-button> </div> <div class="searchUserMessage" v-if="alreadyChoose.users.length > 0 || alreadyChoose.departments.length > 0" > <div class="positionDiv"></div> <div class="clearUserMessage"><a href="javascript:;" @click="clearUserMessage">清除</a></div> <div class="userListBox"> <div v-for="item in alreadyChoose.users" :key="item.emplId"> <img v-if="item.avatar" :src="item.avatar" :alt="item.name"/> <img v-else :src="avatarCanvasFn(item.name)" :alt="item.name"> <span>{{ item.name }}</span> </div> <div v-for="item in alreadyChoose.departments" :key="item.id"> <img src="../../../assets/department.png" :alt="item.name"/> <span>{{ item.name }}</span> </div> </div> </div> <a-table :columns="columns" :dataSource="accountList" size="default" rowKey="ddUserId" :pagination="pagination" @change="handleTableChange"> <span slot="name">姓名</span> <span slot="departmentNameList" slot-scope="departmentNameList, record"> <div v-if=" departmentNameList && departmentNameList.length > 0"> <a-popover v-for="(item,indexOf) in departmentNameList" :key="indexOf"> <template slot="content"> <p>{{record.parentSysDeptNameList[indexOf]}}</p> </template> <span class="deptModel">{{item}}</span> </a-popover> </div> </span> <span slot="realityBalance" slot-scope="realityBalance"> {{ realityBalance.toFixed(2) }} </span> <span slot="cardNo" slot-scope="cardNo"> {{ cardNo }} </span> <span slot="cardStatus" slot-scope="cardStatus, record"> <a-badge v-if="record.cardNo && cardStatus !== 'UNACTIVE'" status="success" text="已绑卡" /> <a-badge v-else-if="record.cardNo && cardStatus === 'UNACTIVE'" status="error" text="已冻结" /> <a-badge v-else status="default" text="未绑卡" /> </span> <span slot="status" slot-scope="status"> <a-badge v-if="status === MINGPAY_ACCOUNT_STATUS.ACTIVE" status="success" text="正常" /> <a-badge v-else-if="status === MINGPAY_ACCOUNT_STATUS.SETTLEMENT" status="error" text="已结现" /> <a-badge v-else status="error" text="已注销" /> </span> <span slot="action" slot-scope="text, record, index" class="operationTable"> <a href="javascript:;" @click="ToViewAllowances(record)">查看津贴</a> <a v-if="record.status === MINGPAY_ACCOUNT_STATUS.ACTIVE" href="javascript:;" @click="showModal(record.ddUserId, record.name, index)">充值</a> <a v-else href="javascript:;" style="color:#cccccc">充值</a> <a-dropdown v-if="record.status === MINGPAY_ACCOUNT_STATUS.ACTIVE"> <a class="ant-dropdown-link" href="javascript:;"> 更多操作 <a-icon type="down" /> </a> <a-menu slot="overlay"> <a-menu-item v-if="record.cardStatus === MINGPAY_ACCOUNT_STATUS.ACTIVE && record.cardNo "> <a href="javascript:;" @click="showConfirm(record.ddUserId, 1, index)">冻结实体卡</a> </a-menu-item> <a-menu-item v-if="record.cardStatus === MINGPAY_ACCOUNT_STATUS.UNACTIVE && record.cardNo"> <a href="javascript:;" @click="showConfirm(record.ddUserId, 2, index)">解冻实体卡</a> </a-menu-item> <a-menu-item v-if="record.cardNo"> <a href="javascript:;" @click="confimBindSure(record.ddUserId, index)">解绑实体卡</a> </a-menu-item> <a-menu-item v-else> <a href="javascript:;" @click="changeVisible2(record.ddUserId, index)">绑定实体卡</a> </a-menu-item> <a-menu-item v-if="record.status != MINGPAY_ACCOUNT_STATUS.LOG_OFF"> <a href="javascript:;" @click="showConfirm(record.ddUserId, 3, index)">注销并结现</a> </a-menu-item> </a-menu> </a-dropdown> <a-dropdown v-else-if="record.status === MINGPAY_ACCOUNT_STATUS.LOG_OFF"> <a class="ant-dropdown-link" href="javascript:;"> 更多操作 <a-icon type="down" /> </a> <a-menu slot="overlay"> <a-menu-item> <a href="javascript:;" @click="showConfirm(record.ddUserId, 4, index)">结现</a> </a-menu-item> </a-menu> </a-dropdown> <a-dropdown v-else> <a style="color: #cccccc"> 更多操作 <a-icon type="down" /> </a> </a-dropdown> </span> </a-table> <a-modal title="绑定实体卡" v-model="visible2" @ok="cardOperation(2)"> <a-form :form="updateBindCardStatusForm"> <a-form-item label="实体卡号" :label-col="{ span: 5 }" :wrapper-col="{ span: 12 }" > <a-input v-decorator="['cardNo', {rules: [{ required: true, message: '请填写正确的实体卡号!' }, {validator: bindCardNum}]}]"/> </a-form-item> </a-form> </a-modal> <a-modal title="现金充值" v-model="visible" @ok="internalRecharge()"> <a-form :form="form"> <a-form-item label="充值金额" :label-col="{ span: 5 }" :wrapper-col="{ span: 12 }" > <a-input v-decorator="['orderPrice',{rules: [{required: true, message: '充值金额不能为空'}, {validator: rechargeNum}]}]" /> </a-form-item> <a-form-item label="备注" :label-col="{ span: 5 }" :wrapper-col="{ span: 12 }" > <a-textarea v-decorator="['remark', {rules: [{ required: true, message: '备注不能为空' }]}]"/> </a-form-item> </a-form> </a-modal> </div> </a-spin> </template> <script> import { config } from './../../../api/config.js' import { $http } from './../../../api/axios.js' import { MINGPAY_ACCOUNT_STATUS } from './../../../api/constant' import store from './../../../store' // import { avatarFn } from './../../../api/avatar' export default { name: 'accountManagement', components: {}, data () { return { visible: false, visible2: false, formLayout: 'horizontal', form: this.$form.createForm(this), updateBindCardStatusForm: this.$form.createForm(this), MINGPAY_ACCOUNT_STATUS: MINGPAY_ACCOUNT_STATUS, data: [], pagination: { current: 1, defaultCurrent: 10, defaultPageSize: 10, hideOnSinglePage: true, total: 0 }, columns: [{ title: '成员', dataIndex: 'name', width: '90px' }, { title: '部门', dataIndex: 'departmentNameList', scopedSlots: { customRender: 'departmentNameList' }, width: '15%' }, { title: '余额', dataIndex: 'realityBalance', scopedSlots: { customRender: 'realityBalance' } }, { title: '卡号', dataIndex: 'cardNo', scopedSlots: { customRender: 'cardNo' } }, { title: '实体卡状态', dataIndex: 'cardStatus', scopedSlots: { customRender: 'cardStatus' } }, { title: '账户状态', dataIndex: 'status', scopedSlots: { customRender: 'status' } }, { title: '操作', key: 'a', dataIndex: 'action', scopedSlots: { customRender: 'action' } }], accountList: [], rechargeData: { ddUserId: '', username: '', orderPrice: '', remark: '' }, alreadyChoose: { departments: [], users: [] }, selsctUserId: '', selsctIndex: 0, searchSource: { ddchoosePeople: { userIdList: [], departmentIdList: [] }, UserMessage: { avatar: '', emplId: '', name: '' }, cardNum: '', cardStatus: '', accountStatus: 'ACTIVE' } } }, watch: {}, computed: {}, created: function () { this.queryAccountList() }, methods: { // 获取账户列表 queryAccountList () { const _that = this let AccountData = { currentPage: this.pagination.current, pageNumber: this.pagination.defaultPageSize, ddDeptIds: this.searchSource.ddchoosePeople.departmentIdList, ddUserIds: this.searchSource.ddchoosePeople.userIdList, status: this.searchSource.accountStatus, cardNo: this.searchSource.cardNum, cardStatus: this.searchSource.cardStatus } $http.get(`/mingpay/v1/isv/account/queryAccountList`, AccountData).then((res) => { _that.accountList = res.data.data.recordList _that.pagination.total = parseInt(res.data.data.totalCount) }).catch((err) => { this.$message.error('网络异常请重试') console.log(err) }) }, // 搜索条件,卡片和账户状态 selectHandleChangeCard (value) { this.searchSource.cardStatus = value }, selectHandleChangeAccount (value) { this.searchSource.accountStatus = value }, // 选人组件调用 choosePeople () { const _that = this config.ddready('ddchoose').then((res) => { let userIdListObj = [] let departmentIdListObj = [] res.departments.map((item, index) => { departmentIdListObj.push(item.id) }) res.users.map((item, index) => { userIdListObj.push(item.emplId) }) this.alreadyChoose = { departments: res.departments, users: res.users } this.searchSource.ddchoosePeople.departmentIdList = departmentIdListObj this.searchSource.ddchoosePeople.userIdList = userIdListObj _that.queryAccountList() }) }, // 校验账户充值金额大小和纯数字 rechargeNum (rule, value, callback) { const temp = /^\d+\.?\d{0,2}$/ if (!temp.test(value) || parseFloat(value) > 10000) { callback('请输入正确的金额,最多保留小数点后两位,充值金额最多为一万元') return } callback() }, // 清理选择帅选人list clearUserMessage () { this.alreadyChoose = { departments: [], users: [] } this.searchSource.ddchoosePeople = { userIdList: [], departmentIdList: [] } }, // 用户头像处理 avatarCanvasFn (name) { let canvas = document.createElement('canvas') let con = canvas.getContext('2d') let ratio = this.getPixelRatio(con) canvas.style.width = 40 + 'px' canvas.style.height = 40 + 'px' canvas.width = 40 * ratio canvas.height = 40 * ratio con.scale(ratio, ratio) con.fillStyle = '#1890ff' con.fillRect(0, 0, 40, 40) con.fillStyle = '#ffffff' con.font = '12px Arial' con.textAlign = 'center' con.fillText(name, 20, 25) return canvas.toDataURL() }, // 头像模糊处理 getPixelRatio (context) { var backingStore = context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1 return (window.devicePixelRatio || 1) / backingStore }, // 绑定实体卡号校验,仅字符串和数字 bindCardNum (rule, value, callback) { var re = /^[0-9a-zA-Z]*$/ if (!re.test(value)) { callback('实体卡卡号必须由数字和字母组成') return } callback() }, // 绑定实体卡modal切换 changeVisible2 (str, index) { this.visible2 = !this.visible2 this.selsctUserId = str this.selsctIndex = index }, // 分页 handleTableChange (pagination, filters, sorter) { this.pagination.current = pagination.current this.queryAccountList() }, // table部门表格字符串处理 departmentNameListToStr (str) { let departmentNameListStr = '' if (str.length !== 0) { str.map((data) => { departmentNameListStr = `${departmentNameListStr}${data},` }) } departmentNameListStr = departmentNameListStr.substring(0, departmentNameListStr.length - 1) return departmentNameListStr }, // 查看津贴 ToViewAllowances (str) { this.$router.push({ name: 'viewAllowances', params: { ddUserId: str.ddUserId } }) }, // 内部充值接口 internalRecharge () { let _that = this console.log(this.form.getFieldsValue().orderPrice || this.form.getFieldsValue().remark) if (!this.form.getFieldsValue().orderPrice) { this.$message.error('金额不能为空') } else if (!this.form.getFieldsValue().remark) { this.$message.error('备注不能为空') } else { store.dispatch('setSpinning', true) this.visible = false this.rechargeData.orderPrice = this.form.getFieldsValue().orderPrice this.rechargeData.remark = this.form.getFieldsValue().remark $http.post(`/mingpay/v1/isv/charge/charge`, this.rechargeData).then((res) => { if (res.data.resultCode === 0) { this.form.resetFields() this.$message.success(res.data.data.message) this.queryAccountList() } }) } }, // 充值modal showModal (userId, userName, index) { this.rechargeData.ddUserId = userId this.rechargeData.username = userName this.selsctIndex = index this.visible = true }, // 账户操作和卡片操作 accountOperation (type, userId, status, index) { let accountOperationData if (type === 3 || type === 4) { accountOperationData = { ddUserId: userId, accountStatus: status } $http.post('/mingpay/v1/isv/account/logOff_and_settlement', accountOperationData).then((res) => { if (res.data.resultCode === 0) { this.queryAccountList() this.$message.success('操作成功') } }).catch(() => { this.$message.error('操作失败') }) } else { accountOperationData = { ddUserId: userId, cardStatus: status } $http.get('/mingpay/v1/isv/account/update_card_status', accountOperationData).then((res) => { if (res.data.resultCode === 0) { this.queryAccountList() this.$message.success('操作成功') } }).catch(() => { this.$message.error('操作失败') }) } }, // binding,unbinding二次确认 confimBindSure (userId, index) { this.selsctUserId = userId this.selsctIndex = index const _that = this this.$confirm({ title: '确认要对该账户实体卡解除绑定么?', content: '解除绑定后,该实体卡将不能付款', okText: '确定', cancelText: '取消', onOk () { _that.cardOperation(1) } }) }, // 冻结,解冻,注销结现二次确认 showConfirm (userId, str, index) { let title = '' let content = '' let status = '' let url = '' const _that = this // 1冻结,2解冻,3注销并结现 switch (str) { case 1: title = '确认要对该账户实体卡进行冻结操作么?' content = '冻结后二维码可使用付款,实体卡片不能付款,若想再次使用实体卡请先解冻' status = MINGPAY_ACCOUNT_STATUS.UNACTIVE url = '' break case 2: title = '确认要对该账户实体卡进行解冻操作么?' content = '解冻后二维码与实体卡片均可正常使用' status = MINGPAY_ACCOUNT_STATUS.ACTIVE url = '' break case 3: title = '确认要对该账户进行注销并结现操作么?' content = '用户余额请线下当面结算完,注销并结现后,该账户资金将被清空,账户不可再次激活' status = MINGPAY_ACCOUNT_STATUS.SETTLEMENT url = '' break case 4: title = '确认要对该账户进行结现操作么?' content = '用户余额请线下当面结算完,确认结现后,该账户资金将被清空,账户不可再次激活' status = MINGPAY_ACCOUNT_STATUS.SETTLEMENT url = '' break } this.$confirm({ title: title, content: content, okText: '确定', cancelText: '取消', onOk () { _that.accountOperation(str, userId, status, index) } }) }, // 绑卡解绑操作 cardOperation (type) { let cardOperationData = '' const cardNo = this.updateBindCardStatusForm.getFieldsValue().cardNo if (type === 2) { cardOperationData = { cardNo: this.updateBindCardStatusForm.getFieldsValue().cardNo, ddUserId: this.selsctUserId } } else if (type === 1) { cardOperationData = { cardNo: '', ddUserId: this.selsctUserId } } $http.get(`/mingpay/v1/isv/account/update_bind_card_status`, cardOperationData).then((res) => { if (res.data.resultCode === 0) { this.queryAccountList() this.visible2 = false this.updateBindCardStatusForm.resetFields() this.$message.success('操作成功') } else if (res.data.resultCode === 10010009) { this.$message.error('该卡片已被占用') } else { this.$message.error(res.data.message) } }).catch((err) => { this.$message.error('网络异常请重试') console.log(err) }) }, search () { this.pagination.current = 1 this.queryAccountList() } }, mounted () {} } </script> <style lang="less" scoped> .searchBox{ display: flex; margin-bottom: 15px; } .searchBox > input { margin-right: 20px; max-width: 180px; } .operationTable a{ margin-right: 8px; } .searchUserMessage{ width: 100%; display: flex; flex-direction: column; justify-content: center; font-size: 12px; padding: 8px 8px; padding-right: 20px; border: 1px solid #cccccc; margin-bottom: 15px; border-radius: 8px; position: relative; } .searchUserMessage img{ width: 32px; height: 32px; border-radius: 50%; margin-bottom: 8px; } .positionDiv{ height: 12px; width: 12px; transform:rotate(45deg); border-left: 1px solid #cccccc; border-top: 1px solid #cccccc; position: absolute; top: -7px; left: 30px; background: white; z-index: 99; } .clearUserMessage{ position: absolute; right: 10px; } .userListBox{ display: flex; flex-flow: wrap; } .userListBox>div{ margin: 8px; display: flex; flex-direction: column; align-items: center; } .userListBox>div>img{ display: block; text-align: center; } .choosePeople{ line-height: 32px; width: 120px; margin-right: 20px; padding-left: 11px; height: 32px; border: 1px solid #d9d9d9; border-radius: 4px; color: #bfbfbf; cursor: pointer; } .choosePeople:hover{ border: 1px solid #1890ff; } .deptModel{ background: #F2F0F0; margin: 5px 0; margin-right: 5px; padding: 2px 4px; border-radius: 3px; line-height: 2; } .ant-table-tbody > tr:hover .deptModel{ background: #CAEEFF; } .ant-popover-inner-content>p{ margin: 0; } </style>