# Conflicts:
#	.env.base
dev-cl
caolin 4 weeks ago
commit d74161b8ce
  1. 7
      src/api/xjapplet/resell.js
  2. 9
      src/api/xjapplet/vip.js
  3. 25
      src/permission.js
  4. 29
      src/router/modules/remaining.ts
  5. 4
      src/store/modules/dict.ts
  6. 2
      src/store/modules/user.ts
  7. 24
      src/utils/auth.ts
  8. 109
      src/views/XjApplet/Vip/components/Recharge.vue
  9. 28
      src/views/XjApplet/Vip/components/VipType.vue
  10. 4
      src/views/XjApplet/Vip/index.vue

@ -30,3 +30,10 @@ export const getResellDetail = async (id) => {
url: '/admin-api/applet/xunjia/distribution/' + id url: '/admin-api/applet/xunjia/distribution/' + id
}) })
} }
export const getResellSimpleList = async (params) => {
return await request.get({
url: '/admin-api/applet/xunjia/distribution/simple-list',
params: params
})
}

@ -37,7 +37,7 @@ export const updateVipType = async (data) => {
export const deleteVipType = async (id) => { export const deleteVipType = async (id) => {
return await request.delete({ return await request.delete({
url: '/admin-api/applet/xunjia/member/memberId?id=' + id url: '/admin-api/applet/xunjia/member/delete?memberId=' + id
}) })
} }
@ -47,3 +47,10 @@ export const getVipTypeOptions = async (params) => {
params: params params: params
}) })
} }
export const getRechargeRecords = async (params) => {
return await request.get({
url: '/admin-api/applet/xunjia/pay/list',
params: params
})
}

