Merge branch 'dev_vite' of http://18.167.251.121:10003/aidlab/aida_front into dev_vite

This commit is contained in:
李志鹏
2026-01-07 10:27:50 +08:00
10 changed files with 853 additions and 607 deletions

View File

@@ -96,7 +96,7 @@
style="width: 250px" style="width: 250px"
/> />
</div> </div>
<div class="admin_state_item" v-if="title?.value == 'Edit'"> <!-- <div class="admin_state_item" v-if="title?.value == 'Edit'">
<span> <span>
{{ $t('admin.SubscribePlan') }}: {{ $t('admin.SubscribePlan') }}:
<span>*</span> <span>*</span>
@@ -108,7 +108,7 @@
:field-names="{ label: 'name', value: 'id' }" :field-names="{ label: 'name', value: 'id' }"
:placeholder="$t('admin.SelectPlan')" :placeholder="$t('admin.SelectPlan')"
></a-select> ></a-select>
</div> </div> -->
</div> </div>
<div class="allUserPoeration_btn admin_page"> <div class="allUserPoeration_btn admin_page">
<div class="admin_search_item" @click="cancelDsign">{{ $t('admin.Close') }}</div> <div class="admin_search_item" @click="cancelDsign">{{ $t('admin.Close') }}</div>

View File

