文件
Henglianshutong/public/assets/js/backend/shopro/commission/agent.js

853 行
39 KiB
JavaScript

define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
var Controller = {
data: () => {
return {
statusStyle: {
normal: { label: '正常', color: '#52c41a' },
pending: { label: '审核中', color: '#faad14' },
reject: { label: '拒绝', color: '#f56c6c' },
freeze: { label: '冻结', color: '#409eff' },
forbidden: { label: '禁用', color: '#999999' },
}
}
},
index: () => {
const { reactive, onMounted } = Vue
const index = {
setup() {
const state = reactive({
data: [],
filter: {
drawer: false,
data: {
tabActive: 'all',
user: { field: 'user_id', value: '' },
level: '',
status: '',
createtime: [],
identity: '',
is_venue: '',
is_county: '',
active_30d: '',
county_code: '',
},
tools: {
user: {
type: 'tinputprepend',
label: '会员信息',
placeholder: '请输入查询内容',
value: {
field: 'user_id',
value: '',
},
options: {
data: [{
label: '用户ID',
value: 'user_id',
},
{
label: '用户昵称',
value: 'user.nickname',
},
{
label: '用户手机号',
value: 'user.mobile',
}]
}
},
level: {
type: 'tselect',
label: '分销商等级',
value: '',
options: {
data: [],
props: {
label: 'name',
value: 'level',
},
},
},
status: {
type: 'tselect',
label: '审核状态',
value: '',
options: {
data: [{
value: 'normal',
label: '正常',
},
{
value: 'forbidden',
label: '禁用',
},
{
value: 'pending',
label: '审核中',
},
{
value: 'freeze',
label: '冻结',
},
{
value: 'reject',
label: '拒绝',
}],
},
},
createtime: {
type: 'tdatetimerange',
label: '更新时间',
value: [],
},
identity: {
type: 'tselect',
label: '身份',
value: '',
options: {
data: [
{ value: 'taster', label: '品酒师' },
{ value: 'maker', label: '创客' },
{ value: 'venue', label: '酒道馆' },
{ value: 'county', label: '区县' },
]
},
},
is_venue: {
type: 'tselect',
label: '酒道馆',
value: '',
options: { data: [{ value: '1', label: '是' }, { value: '0', label: '否' }] },
},
is_county: {
type: 'tselect',
label: '区县',
value: '',
options: { data: [{ value: '1', label: '是' }, { value: '0', label: '否' }] },
},
active_30d: {
type: 'tselect',
label: '30日活跃',
value: '',
options: { data: [{ value: '1', label: '有自购' }, { value: '0', label: '已暂停' }] },
},
county_code: {
type: 'tinput',
label: '区县编码',
placeholder: '请输入区县编码',
value: '',
},
},
condition: {},
}
})
const type = reactive({
data: {
status: [{
type: 'all',
name: '分销商',
},
{
type: 'pending',
name: '待审核',
},
{
type: '0',
name: '待升级',
}],
}
})
function getLevelSelect() {
Fast.api.ajax({
url: `shopro/commission/level/select`,
type: 'GET',
}, function (ret, res) {
state.filter.tools.level.options.data = res.data;
return false
}, function (ret, res) { })
}
function getData() {
let tempSearch = JSON.parse(JSON.stringify(state.filter.data));
let search = composeFilter(tempSearch, {
'user.nickname': 'like',
'user.mobile': 'like',
createtime: 'range',
});
let temp = JSON.parse(search.search);
if (temp && temp.tabActive) {
if (temp.tabActive[0] == 'pending') {
temp.status = ['pending', '='];
delete temp.tabActive;
} else if (temp.tabActive[0] == '0') {
temp.level_status = ['0', '>'];
delete temp.tabActive;
}
}
search = { search: JSON.stringify(temp) };
Fast.api.ajax({
url: 'shopro/commission/agent',
type: 'GET',
data: {
page: pagination.page,
list_rows: pagination.list_rows,
...search,
},
}, function (ret, res) {
state.data = res.data.data
pagination.total = res.data.total
if (res.data.data && res.data.data.length > 0) {
const roleNames = res.data.data[0].custom_role_names || res.data.data[0].role_names;
if (roleNames) {
if (state.filter.tools.identity && state.filter.tools.identity.options) {
state.filter.tools.identity.options.data = [
{ value: 'taster', label: roleNames.taster || '品酒师' },
{ value: 'maker', label: roleNames.maker || '创客' },
{ value: 'venue', label: roleNames.venue || '酒道馆' },
{ value: 'county', label: roleNames.county || '区县' },
];
}
if (state.filter.tools.is_venue) {
state.filter.tools.is_venue.label = roleNames.venue || '酒道馆';
}
if (state.filter.tools.is_county) {
state.filter.tools.is_county.label = roleNames.county || '区县代理';
}
}
}
return false
}, function (ret, res) { })
}
function onOpenFilter() {
state.filter.drawer = true
}
function onChangeFilter() {
pagination.page = 1
getData()
state.filter.drawer && (state.filter.drawer = false)
}
function onChangeTab() {
pagination.page = 1
getData()
}
const pagination = reactive({
page: 1,
list_rows: 10,
total: 0,
})
function onEdit(id, data) {
Fast.api.ajax({
url: `shopro/commission/agent/edit/id/${id}`,
type: 'POST',
data: data,
}, function (ret, res) {
getData();
}, function (ret, res) { })
}
function onDetail(id, row) {
const url = `shopro/commission/agent/detail/id/${id}?id=${id}`;
const title = (row && row.user && row.user.nickname)
? `分销商详情 - ${row.user.nickname}`
: `分销商详情 #${id}`;
if (typeof Backend !== 'undefined' && Backend.api && typeof Backend.api.addtabs === 'function') {
Backend.api.addtabs(url, title);
} else if (top && top.Backend && top.Backend.api && typeof top.Backend.api.addtabs === 'function') {
top.Backend.api.addtabs(url, title);
} else if (Fast && Fast.api && typeof Fast.api.addtabs === 'function') {
Fast.api.addtabs(url, title);
} else {
window.location.href = Fast.api.fixurl(url);
}
}
const identity = reactive({
visible: false,
loading: false,
levels: [],
areaSelect: [],
form: {
user_id: '',
nickname: '',
before_text: '',
level: 1,
is_venue: 0,
is_county: 0,
county_code: '',
area_arr: [],
upgrade_lock: 0,
remark: '',
}
})
function getIdentityLevels() {
Fast.api.ajax({
url: `shopro/commission/level/select`,
type: 'GET',
}, function (ret, res) {
identity.levels = res.data || []
return false
}, function () { })
}
function getIdentityArea() {
Fast.api.ajax({
url: 'shopro/data/area/select',
type: 'GET',
}, function (ret, res) {
identity.areaSelect = res.data || []
return false
}, function () { })
}
function findAreaPath(nodes, targetId, path = []) {
for (const node of (nodes || [])) {
const next = path.concat([node.id])
if (String(node.id) === String(targetId)) {
return next
}
const found = findAreaPath(node.children, targetId, next)
if (found) return found
}
return null
}
function onOpenIdentity(row) {
getIdentityLevels()
getIdentityArea()
identity.form = {
user_id: row.user_id,
nickname: row.user?.nickname || row.user_id,
before_text: row.identity_text || '',
level: Number(row.level || 1),
is_venue: Number(row.is_venue || 0),
is_county: Number(row.is_county || 0),
is_partner: Number(row.is_partner || 0),
county_code: row.county_code || '',
area_arr: row.county_code ? findAreaPath(identity.areaSelect, row.county_code) || [] : [],
upgrade_lock: Number(row.upgrade_lock || 0),
role_names: row.role_names || row.custom_role_names || {},
remark: '',
}
identity.visible = true
// area may load async; retry path once loaded
setTimeout(() => {
if (identity.form.county_code && (!identity.form.area_arr || !identity.form.area_arr.length)) {
identity.form.area_arr = findAreaPath(identity.areaSelect, identity.form.county_code) || []
}
}, 400)
}
function onIdentityAreaChange(val) {
if (Array.isArray(val) && val.length) {
identity.form.county_code = String(val[val.length - 1])
} else {
identity.form.county_code = ''
}
}
function identityLabel(level, isVenue, isCounty, isPartner, roleNames) {
const rn = roleNames || identity.form?.role_names || {}
const tasterTitle = rn.taster || '品酒师'
const makerTitle = rn.maker || '创客'
const venueTitle = rn.venue || '酒道馆'
const countyTitle = rn.county || '区县代理'
const partnerTitle = rn.partner || '合伙股东'
const lv = identity.levels.find(i => Number(i.level) === Number(level))
let name = lv?.name || (Number(level) === 1 ? tasterTitle : `${makerTitle}V${Number(level) - 1}`)
const tags = [name]
if (Number(isVenue)) tags.push(venueTitle)
if (Number(isCounty)) tags.push(countyTitle)
if (Number(isPartner)) tags.push(partnerTitle)
return tags.filter((v, i, a) => a.indexOf(v) === i).join(' · ')
}
function onSubmitIdentity() {
if (identity.form.is_county && !identity.form.county_code) {
ElementPlus.ElMessage.error('开通区县代理时请选择区县')
return
}
const { ElMessageBox } = ElementPlus
const afterText = identityLabel(identity.form.level, identity.form.is_venue, identity.form.is_county, identity.form.is_partner)
const name = identity.form.nickname || identity.form.user_id
ElMessageBox.confirm(
`将「${name}」从 ${identity.form.before_text || '当前身份'} 调整为 ${afterText}。已入账收益不追溯。确定?`,
'确认调整身份',
{ confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }
).then(() => {
identity.loading = true
Fast.api.ajax({
url: `shopro/commission/agent/identity/id/${identity.form.user_id}`,
type: 'POST',
data: {
level: identity.form.level,
is_venue: identity.form.is_venue,
is_county: identity.form.is_county,
county_code: identity.form.county_code,
upgrade_lock: identity.form.upgrade_lock,
remark: identity.form.remark,
},
}, function () {
identity.loading = false
identity.visible = false
getData()
}, function () {
identity.loading = false
})
}).catch(() => {})
}
onMounted(() => {
getLevelSelect()
getData()
})
return {
...Controller.data(),
state,
type,
getData,
onOpenFilter,
onChangeFilter,
onChangeTab,
pagination,
onEdit,
onDetail,
identity,
onOpenIdentity,
onIdentityAreaChange,
onSubmitIdentity,
}
}
}
createApp('index', index);
},
detail: () => {
const { reactive, onMounted } = Vue
const detail = {
setup() {
const queryAgentId = (typeof Config !== 'undefined' && (Config.id || Config.agent_id || Config.user_id))
? (Config.id || Config.agent_id || Config.user_id)
: (new URLSearchParams(location.search).get('id') || (location.pathname.match(/\/id\/(\d+)/i) || [])[1] || Fast.api.query('id'));
const state = reactive({
id: queryAgentId,
data: {},
})
function onBack() {
if (parent && parent.Layer && typeof parent.Layer.getFrameIndex === 'function') {
try {
var index = parent.Layer.getFrameIndex(window.name);
if (index) {
parent.Layer.close(index);
return;
}
} catch (e) {}
}
if (top && top.Backend && top.Backend.api && typeof top.Backend.api.closetabs === 'function') {
top.Backend.api.closetabs();
} else {
window.history.back();
}
}
function getDetail() {
Fast.api.ajax({
url: `shopro/commission/agent/detail/id/${state.id}`,
type: 'GET',
}, function (ret, res) {
state.data = res.data
applyInfo.data = JSON.parse(JSON.stringify(state.data.apply_info))
getLog()
return false
}, function (ret, res) { })
}
function onChangeStatus(status) {
onEdit({ status });
}
function onChangeLevel() {
Fast.api.open(`shopro/commission/level/select?level=${state.data.level}`, "更换分销等级", {
callback(level) {
onEditIdentity({ level });
}
})
}
function onChangeParentUser() {
Fast.api.open(`shopro/commission/agent/select?id=${state.data.user_id}`, "更换上级分销商", {
callback() {
getDetail()
}
})
}
const applyInfo = reactive({
flag: false,
data: []
})
function onCancelApplyInfo() {
applyInfo.data = JSON.parse(JSON.stringify(state.data.apply_info));
applyInfo.flag = false;
}
function onSaveApplyInfo() {
onEdit({ apply_info: applyInfo.data });
applyInfo.flag = false;
}
function onDeleteApplyInfo(index) {
applyInfo.data.splice(index, 1);
}
function onEdit(data) {
Fast.api.ajax({
url: `shopro/commission/agent/edit/id/${state.id}`,
type: 'POST',
data,
}, function (ret, res) {
getDetail()
}, function (ret, res) { })
}
function onEditIdentity(data) {
onOpenIdentity()
}
const identity = reactive({
visible: false,
loading: false,
levels: [],
areaSelect: [],
form: {
nickname: '',
before_text: '',
level: 1,
is_venue: 0,
is_county: 0,
county_code: '',
area_arr: [],
upgrade_lock: 0,
remark: '',
}
})
function findAreaPath(nodes, targetId, path = []) {
for (const node of (nodes || [])) {
const next = path.concat([node.id])
if (String(node.id) === String(targetId)) return next
const found = findAreaPath(node.children, targetId, next)
if (found) return found
}
return null
}
function onOpenIdentity() {
Fast.api.ajax({ url: 'shopro/commission/level/select', type: 'GET' }, function (ret, res) {
identity.levels = res.data || []
return false
}, function () { })
Fast.api.ajax({ url: 'shopro/data/area/select', type: 'GET' }, function (ret, res) {
identity.areaSelect = res.data || []
if (identity.form.county_code) {
identity.form.area_arr = findAreaPath(identity.areaSelect, identity.form.county_code) || []
}
return false
}, function () { })
identity.form = {
nickname: state.data.user?.nickname || state.data.user_id,
before_text: state.data.identity_text || '',
level: Number(state.data.level || 1),
is_venue: Number(state.data.is_venue || 0),
is_county: Number(state.data.is_county || 0),
is_partner: Number(state.data.is_partner || 0),
county_code: state.data.county_code || '',
area_arr: [],
upgrade_lock: Number(state.data.upgrade_lock || 0),
remark: '',
}
identity.visible = true
}
function onIdentityAreaChange(val) {
identity.form.county_code = Array.isArray(val) && val.length ? String(val[val.length - 1]) : ''
}
function onSubmitIdentity() {
if (identity.form.is_county && !identity.form.county_code) {
ElementPlus.ElMessage.error('开通区县代理时请选择区县')
return
}
const { ElMessageBox } = ElementPlus
const rn = state.data.custom_role_names || state.data.role_names || {}
const tasterTitle = rn.taster || '品酒师'
const makerTitle = rn.maker || '创客'
const venueTitle = rn.venue || '酒道馆'
const countyTitle = rn.county || '区县代理'
const partnerTitle = rn.partner || '合伙股东'
const lv = identity.levels.find(i => Number(i.level) === Number(identity.form.level))
const tags = []
if (Number(identity.form.level) >= 2) tags.push(lv?.name || `${makerTitle}V${identity.form.level - 1}`)
else tags.push(lv?.name || tasterTitle)
if (Number(identity.form.is_venue)) tags.push(venueTitle)
if (Number(identity.form.is_county)) tags.push(countyTitle)
if (Number(identity.form.is_partner)) tags.push(partnerTitle)
const after = tags.filter((v, i, a) => a.indexOf(v) === i).join(' · ')
ElMessageBox.confirm(
`将「${identity.form.nickname}」从 ${identity.form.before_text || '当前身份'} 调整为 ${after}。已入账收益不追溯。确定?`,
'确认调整身份',
{ type: 'warning' }
).then(() => {
identity.loading = true
Fast.api.ajax({
url: `shopro/commission/agent/identity/id/${state.id}`,
type: 'POST',
data: {
level: identity.form.level,
is_venue: identity.form.is_venue,
is_county: identity.form.is_county,
county_code: identity.form.county_code,
upgrade_lock: identity.form.upgrade_lock,
remark: identity.form.remark,
},
}, function () {
identity.loading = false
identity.visible = false
getDetail()
}, function () { identity.loading = false })
}).catch(() => {})
}
function onTeam() {
Fast.api.open(`shopro/commission/agent/team?id=${state.id}`, "查看团队")
}
const log = reactive({
tabActive: 'log',
data: [],
status: {
0: 'info',
1: 'success',
'-1': 'warning',
'-2': 'danger',
}
})
function getLog() {
let search = composeFilter({ agent_id: state.id });
Fast.api.ajax({
url: `shopro/commission/${log.tabActive}`,
type: 'GET',
data: {
page: pagination.page,
list_rows: pagination.list_rows,
...search,
},
}, function (ret, res) {
if (log.tabActive == 'order') {
log.data = res.data.list.data;
pagination.total = res.data.list.total;
} else {
log.data = res.data.data;
pagination.total = res.data.total;
}
return false
}, function (ret, res) { })
}
function onChangeTab() {
pagination.page = 1
log.data = []
getLog()
}
const pagination = reactive({
page: 1,
list_rows: 10,
total: 0,
})
function countCommission(item) {
if (item) {
let commission = 0;
let commissioned = 0;
item.forEach((r) => {
if (r.status == 1) {
commissioned += Number(r.commission);
}
commission += Number(r.commission);
});
return `${commission}元/${commissioned}元`;
}
}
onMounted(() => {
getDetail()
})
return {
...Controller.data(),
state,
getDetail,
onChangeStatus,
onChangeLevel,
onChangeParentUser,
applyInfo,
onCancelApplyInfo,
onSaveApplyInfo,
onDeleteApplyInfo,
onEdit,
onEditIdentity,
onOpenIdentity,
onIdentityAreaChange,
onSubmitIdentity,
identity,
onTeam,
log,
getLog,
onChangeTab,
pagination,
countCommission,
onBack,
}
}
}
createApp('detail', detail);
},
select: () => {
const { reactive, onMounted } = Vue
const { ElMessage } = ElementPlus
const select = {
setup() {
const state = reactive({
id: new URLSearchParams(location.search).get('id'),
data: [],
filter: {
data: {
user: { field: 'user_id', value: '' },
},
},
userDetail: {},
parent_user_id: ''
})
async function getUserDetail() {
Fast.api.ajax({
url: `shopro/user/user/detail/id/${state.id}`,
type: 'GET',
}, function (ret, res) {
state.userDetail = res.data;
state.parent_user_id = state.userDetail?.parent_user_id;
return false
}, function (ret, res) { })
}
function getData() {
let tempSearch = JSON.parse(JSON.stringify(state.filter.data));
let search = composeFilter(tempSearch, {
'user.nickname': 'like',
'user.mobile': 'like',
});
Fast.api.ajax({
url: 'shopro/commission/agent/select',
type: 'GET',
data: {
page: pagination.page,
list_rows: pagination.list_rows,
...search,
},
}, function (ret, res) {
state.data = res.data.data
pagination.total = res.data.total
return false
}, function (ret, res) { })
}
const pagination = reactive({
page: 1,
list_rows: 10,
total: 0,
})
function onSelect(row) {
state.parent_user_id = row.user_id;
}
async function onConfirm() {
if (state.parent_user_id == -1) {
ElMessage.info('请选择上级');
return;
}
Fast.api.ajax({
url: `shopro/commission/agent/changeParentUser/id/${state.id}`,
type: 'POST',
data: {
parent_user_id: state.parent_user_id,
},
}, function (ret, res) {
Fast.api.close()
}, function (ret, res) { })
}
onMounted(() => {
getUserDetail()
getData()
})
return {
...Controller.data(),
state,
getData,
pagination,
onSelect,
onConfirm,
}
}
}
createApp('select', select);
},
team: () => {
const { reactive, onMounted } = Vue
const team = {
setup() {
const state = reactive({
id: new URLSearchParams(location.search).get('id'),
data: {},
})
async function getTeam(id) {
Fast.api.ajax({
url: `shopro/commission/agent/team/id/${id}`,
type: 'GET',
}, function (ret, res) {
state.data = res.data;
return false
}, function (ret, res) { })
}
onMounted(() => {
getTeam(state.id)
})
return {
...Controller.data(),
state,
getTeam,
}
}
}
createApp('team', team);
},
};
return Controller;
});