fix(admin): add distribution views and correct dist ignore rule
Wire router imports to promoter list and retail config pages. Remove the overbroad dist* gitignore entry that matched src/views/distribution/. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1
msh_single_admin/.gitignore
vendored
1
msh_single_admin/.gitignore
vendored
@@ -1,7 +1,6 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
node_modules/
|
node_modules/
|
||||||
dist/
|
dist/
|
||||||
dist*/
|
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
|
|||||||
136
msh_single_admin/src/views/distribution/config/index.vue
Normal file
136
msh_single_admin/src/views/distribution/config/index.vue
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
<template>
|
||||||
|
<div class="divBox">
|
||||||
|
<el-card v-loading="loading" class="box-card">
|
||||||
|
<el-form
|
||||||
|
v-if="formVisible"
|
||||||
|
ref="formRef"
|
||||||
|
:model="form"
|
||||||
|
:rules="rules"
|
||||||
|
label-width="160px"
|
||||||
|
size="small"
|
||||||
|
class="mt20"
|
||||||
|
>
|
||||||
|
<el-form-item label="启用分销" prop="brokerageFuncStatus">
|
||||||
|
<el-radio-group v-model="form.brokerageFuncStatus">
|
||||||
|
<el-radio :label="1">启用</el-radio>
|
||||||
|
<el-radio :label="0">关闭</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="分销额度(元)" prop="storeBrokerageQuota">
|
||||||
|
<el-input-number v-model="form.storeBrokerageQuota" :min="-1" :step="1" controls-position="right" />
|
||||||
|
<span class="ml10 text-muted">-1 关闭;≥0 用户累计消费达该金额自动成为分销员</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="一级返佣比例(%)" prop="storeBrokerageRatio">
|
||||||
|
<el-input-number v-model="form.storeBrokerageRatio" :min="0" :max="100" controls-position="right" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="二级返佣比例(%)" prop="storeBrokerageTwo">
|
||||||
|
<el-input-number v-model="form.storeBrokerageTwo" :min="0" :max="100" controls-position="right" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="分销关系绑定" prop="brokerageBindind">
|
||||||
|
<el-radio-group v-model="form.brokerageBindind">
|
||||||
|
<el-radio :label="0">所有用户</el-radio>
|
||||||
|
<el-radio :label="1">仅新用户</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="提现最低金额" prop="userExtractMinPrice">
|
||||||
|
<el-input-number v-model="form.userExtractMinPrice" :min="0" :precision="2" :step="1" controls-position="right" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="提现银行说明" prop="userExtractBank">
|
||||||
|
<el-input v-model="form.userExtractBank" type="textarea" :rows="4" placeholder="每行一个银行或说明" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="佣金冻结时间(天)" prop="extractTime">
|
||||||
|
<el-input-number v-model="form.extractTime" :min="0" :step="1" controls-position="right" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="分销气泡" prop="storeBrokerageIsBubble">
|
||||||
|
<el-radio-group v-model="form.storeBrokerageIsBubble">
|
||||||
|
<el-radio :label="0">展示</el-radio>
|
||||||
|
<el-radio :label="1">不展示</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" v-hasPermi="['admin:retail:spread:manage:set']" @click="submitForm">保存</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { configApi, configUpdateApi } from '@/api/distribution';
|
||||||
|
import { Debounce } from '@/utils/validate';
|
||||||
|
import { checkPermi } from '@/utils/permission';
|
||||||
|
|
||||||
|
const defaultForm = () => ({
|
||||||
|
brokerageFuncStatus: 0,
|
||||||
|
storeBrokerageQuota: -1,
|
||||||
|
storeBrokerageRatio: 0,
|
||||||
|
storeBrokerageTwo: 0,
|
||||||
|
brokerageBindind: 0,
|
||||||
|
userExtractMinPrice: 0,
|
||||||
|
userExtractBank: '',
|
||||||
|
extractTime: 0,
|
||||||
|
storeBrokerageIsBubble: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'DistributionConfig',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
formVisible: false,
|
||||||
|
form: defaultForm(),
|
||||||
|
rules: {
|
||||||
|
brokerageFuncStatus: [{ required: true, message: '请选择', trigger: 'change' }],
|
||||||
|
storeBrokerageQuota: [{ required: true, message: '必填', trigger: 'blur' }],
|
||||||
|
storeBrokerageRatio: [{ required: true, message: '必填', trigger: 'blur' }],
|
||||||
|
storeBrokerageTwo: [{ required: true, message: '必填', trigger: 'blur' }],
|
||||||
|
brokerageBindind: [{ required: true, message: '请选择', trigger: 'change' }],
|
||||||
|
userExtractMinPrice: [{ required: true, message: '必填', trigger: 'blur' }],
|
||||||
|
userExtractBank: [{ required: true, message: '必填', trigger: 'blur' }],
|
||||||
|
extractTime: [{ required: true, message: '必填', trigger: 'blur' }],
|
||||||
|
storeBrokerageIsBubble: [{ required: true, message: '请选择', trigger: 'change' }],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (checkPermi(['admin:retail:spread:manage:get'])) {
|
||||||
|
this.load();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
load() {
|
||||||
|
this.loading = true;
|
||||||
|
this.formVisible = false;
|
||||||
|
configApi()
|
||||||
|
.then((res) => {
|
||||||
|
this.form = Object.assign(defaultForm(), res || {});
|
||||||
|
this.formVisible = true;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
submitForm: Debounce(function () {
|
||||||
|
this.$refs.formRef.validate((valid) => {
|
||||||
|
if (!valid) return;
|
||||||
|
const ration = (this.form.storeBrokerageTwo || 0) + (this.form.storeBrokerageRatio || 0);
|
||||||
|
if (ration > 100) {
|
||||||
|
this.$message.error('一级与二级返佣比例之和不能超过 100%');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
configUpdateApi(this.form).then(() => {
|
||||||
|
this.$message.success('保存成功');
|
||||||
|
this.load();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.text-muted {
|
||||||
|
color: #909399;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
146
msh_single_admin/src/views/distribution/index.vue
Normal file
146
msh_single_admin/src/views/distribution/index.vue
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
<template>
|
||||||
|
<div class="divBox">
|
||||||
|
<el-card class="box-card">
|
||||||
|
<div slot="header" class="clearfix">
|
||||||
|
<div class="container">
|
||||||
|
<el-form inline size="small" @submit.native.prevent>
|
||||||
|
<el-form-item label="关键字:">
|
||||||
|
<el-input
|
||||||
|
v-model="tableFrom.keywords"
|
||||||
|
placeholder="姓名、电话、UID"
|
||||||
|
clearable
|
||||||
|
class="selWidth"
|
||||||
|
@keyup.enter.native="getList(1)"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="时间:">
|
||||||
|
<el-select v-model="tableFrom.dateLimit" placeholder="全部" clearable class="selWidth" @change="getList(1)">
|
||||||
|
<el-option label="今天" value="today" />
|
||||||
|
<el-option label="昨天" value="yesterday" />
|
||||||
|
<el-option label="最近7天" value="lately7" />
|
||||||
|
<el-option label="最近30天" value="lately30" />
|
||||||
|
<el-option label="本月" value="month" />
|
||||||
|
<el-option label="本年" value="year" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="getList(1)">搜索</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-table v-loading="listLoading" :data="tableData.data" style="width: 100%" size="mini">
|
||||||
|
<el-table-column prop="uid" label="UID" min-width="70" />
|
||||||
|
<el-table-column label="头像" min-width="70">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-image
|
||||||
|
v-if="scope.row.avatar"
|
||||||
|
style="width: 36px; height: 36px"
|
||||||
|
:src="scope.row.avatar"
|
||||||
|
:preview-src-list="[scope.row.avatar]"
|
||||||
|
/>
|
||||||
|
<span v-else>—</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="nickname" label="昵称" min-width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ scope.row.nickname | filterEmpty }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="realName" label="姓名" min-width="100">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ scope.row.realName | filterEmpty }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="phone" label="手机号" min-width="110">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ scope.row.phone | filterEmpty }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="spreadNickname" label="上级" min-width="110">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ scope.row.spreadNickname | filterEmpty }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="brokeragePrice" label="未提现佣金" min-width="100" align="right" />
|
||||||
|
<el-table-column prop="totalBrokeragePrice" label="佣金累计" min-width="100" align="right" />
|
||||||
|
<el-table-column prop="spreadCount" label="推广人数" min-width="90" align="center" />
|
||||||
|
<el-table-column prop="spreadOrderNum" label="推广订单数" min-width="100" align="center" />
|
||||||
|
<el-table-column prop="payCount" label="购买次数" min-width="90" align="center" />
|
||||||
|
<el-table-column label="成为分销员时间" min-width="160">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ scope.row.promoterTime ? parseTime(scope.row.promoterTime) : '—' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<div class="block mb20">
|
||||||
|
<el-pagination
|
||||||
|
:page-sizes="[10, 20, 30, 40]"
|
||||||
|
:page-size="tableFrom.limit"
|
||||||
|
:current-page="tableFrom.page"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="tableData.total"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="pageChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { promoterListApi } from '@/api/distribution';
|
||||||
|
import { checkPermi } from '@/utils/permission';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'DistributionIndex',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
listLoading: false,
|
||||||
|
tableFrom: {
|
||||||
|
page: 1,
|
||||||
|
limit: 20,
|
||||||
|
keywords: '',
|
||||||
|
dateLimit: '',
|
||||||
|
},
|
||||||
|
tableData: {
|
||||||
|
data: [],
|
||||||
|
total: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (checkPermi(['admin:retail:list'])) {
|
||||||
|
this.getList(1);
|
||||||
|
} else {
|
||||||
|
this.listLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
checkPermi,
|
||||||
|
getList(num) {
|
||||||
|
this.listLoading = true;
|
||||||
|
this.tableFrom.page = num ? num : this.tableFrom.page;
|
||||||
|
promoterListApi(this.tableFrom)
|
||||||
|
.then((res) => {
|
||||||
|
this.tableData.data = res.list || [];
|
||||||
|
this.tableData.total = res.total != null ? Number(res.total) : 0;
|
||||||
|
this.listLoading = false;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.listLoading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleSizeChange(val) {
|
||||||
|
this.tableFrom.limit = val;
|
||||||
|
this.getList(1);
|
||||||
|
},
|
||||||
|
pageChange(page) {
|
||||||
|
this.tableFrom.page = page;
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
Reference in New Issue
Block a user