@@ -91,11 +91,18 @@
}" }"
@click="plan.status !== 'PENDING' && selectPlanFilter(plan.id)" @click="plan.status !== 'PENDING' && selectPlanFilter(plan.id)"
> >
<span class="plan_name">{{ plan.name }}</span> <a-tooltip v-if="plan.status === 'PENDING'">
<MoreOutlined <template #title>{{ $t('admin.PlanStart') }} {{ plan.startTime }}</template>
class="plan_more_icon" <span class="plan_name">{{ plan.name }}</span>
@click.stop="plan.status !== 'PENDING' && openPlanRenameModal(plan)" <MoreOutlined class="plan_more_icon" />
/> </a-tooltip>
<template v-else>
<span class="plan_name">{{ plan.name }}</span>
<MoreOutlined
class="plan_more_icon"
@click.stop="plan.status !== 'PENDING' && openPlanRenameModal(plan)"
/>
</template>
</div> </div>
</div> </div>
<a-table <a-table
@@ -435,8 +442,11 @@ export default defineComponent({
if (!orgId) return if (!orgId) return
Https.axiosPost(Https.httpUrls.searchSubscribeByOrg, { Https.axiosPost(Https.httpUrls.searchSubscribeByOrg, {
organizationId: orgId, organizationId: orgId,
status: ['ACTIVE','PENDING'] status: ['ACTIVE', 'PENDING']
}).then(res => { }).then(res => {
res.forEach(plan => {
plan.startTime = formatTime(plan.currentPeriodStart, 'YYYY-MM-DD hh:mm:ss')
})
// 将与当前用户 subscriptionPlanId 相同的订阅计划放到第一个 // 将与当前用户 subscriptionPlanId 相同的订阅计划放到第一个
const userSubscriptionPlanId = store.state.UserHabit.userDetail.subscriptionPlanId const userSubscriptionPlanId = store.state.UserHabit.userDetail.subscriptionPlanId
if (userSubscriptionPlanId && Array.isArray(res)) { if (userSubscriptionPlanId && Array.isArray(res)) {
@@ -451,6 +461,7 @@ export default defineComponent({
} else { } else {
planFilterOptions.value = res planFilterOptions.value = res
} }
console.log(planFilterOptions.value)
}) })
} }
// 监听组织ID获取到值后再拉取订阅计划 // 监听组织ID获取到值后再拉取订阅计划
@@ -459,7 +470,8 @@ export default defineComponent({
orgId => { orgId => {
if (orgId) { if (orgId) {
fetchSubscribePlanList() fetchSubscribePlanList()
const userSubscriptionPlanId = store.state.UserHabit.userDetail.subscriptionPlanId const userSubscriptionPlanId =
store.state.UserHabit.userDetail.subscriptionPlanId
if (userSubscriptionPlanId) { if (userSubscriptionPlanId) {
selectPlanFilter(userSubscriptionPlanId) selectPlanFilter(userSubscriptionPlanId)
} }

View File

@@ -31,7 +31,7 @@
:filter-option="filterOption" :filter-option="filterOption"
placeholder="Select Item..." placeholder="Select Item..."
max-tag-count="responsive" max-tag-count="responsive"
:options="countryList" :options="allCountry"
></a-select> ></a-select>
</div> </div>
<div class="admin_state_item"> <div class="admin_state_item">
@@ -192,9 +192,6 @@ export default defineComponent({
cityList: computed(()=>{ cityList: computed(()=>{
return store.state.adminPage.city return store.state.adminPage.city
}), }),
countryList: computed(()=>{
return store.state.adminPage.country
}),
isAwayOrUnfold:false, isAwayOrUnfold:false,
}); });
let filterData: any = reactive({ let filterData: any = reactive({
@@ -471,9 +468,10 @@ export default defineComponent({
filter.dataList = rv.content; filter.dataList = rv.content;
filterData.total = rv.total; filterData.total = rv.total;
filter.tableLoading = false; filter.tableLoading = false;
rv.content.forEach((item: any) => { filterData.totalPayer = rv.content.reduce((total: number, item: any) => {
filterData.totalPayer += Number(item.payerTotal) const value = item && item.status === 'Success' ? parseFloat(item.payerTotal) : 0;
}) return total + (isNaN(value) ? 0 : value);
}, 0);
// this.workspaceItem.position = this.singleTypeList[0].label // this.workspaceItem.position = this.singleTypeList[0].label
} }

View File

@@ -1,352 +1,392 @@
<template> <template>
<div class="allUserPoerationModal" ref="allUserPoerationModal"></div> <div class="allUserPoerationModal" ref="allUserPoerationModal"></div>
<a-modal <a-modal
class="allUserPoeration_modal generalModel" class="allUserPoeration_modal generalModel"
v-model:visible="operationsModal" v-model:visible="operationsModal"
:footer="null" :footer="null"
:get-container="() => $refs.allUserPoerationModal" :get-container="() => $refs.allUserPoerationModal"
width="50%" width="50%"
:maskClosable="false" :maskClosable="false"
:centered="true" :centered="true"
:closable="false" :closable="false"
:mask="true" :mask="true"
wrapClassName="#app" wrapClassName="#app"
:keyboard="false" :keyboard="false"
> >
<div class="generalModel_btn"> <div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="cancelDsign()"> <div class="generalModel_closeIcon" @click.stop="cancelDsign()">
<svg width="100%" height="100%" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg
<circle cx="23" cy="23" r="23" fill="#000" fill-opacity="0.3"/> width="100%"
<rect x="32.5063" y="12" width="3" height="29" rx="1.5" transform="rotate(45 32.5063 12)" fill="white"/> height="100%"
<rect x="34.6274" y="32.5059" width="3" height="29" rx="1.5" transform="rotate(135 34.6274 32.5059)" fill="white"/> viewBox="0 0 46 46"
</svg> fill="none"
xmlns="http://www.w3.org/2000/svg"
</div> >
</div> <circle cx="23" cy="23" r="23" fill="#000" fill-opacity="0.3" />
<div class="modal_title_text"> <rect
<div>{{ title }} User</div> x="32.5063"
</div> y="12"
<div class="allUserPoeration_center admin_page"> width="3"
<div class="admin_state_item"> height="29"
<span>User Name: <span>*</span></span> rx="1.5"
<input transform="rotate(45 32.5063 12)"
:disabled="title != 'Add'" fill="white"
:class="{active:title != 'Add'}" />
v-model="userName" <rect
placeholder="Please enter user name" x="34.6274"
type="text" y="32.5059"
style="width: 250px" width="3"
/> height="29"
</div> rx="1.5"
<div class="admin_state_item"> transform="rotate(135 34.6274 32.5059)"
<span>User Email: <span>*</span></span> fill="white"
<input />
:disabled="title != 'Add'" </svg>
:class="{active:title != 'Add'}" </div>
v-model="userEmail" </div>
placeholder="Please enter email" <div class="modal_title_text">
type="text" <div>{{ title }} User</div>
style="width: 250px" </div>
/> <div class="allUserPoeration_center admin_page">
</div> <div class="admin_state_item">
<div class="admin_state_item"> <span>
<span>Create Time: <span>*</span></span> User Name:
<a-date-picker :disabled="title != 'Add'" style="width: 250px" valueFormat="YYYY-MM-DDTHH:mm:ss" class="range_picker" show-time placeholder="Create Time" v-model:value="validStartTime"> <span>*</span>
<template #suffixIcon> </span>
<span <input
class="icon iconfont range_picker_icon icon-rili" :disabled="title != 'Add'"
></span> :class="{ active: title != 'Add' }"
</template> v-model="userName"
</a-date-picker> placeholder="Please enter user name"
</div> type="text"
<div class="admin_state_item"> style="width: 250px"
<span>End Time: <span>*</span></span> />
<a-date-picker style="width: 250px" valueFormat="YYYY-MM-DDTHH:mm:ss" class="range_picker" show-time placeholder="End Time" v-model:value="validEndTime"> </div>
<template #suffixIcon> <div class="admin_state_item">
<span <span>
class="icon iconfont range_picker_icon icon-rili" User Email:
></span> <span>*</span>
</template> </span>
</a-date-picker> <input
</div> :disabled="title != 'Add'"
<div class="admin_state_item"> :class="{ active: title != 'Add' }"
<span>User Type:<span>*</span></span> v-model="userEmail"
<a-select placeholder="Please enter email"
v-model:value="systemUser" type="text"
size="large" style="width: 250px"
style="width: 250px" />
optionFilterProp="label" </div>
:options="state" <div class="admin_state_item">
placeholder="Please select" <span>
allowClear Create Time:
show-search <span>*</span>
></a-select> </span>
</div> <a-date-picker
<div class="admin_state_item"> :disabled="title != 'Add'"
<span>Credits:</span> style="width: 250px"
<input valueFormat="YYYY-MM-DDTHH:mm:ss"
v-model="credits" class="range_picker"
placeholder="Please enter credits" show-time
type="text" placeholder="Create Time"
style="width: 250px" v-model:value="validStartTime"
/> >
</div> <template #suffixIcon>
<div class="admin_state_item"> <span class="icon iconfont range_picker_icon icon-rili"></span>
<span>Country or Region:</span> </template>
<input </a-date-picker>
</div>
<div class="admin_state_item">
<span>
End Time:
<span>*</span>
</span>
<a-date-picker
style="width: 250px"
valueFormat="YYYY-MM-DDTHH:mm:ss"
class="range_picker"
show-time
placeholder="End Time"
v-model:value="validEndTime"
>
<template #suffixIcon>
<span class="icon iconfont range_picker_icon icon-rili"></span>
</template>
</a-date-picker>
</div>
<div class="admin_state_item">
<span>
User Type:
<span>*</span>
</span>
<a-select
v-model:value="systemUser"
size="large"
style="width: 250px"
optionFilterProp="label"
:options="state"
placeholder="Please select"
allowClear
show-search
></a-select>
</div>
<div class="admin_state_item">
<span>Credits:</span>
<input
v-model="credits"
placeholder="Please enter credits"
type="text"
style="width: 250px"
/>
</div>
<div class="admin_state_item">
<span>Country or Region:</span>
<!-- <input
:disabled="title != 'Add'" :disabled="title != 'Add'"
:class="{active:title != 'Add'}" :class="{active:title != 'Add'}"
v-model="country" v-model="country"
placeholder="Please enter country" placeholder="Please enter country"
type="text" type="text"
style="width: 250px" style="width: 250px"
/> /> -->
</div> <a-select
<div class="admin_state_item"> v-model:value="country"
<span>Organization Name:</span> :disabled="title != 'Add'"
<input :class="{ active: title != 'Add' }"
:disabled="title != 'Add'" :allowClear="true"
:class="{active:title != 'Add'}" show-search
v-model="organizationName" style="width: 250px"
placeholder="Please enter Organization Name" :filter-option="filterOption"
type="text" placeholder="Select Country or Region"
style="width: 250px" max-tag-count="responsive"
/> :options="allCountry"
</div> />
<div class="admin_state_item"> </div>
<span>Sub Account Num:</span> </div>
<input <div class="allUserPoeration_btn admin_page">
:disabled="title != 'Add'" <div class="admin_search_item" @click="cancelDsign">Close</div>
:class="{active:title != 'Add'}" <div class="admin_search_item" @click="setOk">OK</div>
v-model="subAccountNum" </div>
placeholder="Please enter Sub Account Num" </a-modal>
type="number" <div class="mark_loading" v-show="loadingShow">
style="width: 250px" <a-spin size="large" />
/> </div>
</div>
</div>
<div class="allUserPoeration_btn admin_page">
<div class="admin_search_item" @click="cancelDsign">
Close
</div>
<div class="admin_search_item" @click="setOk">
OK
</div>
</div>
</a-modal>
<div class="mark_loading" v-show="loadingShow">
<a-spin size="large" />
</div>
</template> </template>
<script> <script>
import { defineComponent, ref, reactive, watch, onMounted, nextTick, toRefs } from "vue"; import { defineComponent, ref, reactive, watch, onMounted, nextTick, toRefs } from 'vue'
import { Https } from "@/tool/https"; import { Https } from '@/tool/https'
import { Modal, message } from "ant-design-vue"; import { Modal, message } from 'ant-design-vue'
import { ExclamationCircleOutlined } from "@ant-design/icons-vue"; import { ExclamationCircleOutlined } from '@ant-design/icons-vue'
import { formatTime } from "@/tool/util"; import { formatTime } from '@/tool/util'
export default defineComponent({ export default defineComponent({
components: { components: {},
}, emits: ['searchHistoryList'],
emits: ['searchHistoryList'], setup(props, { emit }) {
setup(props,{emit}) { let operations = reactive({
let operations = reactive({ operationsModal: false,
operationsModal:false, operationsEdit: false,
operationsEdit:false, loadingShow: false,
loadingShow:false, title: ''
title:'' })
}) let operationsData = reactive({
let operationsData = reactive({ accountId: -1,
accountId:-1, userName: '',
userName:'', userEmail: '',
userEmail:'', validStartTime: '',
validStartTime:'', validEndTime: '',
validEndTime:'', systemUser: '',
systemUser:'', credits: '',
credits:'', country: ''
country:'', })
organizationName:'', let state = ref([
subAccountNum:0, {
}) label: 'visitor',
let state = ref([ value: '0'
{ },
label:'visitor', {
value:'0', label: 'yearly',
}, value: '1'
{ },
label:'yearly', {
value:'1', label: 'monthly',
}, value: '2'
{ },
label:'monthly', {
value:'2', label: 'trial',
}, value: '3'
{ },
label:'trial', {
value:'3', label: 'userInEvent',
}, value: '4'
{ },
label: "userInEvent", {
value: "4", label: 'Edu Admin',
}, value: '7'
{ }
label: "Edu Admin", ])
value: "7", let init = (funStr, data) => {
}, operations.operationsModal = true
]); operations.operationsEdit = true
let init = (funStr,data)=>{ operations.title = funStr
operations.operationsModal = true if (funStr == 'Add') operations.operationsEdit = false
operations.operationsEdit = true if (funStr == 'Edit') {
operations.title = funStr operationsData.organizationName = data.organizationName
if(funStr == 'Add') operations.operationsEdit = false operationsData.subAccountNum = data.subAccountNum ? data.subAccountNum : 0
if(funStr == 'Edit'){ let startTime = data.validStartTime
operationsData.organizationName = data.organizationName ? formatTime(data.validStartTime / 1000, 'YYYY-MM-DDThh:mm:ss')
operationsData.subAccountNum = data.subAccountNum?data.subAccountNum:0 : ''
let startTime = data.validStartTime?formatTime(data.validStartTime / 1000,"YYYY-MM-DDThh:mm:ss"):'' let endTime = data.validEndTime
let endTime = data.validEndTime?formatTime(data.validEndTime / 1000,"YYYY-MM-DDThh:mm:ss"):'' ? formatTime(data.validEndTime / 1000, 'YYYY-MM-DDThh:mm:ss')
operationsData.accountId=data.id : ''
operationsData.userName=data.userName operationsData.accountId = data.id
operationsData.userEmail=data.userEmail operationsData.userName = data.userName
// operationsData.validStartTime='2024-08-05T00:00:06' operationsData.userEmail = data.userEmail
// operationsData.validEndTime='2024-08-05T00:00:06' // operationsData.validStartTime='2024-08-05T00:00:06'
operationsData.validStartTime=startTime // operationsData.validEndTime='2024-08-05T00:00:06'
operationsData.validEndTime=endTime operationsData.validStartTime = startTime
operationsData.systemUser=String(data.systemUser) operationsData.validEndTime = endTime
operationsData.credits=data.credits operationsData.systemUser = String(data.systemUser)
operationsData.country=data.country operationsData.credits = data.credits
// operationsData.accountId = data.accountId operationsData.country = data.country
// operationsData.userName = data.userName // operationsData.accountId = data.accountId
// operationsData.userEmail = data.userEmail // operationsData.userName = data.userName
// operationsData.validStartTime = formatTime(data.validStartTime) // operationsData.userEmail = data.userEmail
// operationsData.validEndTime = formatTime(data.validEndTime) // operationsData.validStartTime = formatTime(data.validStartTime)
} // operationsData.validEndTime = formatTime(data.validEndTime)
}
}
let setTime = time => {
if (time) {
const date = new Date(time)
const timestamp = date.getTime() // 转换为秒数
return timestamp
} else {
return ''
}
}
let setAddData = () => {
return {
country: operationsData.country,
credits: operationsData.credits,
systemUser: operationsData.systemUser,
userEmail: operationsData.userEmail,
userName: operationsData.userName,
validEndTime: setTime(operationsData.validEndTime),
validStartTime: setTime(operationsData.validStartTime),
organizationName: operationsData.organizationName
? operationsData.organizationName
: null,
subAccountNum: operationsData.subAccountNum
}
}
let setEditData = () => {
return {
accountId: operationsData.accountId,
credits: operationsData.credits,
systemUser: operationsData.systemUser,
validEndTime: setTime(operationsData.validEndTime),
userName: operationsData.userName,
userEmail: operationsData.userEmail
}
}
let cancelDsign = () => {
operationsData.accountId = -1
operationsData.userName = ''
operationsData.userEmail = ''
operationsData.validStartTime = ''
operationsData.validEndTime = ''
operationsData.systemUser = ''
operationsData.credits = ''
operationsData.country = ''
operations.operationsModal = false
}
let setOk = () => {
let data
if (operations.title == 'Add') {
data = setAddData()
if (
!data.userName ||
!data.userEmail ||
!data.validStartTime ||
!data.validEndTime ||
!data.systemUser
)
return message.warning('Please check the input box marked with *')
Https.axiosPost(Https.httpUrls.adminAddUser, data).then(rv => {
if (rv) {
cancelDsign()
emit('searchHistoryList')
}
})
} else {
data = setEditData()
if (!data.userName || !data.userEmail || !data.validEndTime || !data.systemUser)
return message.warning('Please check the input box marked with *')
Https.axiosPost(Https.httpUrls.modifyUser, {}, { params: data }).then(rv => {
if (rv) {
cancelDsign()
emit('searchHistoryList')
}
})
}
}
} const allCountry = ref([])
let setTime = (time) =>{ const filterOption = (input, option) => {
if(time){ return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
const date = new Date(time); }
const timestamp = date.getTime(); // 转换为秒数 onMounted(() => {
return timestamp const countryList = sessionStorage.getItem('allCountry')
}else{ if (countryList) {
return '' allCountry.value = JSON.parse(countryList)
} }
})
} return {
let setAddData = ()=>{ ...toRefs(operations),
return { ...toRefs(operationsData),
"country": operationsData.country, state,
"credits": operationsData.credits, cancelDsign,
"systemUser": operationsData.systemUser, init,
"userEmail": operationsData.userEmail, setOk,
"userName": operationsData.userName, allCountry,
"validEndTime": setTime(operationsData.validEndTime), filterOption
"validStartTime": setTime(operationsData.validStartTime), }
"organizationName": operationsData.organizationName?operationsData.organizationName:null, }
"subAccountNum": operationsData.subAccountNum, })
}
}
let setEditData = ()=>{
return {
"accountId": operationsData.accountId,
"credits": operationsData.credits,
"systemUser": operationsData.systemUser,
"validEndTime": setTime(operationsData.validEndTime),
"userName": operationsData.userName,
"userEmail": operationsData.userEmail,
}
}
let cancelDsign = ()=>{
operationsData.accountId=-1
operationsData.userName=''
operationsData.userEmail=''
operationsData.validStartTime=''
operationsData.validEndTime=''
operationsData.systemUser=''
operationsData.credits=''
operationsData.country=''
operations.operationsModal = false
}
let setOk = ()=>{
let data
if(operations.title == 'Add'){
data = setAddData()
if(!data.userName || !data.userEmail || !data.validStartTime || !data.validEndTime || !data.systemUser)return message.warning('Please check the input box marked with *')
Https.axiosPost(Https.httpUrls.adminAddUser, data).then(
(rv) => {
if (rv) {
cancelDsign()
emit('searchHistoryList')
}
}
);
}else{
data = setEditData()
if(!data.userName || !data.userEmail || !data.validEndTime || !data.systemUser)return message.warning('Please check the input box marked with *')
Https.axiosPost(Https.httpUrls.modifyUser,{},{params:data}).then(
(rv) => {
if (rv) {
cancelDsign()
emit('searchHistoryList')
}
}
);
}
}
return {
...toRefs(operations),
...toRefs(operationsData),
state,
cancelDsign,
init,
setOk,
};
},
data() {
return {
};
},
mounted() {},
methods: {
},
});
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
:deep(.allUserPoeration_modal){ :deep(.allUserPoeration_modal) {
.ant-modal-body{ .ant-modal-body {
height: auto; height: auto;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
} }
</style> </style>
<style lang="less" scoped> <style lang="less" scoped>
.allUserPoeration_modal { .allUserPoeration_modal {
.closeIcon { .closeIcon {
z-index: 2; z-index: 2;
}
> .admin_state_item {
> span {
width: 15rem;
} }
> .admin_state_item{ }
> span{ .allUserPoeration_btn {
width: 15rem; display: flex;
} flex-direction: row;
} height: auto;
.allUserPoeration_btn{ justify-content: flex-end;
display: flex; padding: 1rem 0;
flex-direction: row; .admin_search_item {
height: auto; margin-bottom: 0;
justify-content: flex-end; }
padding: 1rem 0; }
.admin_search_item{ .allUserPoeration_center {
margin-bottom: 0; flex: 1;
} overflow-y: auto;
} flex-direction: row;
.allUserPoeration_center{ flex-wrap: wrap;
flex: 1; }
overflow-y: auto;
flex-direction: row;
flex-wrap: wrap;
}
} }
</style> </style>

View File

@@ -48,7 +48,7 @@
</a-select> </a-select>
</a-form-item> </a-form-item>
<a-form-item label="Admin Account"> <a-form-item label="Admin Account">
<a-select <!-- <a-select
v-model:value="searchForm.adminAccId" v-model:value="searchForm.adminAccId"
allow-clear allow-clear
show-search show-search
@@ -56,7 +56,8 @@
placeholder="Select Account" placeholder="Select Account"
style="width: 180px" style="width: 180px"
:options="allUserList" :options="allUserList"
></a-select> ></a-select> -->
<SelectUser v-model="testuser" />
</a-form-item> </a-form-item>
<a-form-item label="Status"> <a-form-item label="Status">
<a-select <a-select
@@ -68,6 +69,18 @@
:options="statusOption" :options="statusOption"
/> />
</a-form-item> </a-form-item>
<a-form-item label="Country or Region">
<a-select
v-model:value="searchForm.country"
:allowClear="true"
show-search
style="width: 250px"
:filter-option="filterOption"
placeholder="Select Item..."
max-tag-count="responsive"
:options="countryList"
/>
</a-form-item>
<a-form-item> <a-form-item>
<a-space> <a-space>
<a-button type="primary" @click="handleSearch">Search</a-button> <a-button type="primary" @click="handleSearch">Search</a-button>
@@ -279,7 +292,7 @@
</div> </div>
<div class="admin_state_item"> <div class="admin_state_item">
<span> <span>
Account Num: Sub-Account Num:
<span>*</span> <span>*</span>
</span> </span>
<a-input-number <a-input-number
@@ -386,6 +399,7 @@ import {
nextTick, nextTick,
useTemplateRef useTemplateRef
} from 'vue' } from 'vue'
import SelectUser from '@/component/common/SelectUser.vue'
import { message } from 'ant-design-vue' import { message } from 'ant-design-vue'
import { Https } from '@/tool/https' import { Https } from '@/tool/https'
import { formatTime } from '@/tool/util' import { formatTime } from '@/tool/util'
@@ -394,6 +408,8 @@ import type { FormInstance, Rule } from 'ant-design-vue/es/form'
import { debounce } from 'lodash-es' import { debounce } from 'lodash-es'
import dayjs, { Dayjs } from 'dayjs' import dayjs, { Dayjs } from 'dayjs'
const testuser = ref('')
type PlanStatus = 'PENDING' | 'ACTIVE' | 'EXPIRED' type PlanStatus = 'PENDING' | 'ACTIVE' | 'EXPIRED'
interface SubscriptionPlan { interface SubscriptionPlan {
id: number id: number
@@ -413,6 +429,8 @@ const disabledDate = (current: Dayjs) => {
return current && current < dayjs().subtract(1, 'days').endOf('day') return current && current < dayjs().subtract(1, 'days').endOf('day')
} }
const countryList = ref([])
const searchForm = reactive({ const searchForm = reactive({
name: '', name: '',
startTime: '', startTime: '',
@@ -498,17 +516,19 @@ const columns = [
}, },
{ {
title: 'Admin Account', title: 'Admin Account',
dataIndex: 'adminAccId', dataIndex: 'adminAccEmail',
key: 'adminAccId', key: 'adminAccEmail',
align: 'center', align: 'center',
width: 180 width: 180,
ellipsis: true
}, },
{ {
title: 'Account Num', title: 'Sub-Account Num',
dataIndex: 'accountNum', dataIndex: 'accountNum',
key: 'accountNum', key: 'accountNum',
align: 'center', align: 'center',
width: 120 width: 120,
ellipsis: true
}, },
{ {
title: 'Start Time', title: 'Start Time',
@@ -558,6 +578,8 @@ onMounted(async () => {
await handleSearch() await handleSearch()
calculateTableHeight() calculateTableHeight()
window.addEventListener('resize', handleResize) window.addEventListener('resize', handleResize)
const list = sessionStorage.getItem('allCountry')
countryList.value = list ? JSON.parse(list) : []
}) })
onBeforeUnmount(() => { onBeforeUnmount(() => {
@@ -949,9 +971,15 @@ const filterOption = (input: string, option: any) => {
} }
.subscriptionPlan_modal { .subscriptionPlan_modal {
> .admin_state_item { .form_content{
width: 100%;
display: flex;
flex-wrap: wrap;
row-gap: 2rem;
}
.admin_state_item {
> span { > span {
width: 15rem; width: 17rem !important;
} }
} }
.modal_title_text { .modal_title_text {

View File

@@ -0,0 +1,135 @@
<template>
<a-select
v-model:value="value"
:allowClear="true"
show-search
style="width: 250px"
:filter-option="false"
placeholder="Select Item..."
max-tag-count="responsive"
:options="options"
:loading="fetching"
@popupScroll="handleScrollUserList"
@search="onSearch"
@focus="handleFocus"
@change="onChange"
></a-select>
</template>
<script setup lang="ts">
import { computed, ref, reactive } from 'vue'
import { debounce } from 'lodash-es'
type OptionItem = { [k: string]: any }
const props = defineProps<{
modelValue?: any
}>()
const emit = defineEmits(['update:modelValue', 'change', 'search'])
const pager = reactive<{ page: number; size: number; total: number | null }>({
page: 1,
size: 20,
total: null
})
const fetching = ref(false)
const keyword = ref('')
const internalList = ref<OptionItem[]>([])
// page size is stored in pager.size
const value = computed({
get: () => props.modelValue,
set: v => emit('update:modelValue', v)
})
const getLabel = (it: OptionItem) => {
return String(it['label'] ?? '')
}
const getValue = (it: OptionItem, idx: number) => {
return it['value'] ?? String(idx)
}
const options = computed(() => {
return internalList.value.map((it, idx) => ({
label: getLabel(it),
value: getValue(it, idx),
raw: it
}))
})
const defaultFetch = async ({
page: p,
pageSize: ps,
keyword: kw
}: {
page: number
pageSize: number
keyword: string
}) => {
const raw = sessionStorage.getItem('allCountry') || '[]'
let list: OptionItem[] = []
try {
list = JSON.parse(raw)
if (!Array.isArray(list)) list = []
} catch (e) {
list = []
}
// Return the raw list from sessionStorage exactly as-is (no slicing/filtering/delay)
return { data: list, total: list.length }
}
const doFetch = async (reset = false) => {
if (reset) pager.page = 1
if (pager.total !== null && (pager.page - 1) * pager.size >= (pager.total ?? 0)) return
fetching.value = true
try {
const res = await defaultFetch({
page: pager.page,
pageSize: pager.size,
keyword: keyword.value
})
const data = res?.data ?? []
pager.total = res?.total ?? null
if (pager.page === 1) internalList.value = data
else internalList.value = internalList.value.concat(data)
pager.page += 1
} finally {
fetching.value = false
}
}
const debouncedSearch = debounce((val: string) => {
keyword.value = val
emit('search', val)
doFetch(true)
}, 300)
const onSearch = (val: string) => {
debouncedSearch(val)
}
const handleScrollUserList = (e: Event) => {
const target = e?.target as HTMLElement | null
if (!target) return
const nearBottom = target.scrollTop + target.clientHeight >= target.scrollHeight - 40
if (nearBottom && !fetching.value) {
doFetch(false)
}
}
const handleFocus = () => {
// When focused, load first page (or reload with current keyword)
doFetch(true)
}
const onChange = (val: any) => {
emit('change', val)
console.log('change---------', val)
}
</script>
<style lang="less" scoped></style>

View File

@@ -32,14 +32,14 @@
<div class="info" :class="{ academic: item.type == 'academic' }"> <div class="info" :class="{ academic: item.type == 'academic' }">
{{ item?.info }} {{ item?.info }}
</div> </div>
<div class="price " v-if="item.type != 'academic'"> <div class="price" v-if="item.type != 'academic'">
<div>{{ item?.price }}</div> <div>{{ item?.price }}</div>
<span <span
:class="[ :class="[
{ yearl: monthlyOrYearly == 'yearl' }, { yearl: monthlyOrYearly == 'yearl' },
{ personal: item.type === 'personal' } { personal: item.type === 'personal' }
]" ]"
style="white-space: nowrap;" style="white-space: nowrap"
> >
{{ item?.detail }} {{ item?.detail }}
</span> </span>
@@ -111,7 +111,7 @@ export default defineComponent({
type: 'personal', type: 'personal',
info: '您的AI时尚设计助手', info: '您的AI时尚设计助手',
price: 'HK$0', price: 'HK$0',
detail: '自注册之日起 5 天内 · 50 个积分', detail: '自注册之日起 7 天内 · 50 个积分',
highlight: '', highlight: '',
discounts: '9折优惠', discounts: '9折优惠',
detailList: [ detailList: [
@@ -190,7 +190,7 @@ export default defineComponent({
type: 'personal', type: 'personal',
info: '您的AI时尚设计助手', info: '您的AI时尚设计助手',
price: 'HK$0', price: 'HK$0',
detail: '自注册之日起 5 天内 · 50 个积分', detail: '自注册之日起 7 天内 · 50 个积分',
highlight: '', highlight: '',
discounts: '9折优惠', discounts: '9折优惠',
detailList: [ detailList: [
@@ -255,7 +255,7 @@ export default defineComponent({
type: 'personal', type: 'personal',
info: 'Your AI Fashion Design Assistant', info: 'Your AI Fashion Design Assistant',
price: 'HK$0', price: 'HK$0',
detail: '5 days from sign-up · 50 credits', detail: '7 days from sign-up · 50 credits',
highlight: '', highlight: '',
discounts: '10% off', discounts: '10% off',
detailList: [ detailList: [
@@ -334,7 +334,7 @@ export default defineComponent({
type: 'personal', type: 'personal',
info: 'Your AI Fashion Design Assistant', info: 'Your AI Fashion Design Assistant',
price: 'HK$0', price: 'HK$0',
detail: '5 days from sign-up · 50 credits', detail: '7 days from sign-up · 50 credits',
highlight: '', highlight: '',
discounts: '10% off', discounts: '10% off',
detailList: [ detailList: [
@@ -541,6 +541,7 @@ export default defineComponent({
position: relative; position: relative;
--selectPadding: 0.58rem; --selectPadding: 0.58rem;
padding: var(--selectPadding); padding: var(--selectPadding);
transform: scale(1.05);
@media (max-width: 767px) { @media (max-width: 767px) {
--selectPadding: 0.36rem; --selectPadding: 0.36rem;
border-radius: 0.58rem; border-radius: 0.58rem;
@@ -551,7 +552,7 @@ export default defineComponent({
left: var(--selectPadding); left: var(--selectPadding);
} }
> .leftText { > .leftText {
color: #000; color: #fff;
} }
} }
&.right { &.right {
@@ -559,11 +560,12 @@ export default defineComponent({
left: calc(50% + var(--selectPadding)); left: calc(50% + var(--selectPadding));
} }
> .rightText { > .rightText {
color: #000; color: #fff;
} }
} }
> .bg { > .bg {
border: 0.7px solid #e7ebff; border: 0.7px solid #e7ebff;
border-radius: 0.5rem;
box-shadow: 0px 4.35px 26.08px 0px #b5c2fb1a; box-shadow: 0px 4.35px 26.08px 0px #b5c2fb1a;
background: #ffffff; background: #ffffff;
width: calc(50% - var(--selectPadding) * 2); width: calc(50% - var(--selectPadding) * 2);
@@ -571,6 +573,12 @@ export default defineComponent({
position: absolute; position: absolute;
transition: all 0.3s; transition: all 0.3s;
} }
&.left,
&.right {
.bg {
background-color: #000;
}
}
> .leftText, > .leftText,
> .rightText { > .rightText {
cursor: pointer; cursor: pointer;
@@ -634,7 +642,7 @@ export default defineComponent({
border-radius: 1.3rem; border-radius: 1.3rem;
margin: 0; margin: 0;
margin-bottom: 2.8rem; margin-bottom: 2.8rem;
padding: 2rem; padding: 2rem;
padding-bottom: 1.3rem; padding-bottom: 1.3rem;
} }
.product_signUp_box { .product_signUp_box {
@@ -727,7 +735,7 @@ export default defineComponent({
} }
@media (max-width: 767px) { @media (max-width: 767px) {
font-size: 1.2rem; font-size: 1.2rem;
margin-top: 1rem; margin-top: 1rem;
// margin-left: 0.7rem; // margin-left: 0.7rem;
// margin-bottom: 1rem; // margin-bottom: 1rem;
} }
@@ -759,9 +767,9 @@ export default defineComponent({
border-top-right-radius: 1.1rem; border-top-right-radius: 1.1rem;
border-bottom-left-radius: 0.4rem; border-bottom-left-radius: 0.4rem;
font-size: 1rem; font-size: 1rem;
line-height: 2.5rem; line-height: 2.5rem;
font-weight: 500; font-weight: 500;
width: 9rem; width: 9rem;
} }
} }
.product_detail { .product_detail {
@@ -869,7 +877,7 @@ export default defineComponent({
padding-top: 2rem; padding-top: 2rem;
justify-content: flex-end; justify-content: flex-end;
margin-bottom: 0; margin-bottom: 0;
&.chinese{ &.chinese {
justify-content: space-evenly; justify-content: space-evenly;
} }
li { li {

View File

@@ -1593,7 +1593,8 @@ export default {
InputPlanName: '请输入计划名称', InputPlanName: '请输入计划名称',
Cancel: '取消', Cancel: '取消',
SelectPlan: '选择计划', SelectPlan: '选择计划',
AllPlan: '全部' AllPlan: '全部',
PlanStart:'订阅计划生效时间:'
}, },
Login: { Login: {
Login: '登录', Login: '登录',

View File

@@ -1192,9 +1192,10 @@ export default {
createGroup: 'Create Group', createGroup: 'Create Group',
slutionGroup: 'Slution Group', slutionGroup: 'Slution Group',
deleteLayer: 'Delete Layer', deleteLayer: 'Delete Layer',
cannotDeleteOnlyLayer: 'Cannot delete the last layer. At least one layer must remain.', cannotDeleteOnlyLayer:
'Cannot delete the last layer. At least one layer must remain.',
fixedLayerCannotDelete: 'Fixed layer cannot be deleted', fixedLayerCannotDelete: 'Fixed layer cannot be deleted',
backLayerCannotDelete: 'Background layer cannot be deleted', backLayerCannotDelete: 'Background layer cannot be deleted',
clearSelection: 'Clear Selection', clearSelection: 'Clear Selection',
AddPinnedLayer: 'Add a pinned layer', AddPinnedLayer: 'Add a pinned layer',
selectedLayers: 'The number of selected layers:', selectedLayers: 'The number of selected layers:',
@@ -1216,7 +1217,7 @@ export default {
color: 'Color', color: 'Color',
Print: 'Print', Print: 'Print',
Elements: 'Elements', Elements: 'Elements',
PrintAndElementsGroup: 'Print and Elements Group', PrintAndElementsGroup: 'Print and Elements Group',
KeyboardShortcutsOperationGuide: 'Keyboard shortcuts & Operation guide', KeyboardShortcutsOperationGuide: 'Keyboard shortcuts & Operation guide',
other: 'Other', other: 'Other',
touchDevice: 'Touch Device', touchDevice: 'Touch Device',
@@ -1335,11 +1336,11 @@ export default {
flipVertical: 'Vertical Flip', flipVertical: 'Vertical Flip',
cropAndAdd: 'Crop and Add', cropAndAdd: 'Crop and Add',
cropImage: 'Crop Image', cropImage: 'Crop Image',
noRepeat: 'no-repeat', noRepeat: 'no-repeat',
repeat: 'repeat', repeat: 'repeat',
repeatX: 'repeat-x', repeatX: 'repeat-x',
repeatY: 'repeat-y', repeatY: 'repeat-y',
repeatSetting: 'Repeat Setting', repeatSetting: 'Repeat Setting',
angle: 'Angle', angle: 'Angle',
scale: 'Scale', scale: 'Scale',
offset: 'Offset', offset: 'Offset',
@@ -1506,41 +1507,47 @@ export default {
DeleteTexture: 'Delete Texture', DeleteTexture: 'Delete Texture',
TextureSettings: 'Texture Settings', TextureSettings: 'Texture Settings',
TextureSelector: 'Texture Selector', TextureSelector: 'Texture Selector',
// 混合模式 // 混合模式
CompositeNormal: 'Normal', CompositeNormal: 'Normal',
CompositeNormalTip: 'Normal: Default, new graphics cover original content', CompositeNormalTip: 'Normal: Default, new graphics cover original content',
CompositeDarken: 'Darken', CompositeDarken: 'Darken',
CompositeDarkenTip: 'Darken: Take the darkest color', CompositeDarkenTip: 'Darken: Take the darkest color',
CompositeMultiply: 'Multiply', CompositeMultiply: 'Multiply',
CompositeMultiplyTip: 'Multiply: Darken the image', CompositeMultiplyTip: 'Multiply: Darken the image',
CompositeColorBurn: 'Color Burn', CompositeColorBurn: 'Color Burn',
CompositeColorBurnTip: 'Color Burn: Increase contrast and darken the bottom color', CompositeColorBurnTip: 'Color Burn: Increase contrast and darken the bottom color',
CompositeLighten: 'Lighten', CompositeLighten: 'Lighten',
CompositeLightenTip: 'Lighten: Take the brightest color', CompositeLightenTip: 'Lighten: Take the brightest color',
CompositeScreen: 'Screen', CompositeScreen: 'Screen',
CompositeScreenTip: 'Screen: Lighten the image', CompositeScreenTip: 'Screen: Lighten the image',
CompositeColorDodge: 'Color Dodge', CompositeColorDodge: 'Color Dodge',
CompositeColorDodgeTip: 'Color Dodge: Reduce contrast and lighten the bottom color', CompositeColorDodgeTip: 'Color Dodge: Reduce contrast and lighten the bottom color',
CompositeLighter: 'Color Dodge (Add)', CompositeLighter: 'Color Dodge (Add)',
CompositeLighterTip: 'Color Dodge (Add): Add the brightness of the overlapping parts', CompositeLighterTip: 'Color Dodge (Add): Add the brightness of the overlapping parts',
CompositeOverlay: 'Overlay', CompositeOverlay: 'Overlay',
CompositeOverlayTip: 'Overlay: Highlight effect', CompositeOverlayTip: 'Overlay: Highlight effect',
CompositeSoftLight: 'Soft Light', CompositeSoftLight: 'Soft Light',
CompositeSoftLightTip: 'Soft Light: Blend effect', CompositeSoftLightTip: 'Soft Light: Blend effect',
CompositeHardLight: 'Hard Light', CompositeHardLight: 'Hard Light',
CompositeHardLightTip: 'Hard Light: Highlight effect', CompositeHardLightTip: 'Hard Light: Highlight effect',
CompositeDifference: 'Difference', CompositeDifference: 'Difference',
CompositeDifferenceTip: 'Difference: Take the color difference between the two images', CompositeDifferenceTip:
CompositeExclusion: 'Exclusion', 'Difference: Take the color difference between the two images',
CompositeExclusionTip: 'Exclusion: Take the absolute value of the color difference between the two images', CompositeExclusion: 'Exclusion',
CompositeHue: 'Hue', CompositeExclusionTip:
CompositeHueTip: 'Hue: Preserve the original image color and change the hue of the new image', 'Exclusion: Take the absolute value of the color difference between the two images',
CompositeSaturation: 'Saturation', CompositeHue: 'Hue',
CompositeSaturationTip: 'Saturation: Preserve the original image hue and change the saturation of the new image', CompositeHueTip:
CompositeColor: 'Color', 'Hue: Preserve the original image color and change the hue of the new image',
CompositeColorTip: 'Color: Preserve the original image saturation and change the color of the new image', CompositeSaturation: 'Saturation',
CompositeLuminosity: 'Luminosity', CompositeSaturationTip:
CompositeLuminosityTip: 'Luminosity: Preserve the original image color and change the luminosity of the new image', 'Saturation: Preserve the original image hue and change the saturation of the new image',
CompositeColor: 'Color',
CompositeColorTip:
'Color: Preserve the original image saturation and change the color of the new image',
CompositeLuminosity: 'Luminosity',
CompositeLuminosityTip:
'Luminosity: Preserve the original image color and change the luminosity of the new image'
}, },
speedList: { speedList: {
High: 'High', High: 'High',
@@ -1624,7 +1631,7 @@ export default {
ChatRobot: 'ChatRobot', ChatRobot: 'ChatRobot',
Yes: 'Yes', Yes: 'Yes',
No: 'No', No: 'No',
SubscribePlan:'Subscribe Plan', SubscribePlan: 'Subscribe Plan',
SwitchPlanSuccess: 'Switch subscription plan successfully', SwitchPlanSuccess: 'Switch subscription plan successfully',
SwitchPlanFailed: 'Failed to switch subscription plan', SwitchPlanFailed: 'Failed to switch subscription plan',
NoPlanSelected: 'Please select a subscription plan first', NoPlanSelected: 'Please select a subscription plan first',
@@ -1637,7 +1644,8 @@ export default {
InputPlanName: 'Please enter plan name', InputPlanName: 'Please enter plan name',
Cancel: 'Cancel', Cancel: 'Cancel',
SelectPlan: 'Select Plan', SelectPlan: 'Select Plan',
AllPlan:'All' AllPlan: 'All',
PlanStart:'This plan will be actived from',
}, },
Login: { Login: {
Login: 'Login', Login: 'Login',
@@ -1656,7 +1664,7 @@ export default {
AgreePolicies: 'Please agree to all terms, privacy policy, and fees.', AgreePolicies: 'Please agree to all terms, privacy policy, and fees.',
PasswordConditions: 'You must satisfy ALL password conditions to register.', PasswordConditions: 'You must satisfy ALL password conditions to register.',
LoginWithGoogle: 'Sign in with Google', LoginWithGoogle: 'Sign in with Google',
LoginWithWechat: 'Sign in with Wechat', LoginWithWechat: 'Sign in with Wechat'
}, },
LoginPersonal: { LoginPersonal: {
Email: 'Email', Email: 'Email',

View File

@@ -1,189 +1,205 @@
const all = (t)=>{ const all = (t)=>{
return[{ return [
name:'All User', {
route:'/administrator/allUser', name: 'All User',
icon:'yonghu', route: '/administrator/allUser',
expandIcon:'icon-xiala', icon: 'yonghu',
key:'sub1', expandIcon: 'icon-xiala',
isShow:true, key: 'sub1',
// children: [ isShow: true
// { // children: [
// name:'User Management', // {
// route:'/home/excil1', // name:'User Management',
// icon:'', // route:'/home/excil1',
// key:'/home/excil22', // icon:'',
// isShow:true, // key:'/home/excil22',
// }, // isShow:true,
// { // },
// code:'ROLE_MANAGER', // {
// name:'Access Permission', // code:'ROLE_MANAGER',
// route:'/home/excil2', // name:'Access Permission',
// icon:'', // route:'/home/excil2',
// key:'/home/excil33', // icon:'',
// isShow:true, // key:'/home/excil33',
// }, // isShow:true,
// ], // },
},{ // ],
name:'Design Frequency', },
route:'/administrator/testClickData', {
icon:'shenpi', name: 'Design Frequency',
expandIcon:'icon-xiala', route: '/administrator/testClickData',
key:'sub2', icon: 'shenpi',
isShow:true, expandIcon: 'icon-xiala',
},{ key: 'sub2',
name:'Trial User', isShow: true
icon:'usetime', },
expandIcon:'icon-xiala', {
key:'sub3', name: 'Trial User',
isShow:true, icon: 'usetime',
children:[ expandIcon: 'icon-xiala',
{ key: 'sub3',
name:'All Trial User', isShow: true,
route:'/administrator/trialAllUser', children: [
icon:'usetime', {
key:'sub3-1', name: 'All Trial User',
isShow:true, route: '/administrator/trialAllUser',
},{ icon: 'usetime',
name:'Trial User Approval', key: 'sub3-1',
route:'/administrator/trialApproval', isShow: true
icon:'usetime', },
key:'sub3-2', {
isShow:true, name: 'Trial User Approval',
},{ route: '/administrator/trialApproval',
name:'Trial User CHART', icon: 'usetime',
route:'/administrator/trialUserCountry', key: 'sub3-2',
icon:'', isShow: true
key:'sub3-3', },
isShow:true, {
},{ name: 'Trial User CHART',
name:'Conversion Rate', route: '/administrator/trialUserCountry',
route:'/administrator/trialUserConversionRateChart', icon: '',
icon:'', key: 'sub3-3',
key:'sub3-4', isShow: true
isShow:true, },
}, {
] name: 'Conversion Rate',
},{ route: '/administrator/trialUserConversionRateChart',
name:'Function Use CHART', icon: '',
route:'/administrator/recentActiveChart', key: 'sub3-4',
icon:'usetime', isShow: true
key:'sub4', }
isShow:true, ]
},{ },
name:'Active User', {
icon:'usetime', name: 'Function Use CHART',
route:'/administrator/recentActiveUser', route: '/administrator/recentActiveChart',
key:'sub5', icon: 'usetime',
isShow:true, key: 'sub4',
},{ isShow: true
name:'New User', },
icon:'usetime', {
expandIcon:'icon-xiala', name: 'Active User',
key:'sub6', icon: 'usetime',
isShow:true, route: '/administrator/recentActiveUser',
children:[ key: 'sub5',
{ isShow: true
name:'New User List', },
route:'/administrator/recentNewUser', {
icon:'', name: 'New User',
key:'sub6-1', icon: 'usetime',
isShow:true, expandIcon: 'icon-xiala',
},{ key: 'sub6',
name:'New User CHART', isShow: true,
route:'/administrator/recentNewUserChart', children: [
icon:'', {
key:'sub6-2', name: 'New User List',
isShow:true, route: '/administrator/recentNewUser',
}, icon: '',
] key: 'sub6-1',
},{ isShow: true
name:'Events', },
icon:'usetime', {
key:'sub9', name: 'New User CHART',
expandIcon:'icon-xiala', route: '/administrator/recentNewUserChart',
isShow:true, icon: '',
children: [ key: 'sub6-2',
{ isShow: true
name:'Questionnaire Survey', }
route:'/administrator/questionnaire', ]
icon:'', },
key:'sub9-1', {
isShow:true, name: 'Events',
}, icon: 'usetime',
// { key: 'sub9',
// code:'ROLE_MANAGER', expandIcon: 'icon-xiala',
// name:'Access Permission', isShow: true,
// route:'/home/excil2', children: [
// icon:'', {
// key:'/home/excil33', name: 'Questionnaire Survey',
// isShow:true, route: '/administrator/questionnaire',
// }, icon: '',
], key: 'sub9-1',
},{ isShow: true
name:'Affiliate', }
icon:'usetime', // {
expandIcon:'icon-xiala', // code:'ROLE_MANAGER',
key:'sub10', // name:'Access Permission',
isShow:true, // route:'/home/excil2',
children: [ // icon:'',
{ // key:'/home/excil33',
name:'Approval Affiliate', // isShow:true,
route:'/administrator/affiliateAudit', // },
icon:'', ]
key:'sub10-1', },
isShow:true, {
}, name: 'Affiliate',
{ icon: 'usetime',
name:'Affiliate Referral', expandIcon: 'icon-xiala',
route:'/administrator/affiliateReferral', key: 'sub10',
icon:'', isShow: true,
key:'sub10-2', children: [
isShow:true, {
}, name: 'Approval Affiliate',
], route: '/administrator/affiliateAudit',
},{ icon: '',
name:'Transaction', key: 'sub10-1',
icon:'usetime', isShow: true
expandIcon:'icon-xiala', },
key:'sub11', {
isShow:true, name: 'Affiliate Referral',
children: [ route: '/administrator/affiliateReferral',
{ icon: '',
name:'Transaction Record', key: 'sub10-2',
route:'/administrator/TransactionTable', isShow: true
icon:'', }
key:'sub11-1', ]
isShow:true, },
}, {
// { name: 'Transaction',
// code:'ROLE_MANAGER', icon: 'usetime',
// name:'Access Permission', expandIcon: 'icon-xiala',
// route:'/home/excil2', key: 'sub11',
// icon:'', isShow: true,
// key:'/home/excil33', children: [
// isShow:true, {
// }, name: 'Transaction Record',
], route: '/administrator/TransactionTable',
},{ icon: '',
name:'Promotion Code', key: 'sub11-1',
icon:'usetime', isShow: true
route:'/administrator/coupons', }
key:'sub12', // {
isShow:true, // code:'ROLE_MANAGER',
},{ // name:'Access Permission',
// route:'/home/excil2',
name:'Organization', // icon:'',
icon:'usetime', // key:'/home/excil33',
route:'/administrator/organization', // isShow:true,
key:'sub13', // },
isShow:true, ]
},{ },
name:'Subscription Plan', {
icon:'usetime', name: 'Promotion Code',
route:'/administrator/subscriptionPlan', icon: 'usetime',
key:'sub14', route: '/administrator/coupons',
isShow:true, key: 'sub12',
}] isShow: true
},
{
name: 'Organization',
icon: 'usetime',
route: '/administrator/organization',
key: 'sub13',
isShow: true
},
{
name: 'Organization Plan',
icon: 'usetime',
route: '/administrator/subscriptionPlan',
key: 'sub14',
isShow: true
}
]
} }
const schoolOrEnterprise = (t) =>{ const schoolOrEnterprise = (t) =>{
return[ return[