@ -7,7 +7,8 @@ import { usePageLoading } from '@/hooks/web/usePageLoading'
import { useDictStoreWithOut } from '@/store/modules/dict' import { useDictStoreWithOut } from '@/store/modules/dict'
import { useUserStoreWithOut } from '@/store/modules/user' import { useUserStoreWithOut } from '@/store/modules/user'
import { usePermissionStoreWithOut } from '@/store/modules/permission' import { usePermissionStoreWithOut } from '@/store/modules/permission'
import { getTenantId, getAppId } from '@/utils/auth' import { useAppStoreWithOut } from '@/store/modules/app'
import { getTenantId, getAppId, setTenantId, setAppId } from '@/utils/auth'
import cache from '@/plugins/cache' import cache from '@/plugins/cache'
const { start, done } = useNProgress() const { start, done } = useNProgress()
@ -39,13 +40,17 @@ router.beforeEach(async (to, from, next) => {
} else { } else {
if (getAccessToken()) { if (getAccessToken()) {
if (to.path === '/login') { if (to.path === '/login') {
if (to.query?.tenantId && to.query?.appId) {
setApp(to.query.tenantId, to.query.appId)
await waitTime(1500)
}
next({ path: '/' }) next({ path: '/' })
} else { } else {
// 获取所有字典 // 获取所有字典
const dictStore = useDictStoreWithOut() const dictStore = useDictStoreWithOut()
const userStore = useUserStoreWithOut() const userStore = useUserStoreWithOut()
const permissionStore = usePermissionStoreWithOut() const permissionStore = usePermissionStoreWithOut()
if (!dictStore.getIsSetDict && to.path != '/nm-detail') { if (!dictStore.getIsSetDict) {
await dictStore.setDictMap() await dictStore.setDictMap()
} }
if (!userStore.getIsSetUser) { if (!userStore.getIsSetUser) {
@ -81,6 +86,22 @@ router.beforeEach(async (to, from, next) => {
} }
}) })
async function waitTime(seconds) {
return new Promise((resolve) => {
setTimeout(() => {
resolve()
}, seconds)
})
}
function setApp(tenantId, appId) {
setTenantId(tenantId)
setAppId(appId)
const appStore = useAppStoreWithOut()
appStore.setAppInfo(appId)
}
router.afterEach((to) => { router.afterEach((to) => {
useTitle(to?.meta?.title) useTitle(to?.meta?.title)
done() // 结束Progress done() // 结束Progress

@ -51,7 +51,7 @@ const remainingRouter: AppRouteRecordRaw[] = [
} }
}, },
{ {
path: '', path: '/',
component: Layout, component: Layout,
redirect: '/Home/index', redirect: '/Home/index',
name: '', name: '',
@ -59,6 +59,31 @@ const remainingRouter: AppRouteRecordRaw[] = [
title: '首页', title: '首页',
hidden: true hidden: true
} }
// children: [
// {
// path: '/index',
// component: () => import('@/views/Home/Index.vue'),
// name: 'Home',
// meta: {
// title: '首页',
// icon: 'ep:home-filled',
// noTagsView: true,
// affix: true
// // hidden: true
// }
// }
// {
// path: 'menu',
// component: () => import('@/views/Basic/Menu/index.vue'),
// name: 'Menu',
// meta: {
// affix: true,
// noTagsView: true,
// icon: 'ep:user',
// title: '菜单管理'
// }
// }
// ]
}, },
{ {
path: '/swagger', path: '/swagger',
@ -133,8 +158,8 @@ const remainingRouter: AppRouteRecordRaw[] = [
// path: '/Basic', // path: '/Basic',
// component: Layout, // component: Layout,
// name: 'Basic', // name: 'Basic',
// meta: { title: '菜单管理' },
// redirect: '/Basic/menu', // redirect: '/Basic/menu',
// meta: { title: '菜单管理' },
// children: [ // children: [
// { // {
// path: 'menu', // path: 'menu',

@ -45,7 +45,7 @@ export const useDictStore = defineStore('dict', {
this.dictMap = dictMap this.dictMap = dictMap
this.isSetDict = true this.isSetDict = true
} else { } else {
const res = await listSimpleDictData() const res = (await listSimpleDictData()) || []
// 设置数据 // 设置数据
const dictDataMap = new Map<string, any>() const dictDataMap = new Map<string, any>()
res.forEach((dictData: DictDataVO) => { res.forEach((dictData: DictDataVO) => {
@ -75,7 +75,7 @@ export const useDictStore = defineStore('dict', {
}, },
async resetDict() { async resetDict() {
cache.session.delete(CACHE_KEY.DICT_CACHE) cache.session.delete(CACHE_KEY.DICT_CACHE)
const res = await listSimpleDictData() const res = (await listSimpleDictData()) || []
// 设置数据 // 设置数据
const dictDataMap = new Map<string, any>() const dictDataMap = new Map<string, any>()
res.forEach((dictData: DictDataVO) => { res.forEach((dictData: DictDataVO) => {

@ -64,7 +64,7 @@ export const useUserStore = defineStore('admin-user', {
async loginOut() { async loginOut() {
await loginOut() await loginOut()
removeToken() removeToken()
cache.local.clear() // cache.local.clear()
this.resetState() this.resetState()
}, },
resetState() { resetState() {

@ -8,26 +8,34 @@ const RefreshTokenKey = 'REFRESH_TOKEN'
// 获取token // 获取token
export const getAccessToken = () => { export const getAccessToken = () => {
// 此处与TokenKey相同,此写法解决初始化时Cookies中不存在TokenKey报错 // 此处与TokenKey相同,此写法解决初始化时Cookies中不存在TokenKey报错
return cache.local.get(AccessTokenKey) return localStorage.getItem(AccessTokenKey)
? cache.local.get(AccessTokenKey) ? localStorage.getItem(AccessTokenKey)
: cache.local.get('ACCESS_TOKEN') : localStorage.getItem('ACCESS_TOKEN')
// return cache.local.get(AccessTokenKey)
// ? cache.local.get(AccessTokenKey)
// : cache.local.get('ACCESS_TOKEN')
} }
// 刷新token // 刷新token
export const getRefreshToken = () => { export const getRefreshToken = () => {
return cache.local.get(RefreshTokenKey) return localStorage.getItem(RefreshTokenKey)
// return cache.local.get(RefreshTokenKey)
} }
// 设置token // 设置token
export const setToken = (token: TokenType) => { export const setToken = (token: TokenType) => {
cache.local.set(RefreshTokenKey, token.refreshToken) localStorage.setItem(AccessTokenKey, token.accessToken)
cache.local.set(AccessTokenKey, token.accessToken) localStorage.setItem(RefreshTokenKey, token.refreshToken)
// cache.local.set(RefreshTokenKey, token.refreshToken)
// cache.local.set(AccessTokenKey, token.accessToken)
} }
// 删除token // 删除token
export const removeToken = () => { export const removeToken = () => {
cache.local.delete(AccessTokenKey) localStorage.removeItem(AccessTokenKey)
cache.local.delete(RefreshTokenKey) localStorage.removeItem(RefreshTokenKey)
// cache.local.delete(AccessTokenKey)
// cache.local.delete(RefreshTokenKey)
} }
/** 格式化token(jwt格式) */ /** 格式化token(jwt格式) */

@ -0,0 +1,109 @@
<template>
<div>
<el-form :model="searchForm" inline @submit.prevent>
<el-form-item>
<el-input v-model="searchForm.phone" placeholder="学员手机号" />
</el-form-item>
<el-form-item>
<el-select
v-model="searchForm.distributionId"
placeholder="选择分销人"
clearable
filterable
>
<el-option
v-for="item in distributionOptions"
:key="item.distributionId"
:label="item.name"
:value="item.distributionId"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-date-picker
v-model="searchForm.createDate"
type="daterange"
range-separator="-"
value-format="YYYY-MM-DD"
format="YYYY-MM-DD"
start-placeholder="充值日期"
end-placeholder="充值日期"
/>
</el-form-item>
<el-form-item>
<el-button @click="searchList">查询</el-button>
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="tableList" height="calc(100vh - 260px)">
<el-table-column type="index" width="55" align="center" />
<el-table-column label="手机号" align="left" prop="phone" width="140" />
<el-table-column label="会员名" align="left" prop="memberName" min-width="140" />
<el-table-column label="支付金额" align="left" prop="money" min-width="100" />
<el-table-column label="车型" prop="carName" align="left" width="100" />
<el-table-column label="科目" align="left" prop="subjects" width="100" />
<el-table-column label="充值日期" align="left" prop="payTime" min-width="120" />
<el-table-column label="截止日期" align="left" prop="endDate" min-width="120" />
<el-table-column label="分销人" align="left" prop="distributionName" min-width="100" />
</el-table>
<pagination
v-show="total > 0"
:total="total"
v-model:page="searchForm.pageNo"
v-model:limit="searchForm.pageSize"
@pagination="getList"
/>
</div>
</template>
<script setup name="Recharge">
import { getRechargeRecords } from '@/api/xjapplet/vip'
import { getResellSimpleList } from '@/api/xjapplet/resell'
const searchForm = ref({
distributionId: undefined,
phone: undefined,
createDate: [],
pageNo: 1,
pageSize: 50
})
const loading = ref(false)
const tableList = ref([])
const total = ref(0)
const distributionOptions = ref([])
onMounted(() => {
changeCarType()
})
function changeCarType() {
getResellSimpleList().then((response) => {
distributionOptions.value = response
})
searchList()
}
function searchList() {
searchForm.value.pageNo = 1
getList()
}
function getList() {
loading.value = true
if (searchForm.value.createDate && searchForm.value.createDate.length > 0) {
searchForm.value.payTimeBegin = searchForm.value.createDate[0] + ' 00:00:00'
searchForm.value.payTimeEnd = searchForm.value.createDate[1] + ' 23:59:59'
} else {
searchForm.value.payTimeBegin = undefined
searchForm.value.payTimeEnd = undefined
}
getRechargeRecords(searchForm.value).then((response) => {
tableList.value = response.list
total.value = response.total
loading.value = false
})
}
</script>
<style lang="scss" scoped></style>

@ -6,8 +6,8 @@
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-radio-group v-model="searchForm.carTypeId" @change="searchList"> <el-radio-group v-model="searchForm.carTypeId" @change="searchList">
<el-radio label="1001">小车</el-radio> <el-radio :label="1001">小车</el-radio>
<el-radio label="1002">摩托车</el-radio> <el-radio :label="1002">摩托车</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
@ -68,14 +68,14 @@
</el-form-item> </el-form-item>
<el-form-item label="车型" prop="carTypeId"> <el-form-item label="车型" prop="carTypeId">
<el-select v-model="form.carTypeId" style="width: 100%"> <el-select v-model="form.carTypeId" style="width: 100%">
<el-option label="小车" value="1001" /> <el-option label="小车" :value="1001" />
<el-option label="摩托车" value="1002" /> <el-option label="摩托车" :value="1002" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="科目" prop="subjects"> <el-form-item label="科目" prop="subjectList">
<el-select v-model="form.subjects" placeholder="多选" multiple style="width: 100%"> <el-select v-model="form.subjectList" placeholder="多选" multiple style="width: 100%">
<el-option label="科一" value="4" /> <el-option label="科一" value="1" />
<el-option label="科四" value="1" /> <el-option label="科四" value="4" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="原价" prop="price"> <el-form-item label="原价" prop="price">
@ -116,7 +116,7 @@ import { getVipTypeList, addVipType, updateVipType, deleteVipType } from '@/api/
const message = useMessage() const message = useMessage()
const searchForm = ref({ const searchForm = ref({
memberName: undefined, memberName: undefined,
carTypeId: '1001', carTypeId: 1001,
pageNo: 1, pageNo: 1,
pageSize: 50 pageSize: 50
}) })
@ -146,7 +146,7 @@ const showDialog = ref(false)
const form = ref({ const form = ref({
memberName: '', memberName: '',
carTypeId: undefined, carTypeId: undefined,
subjects: [], subjectList: [],
price: '', price: '',
discount: '', discount: '',
duration: '', duration: '',
@ -156,7 +156,7 @@ const form = ref({
const rules = ref({ const rules = ref({
memberName: [{ required: true, message: '请输入会员名称', trigger: 'blur' }], memberName: [{ required: true, message: '请输入会员名称', trigger: 'blur' }],
carTypeId: [{ required: true, message: '请输入车型', trigger: 'change' }], carTypeId: [{ required: true, message: '请输入车型', trigger: 'change' }],
subjects: [{ required: true, message: '请输入科目', trigger: 'blur' }], subjectList: [{ required: true, message: '请输入科目', trigger: 'blur' }],
price: [{ required: true, message: '请输入价格', trigger: 'blur' }], price: [{ required: true, message: '请输入价格', trigger: 'blur' }],
discount: [{ required: true, message: '请输入折扣价', trigger: 'blur' }], discount: [{ required: true, message: '请输入折扣价', trigger: 'blur' }],
duration: [{ required: true, message: '请输入有效期', trigger: 'blur' }] duration: [{ required: true, message: '请输入有效期', trigger: 'blur' }]
@ -165,10 +165,10 @@ const rules = ref({
function addVip() { function addVip() {
showDialog.value = true showDialog.value = true
form.value.carTypeId = { form.value = {
memberName: '', memberName: '',
carTypeId: searchForm.value.carTypeId, carTypeId: searchForm.value.carTypeId,
subjects: [], subjectList: [],
price: '', price: '',
discount: '', discount: '',
duration: '', duration: '',
@ -178,7 +178,7 @@ function addVip() {
} }
function editVip(row) { function editVip(row) {
form.value = { ...row, subjects: row.subjects.split(','), unit: Number(row.unit) } form.value = { ...row, unit: Number(row.unit) }
showDialog.value = true showDialog.value = true
} }

@ -13,6 +13,9 @@
<el-tab-pane label="用户折扣" :name="4" v-if="checkPermi(['xj-applet:vip:user-discount'])"> <el-tab-pane label="用户折扣" :name="4" v-if="checkPermi(['xj-applet:vip:user-discount'])">
<UserDiscount v-if="tabIndex == 4" /> <UserDiscount v-if="tabIndex == 4" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="充值记录" :name="5" v-if="checkPermi(['xj-applet:vip:recharge'])">
<Recharge v-if="tabIndex == 5" />
</el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</template> </template>
@ -23,6 +26,7 @@ import UserDiscount from './components/UserDiscount.vue'
import VipDiscount from './components/VipDiscount.vue' import VipDiscount from './components/VipDiscount.vue'
import VipType from './components/VipType.vue' import VipType from './components/VipType.vue'
import VipUser from './components/VipUser.vue' import VipUser from './components/VipUser.vue'
import Recharge from './components/Recharge.vue'
const tabIndex = ref(1) const tabIndex = ref(1)
</script> </script>

Loading…
Cancel
Save