2 Commits

Author SHA1 Message Date
6cace08a51 style: 去除底边距 2026-04-28 17:11:19 +08:00
6207095221 feat: 管理员页面 2026-04-28 17:11:10 +08:00
2 changed files with 1995 additions and 1536 deletions

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="admin_page"> <div class="admin_page">
<div class="admin_table_search" :style="{height:isAwayOrUnfold?'7rem':''}"> <div class="admin_table_search" :style="{ height: isAwayOrUnfold ? '7rem' : '' }">
<div class="admin_state"> <div class="admin_state">
<div class="admin_state_item"> <div class="admin_state_item">
<span>Create Time:</span> <span>Create Time:</span>
@@ -8,16 +8,11 @@
style="width: 250px" style="width: 250px"
class="range_picker" class="range_picker"
v-model:value="rangePickerValue" v-model:value="rangePickerValue"
:placeholder="[ :placeholder="[$t('HistoryPage.StartDate'), $t('HistoryPage.EndDate')]"
$t('HistoryPage.StartDate'),
$t('HistoryPage.EndDate'),
]"
valueFormat="YYYY-MM-DD" valueFormat="YYYY-MM-DD"
> >
<template #suffixIcon> <template #suffixIcon>
<span <span class="icon iconfont range_picker_icon icon-rili"></span>
class="icon iconfont range_picker_icon icon-rili"
></span>
</template> </template>
</a-range-picker> </a-range-picker>
</div> </div>
@@ -63,38 +58,50 @@
show-search show-search
></a-select> ></a-select>
</div> </div>
<div class="admin_state_item">
<span>Orgnization:</span>
<a-select
v-model:value="organizationId"
placeholder="Select the organization"
allow-clear
style="width: 250px"
@popupScroll="handleOrganizationScroll"
>
<a-select-option
v-for="item in organizationOptions"
:key="item.id"
:value="item.id"
>
{{ item.name }}
</a-select-option>
</a-select>
</div>
</div> </div>
<div class="admin_search"> <div class="admin_search">
<div class="admin_search_item" @click="searchHistoryList" :style="{height:isAwayOrUnfold?'4rem':''}"> <div
class="admin_search_item"
@click="searchHistoryList"
:style="{ height: isAwayOrUnfold ? '4rem' : '' }"
>
Search Search
</div> </div>
<div class="admin_search_item" @click="addhHistoryList"> <div class="admin_search_item" @click="addhHistoryList">Add</div>
Add
</div>
</div> </div>
<div class="admin_state_list"> <div class="admin_state_list">
<div <div class="admin_state_list_item" @click="lastGeTrialList('year')">
class="admin_state_list_item"
@click="lastGeTrialList('year')"
>
Nearly a year Nearly a year
</div> </div>
<div <div class="admin_state_list_item" @click="lastGeTrialList('month')">
class="admin_state_list_item"
@click="lastGeTrialList('month')"
>
Last month Last month
</div> </div>
<div <div class="admin_state_list_item" @click="lastGeTrialList('week')">Last week</div>
class="admin_state_list_item"
@click="lastGeTrialList('week')"
>
Last week
</div> </div>
</div> </div>
</div> <div class="awayOrUnfold" :class="{ active: isAwayOrUnfold }">
<div class="awayOrUnfold" :class="{active:isAwayOrUnfold}"> <span
<span class="icon iconfont menu_icon icon-xiala" @click="()=>isAwayOrUnfold = !isAwayOrUnfold"></span> class="icon iconfont menu_icon icon-xiala"
@click="() => (isAwayOrUnfold = !isAwayOrUnfold)"
></span>
</div> </div>
<div class="admin_table_content" ref="historyTable"> <div class="admin_table_content" ref="historyTable">
<a-table <a-table
@@ -104,24 +111,19 @@
:data-source="dataList" :data-source="dataList"
:scroll="{ y: historyTableHeight }" :scroll="{ y: historyTableHeight }"
@change="changePage" @change="changePage"
:showSorterTooltip='false' :showSorterTooltip="false"
:pagination="{ :pagination="{
showSizeChanger: true, showSizeChanger: true,
current: currentPage, current: currentPage,
pageSize: pageSize, pageSize: pageSize,
total: total, total: total,
showQuickJumper: true, showQuickJumper: true,
bordered: false, bordered: false
}" }"
> >
<template #bodyCell="{ column, text, record, index }"> <template #bodyCell="{ column, text, record, index }">
<div class="operate_list" v-if="column?.Operations"> <div class="operate_list" v-if="column?.Operations">
<div <div class="operate_item" @click="setAagree(record)">Edit</div>
class="operate_item"
@click="setAagree(record)"
>
Edit
</div>
<!-- <div <!-- <div
class="operate_item" class="operate_item"
@click="deleteGroup(record, index)" @click="deleteGroup(record, index)"
@@ -132,34 +134,29 @@
</template> </template>
</a-table> </a-table>
</div> </div>
<allUserPoerationsVue ref="allUserPoerationsVue" @searchHistoryList="searchHistoryList"></allUserPoerationsVue> <allUserPoerationsVue
ref="allUserPoerationsVue"
@searchHistoryList="searchHistoryList"
/>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { import { defineComponent, ref, createVNode, computed, reactive, toRefs, onMounted } from "vue"
defineComponent, import { formatTime } from "@/tool/util"
ref, import { useStore } from "vuex"
createVNode, import { Https } from "@/tool/https"
computed, import allUserPoerationsVue from "./allUserPoerations.vue"
reactive, import SelectUser from "@/component/common/SelectUser.vue"
toRefs,
onMounted,
} from "vue";
import { formatTime } from "@/tool/util";
import { useStore } from "vuex";
import { Https } from "@/tool/https";
import allUserPoerationsVue from "./allUserPoerations.vue";
import SelectUser from '@/component/common/SelectUser.vue'
export default defineComponent({ export default defineComponent({
components: {allUserPoerationsVue,SelectUser}, components: { allUserPoerationsVue, SelectUser },
setup() { setup() {
const store:any = useStore() const store: any = useStore()
let filter: any = reactive({ let filter: any = reactive({
dataList: [], dataList: [],
tableLoading: false, tableLoading: false,
allCountry:[], allCountry: [],
isAwayOrUnfold:false isAwayOrUnfold: false
}); })
let filterData: any = reactive({ let filterData: any = reactive({
rangePickerValue: [], rangePickerValue: [],
currentPage: 1, currentPage: 1,
@@ -172,40 +169,41 @@ export default defineComponent({
occupation: "", occupation: "",
systemUser: "", systemUser: "",
order: "", //'Ascending 升序 Descending 降序' order: "", //'Ascending 升序 Descending 降序'
orderBy:'', orderBy: "",
userName: "", userName: "",
}); organizationId: null
})
let state: any = ref([ let state: any = ref([
{ {
label: "all", label: "all",
value: "", value: ""
}, },
{ {
label:'visitor', label: "visitor",
value:'0', value: "0"
}, },
{ {
label:'yearly', label: "yearly",
value:'1', value: "1"
}, },
{ {
label:'monthly', label: "monthly",
value:'2', value: "2"
}, },
{ {
label:'trial', label: "trial",
value:'3', value: "3"
}, },
{ {
label: "userInEvent", label: "userInEvent",
value: "4", value: "4"
}, },
{ {
label: "Edu Admin", label: "Edu Admin",
value: "7", value: "7"
}, }
]); ])
let renameData: any = ref({}); //修改名字选中的数据 let renameData: any = ref({}) //修改名字选中的数据
const columns: any = computed(() => { const columns: any = computed(() => {
return [ return [
{ {
@@ -213,25 +211,25 @@ export default defineComponent({
align: "center", align: "center",
dataIndex: "id", dataIndex: "id",
key: "id", key: "id",
width:100, width: 100,
fixed: "left", fixed: "left",
sorter: true, sorter: true
}, },
{ {
title: "Email", title: "Email",
align: "center", align: "center",
dataIndex: "userEmail", dataIndex: "userEmail",
key: "userEmail", key: "userEmail",
width:200, width: 200,
ellipsis:true ellipsis: true
}, },
{ {
title: "User Name", title: "User Name",
align: "center", align: "center",
dataIndex: "userName", dataIndex: "userName",
key: "userName", key: "userName",
width:150, width: 150,
ellipsis:true ellipsis: true
// customRender: (record: any) => { // customRender: (record: any) => {
// let time = formatTime( // let time = formatTime(
// record.text / 1000, // record.text / 1000,
@@ -245,77 +243,77 @@ export default defineComponent({
align: "center", align: "center",
dataIndex: "language", dataIndex: "language",
key: "language", key: "language",
width:100, width: 100,
ellipsis:true, ellipsis: true
}, },
{ {
title: "Valid Start Time", title: "Valid Start Time",
align: "center", align: "center",
dataIndex: "validStartTime", dataIndex: "validStartTime",
key: "validstartTime", key: "validstartTime",
width:200, width: 200,
ellipsis:true, ellipsis: true,
customRender: (record: any) => { customRender: (record: any) => {
let time = '' let time = ""
if(record.text){ if (record.text) {
time = formatTime(record.text / 1000, 'YYYY-MM-DD hh:mm:ss') time = formatTime(record.text / 1000, "YYYY-MM-DD hh:mm:ss")
} }
return time return time
}, }
}, },
{ {
title: "Valid End Time", title: "Valid End Time",
align: "center", align: "center",
dataIndex: "validEndTime", dataIndex: "validEndTime",
key: "validendTime", key: "validendTime",
width:200, width: 200,
ellipsis:true, ellipsis: true,
customRender: (record: any) => { customRender: (record: any) => {
let time = '' let time = ""
if(record.text){ if (record.text) {
time = formatTime(record.text / 1000, 'YYYY-MM-DD hh:mm:ss') time = formatTime(record.text / 1000, "YYYY-MM-DD hh:mm:ss")
} }
return time return time
}, }
}, },
{ {
title: "Country or Region", title: "Country or Region",
align: "center", align: "center",
dataIndex: "country", dataIndex: "country",
key: "country", key: "country",
width:200, width: 200
}, },
{ {
title: "Create Date", title: "Create Date",
align: "center", align: "center",
dataIndex: "createDate", dataIndex: "createDate",
key: "createDate", key: "createDate",
width:200, width: 200,
sorter: true, sorter: true
}, },
{ {
title: "Is Beginner", title: "Is Beginner",
align: "center", align: "center",
dataIndex: "isBeginner", dataIndex: "isBeginner",
key: "isBeginner", key: "isBeginner",
width:80, width: 80,
ellipsis:true, ellipsis: true,
customRender: (record: any) => { customRender: (record: any) => {
let str; let str
if (record.value == 1) { if (record.value == 1) {
str = "Yes"; str = "Yes"
} else { } else {
str = "No"; str = "No"
}
return str
} }
return str;
},
}, },
{ {
title: 'Machine Room Ip', title: "Machine Room Ip",
align: "center", align: "center",
dataIndex: "browserIdentifiers", dataIndex: "browserIdentifiers",
key: "browserIdentifiers", key: "browserIdentifiers",
width:200, width: 200
}, },
{ {
title: "Credits", title: "Credits",
@@ -326,11 +324,11 @@ export default defineComponent({
// resizable: true, // resizable: true,
dataIndex: "credits", dataIndex: "credits",
key: "credits", key: "credits",
width:100, width: 100,
sorter: true, sorter: true
}, },
{ {
title: 'User Type', title: "User Type",
align: "center", align: "center",
// width: 150, // width: 150,
// minWidth: 100, // minWidth: 100,
@@ -338,84 +336,84 @@ export default defineComponent({
// resizable: true, // resizable: true,
dataIndex: "systemUser", dataIndex: "systemUser",
key: "systemUser", key: "systemUser",
width:100, width: 100,
customRender: (record: any) => { customRender: (record: any) => {
let str; let str
if (record.value == 0) { if (record.value == 0) {
str = "visitor"; str = "visitor"
} else if (record.value == 1) { } else if (record.value == 1) {
str = "yearly"; str = "yearly"
} else if (record.value == 2) { } else if (record.value == 2) {
str = "monthly"; str = "monthly"
} else if (record.value == 3) { } else if (record.value == 3) {
str = "trial"; str = "trial"
} else if (record.value == 4) { } else if (record.value == 4) {
str = "userInEvent"; str = "userInEvent"
} else if (record.value == 7) { } else if (record.value == 7) {
str = "Edu Admin"; str = "Edu Admin"
}
return str
} }
return str;
},
}, },
{ {
title: "Operations", title: "Operations",
key: "operation", key: "operation",
width:120, width: 120,
align: "center", align: "center",
fixed: "right", fixed: "right",
// slots:{customRender:'action'} // slots:{customRender:'action'}
Operations: true, Operations: true
}, }
]; ]
}); })
//改变页码 //改变页码
let changePage = (e: any, filters:any, sorter:any) => { let changePage = (e: any, filters: any, sorter: any) => {
filterData.currentPage = e.current; filterData.currentPage = e.current
filterData.pageSize = e.pageSize; filterData.pageSize = e.pageSize
if(sorter.order){ if (sorter.order) {
if(sorter.columnKey == 'id'){ if (sorter.columnKey == "id") {
filterData.orderBy = 'id' filterData.orderBy = "id"
}else if(sorter.columnKey == "createDate"){ } else if (sorter.columnKey == "createDate") {
filterData.orderBy = 'time' filterData.orderBy = "time"
}else if(sorter.columnKey == "credits"){ } else if (sorter.columnKey == "credits") {
filterData.orderBy = 'credits' filterData.orderBy = "credits"
} }
} }
if(sorter.order){ if (sorter.order) {
filterData.order = sorter.order == "descend" ? "Descending" : "Ascending"; filterData.order = sorter.order == "descend" ? "Descending" : "Ascending"
}else{ } else {
filterData.order = '' filterData.order = ""
}
gettrialList()
} }
gettrialList();
};
//查询列表 //查询列表
let searchHistoryList = () => { let searchHistoryList = () => {
filterData.currentPage = 1; filterData.currentPage = 1
gettrialList(); gettrialList()
}; }
let clearHistoryList = () => { let clearHistoryList = () => {
filterData.rangePickerValue = [], ;((filterData.rangePickerValue = []),
filterData.currentPage = 1, (filterData.currentPage = 1),
filterData.pageSize = 10, (filterData.pageSize = 10),
filterData.total = 0, (filterData.total = 0),
filterData.country = "", (filterData.country = ""),
filterData.email = "", (filterData.email = ""),
filterData.userType = "", (filterData.userType = ""),
filterData.ids = [], (filterData.ids = []),
filterData.occupation = "", (filterData.occupation = ""),
filterData.order = "", //'Ascending 升序 Descending 降序' (filterData.order = ""), //'Ascending 升序 Descending 降序'
filterData.orderBy = "", //'Ascending 升序 Descending 降序' (filterData.orderBy = ""), //'Ascending 升序 Descending 降序'
filterData.systemUser = "", (filterData.systemUser = ""),
filterData.userName = ""; (filterData.userName = ""))
}; }
let setHistoryListData = () => { let setHistoryListData = () => {
let startDate: any = filterData.rangePickerValue?.[0] let startDate: any = filterData.rangePickerValue?.[0]
? filterData.rangePickerValue[0] + " " + "00:00:00" ? filterData.rangePickerValue[0] + " " + "00:00:00"
: ""; : ""
let endDate: any = filterData.rangePickerValue?.[1] let endDate: any = filterData.rangePickerValue?.[1]
? filterData.rangePickerValue[1] + " " + "23:59:59" ? filterData.rangePickerValue[1] + " " + "23:59:59"
: ""; : ""
let data = { let data = {
endTime: endDate, endTime: endDate,
startTime: startDate, startTime: startDate,
@@ -430,63 +428,118 @@ export default defineComponent({
order: filterData.order, order: filterData.order,
orderBy: filterData.orderBy, orderBy: filterData.orderBy,
userName: filterData.userName, userName: filterData.userName,
}; organizationId: filterData.organizationId
return data; }
}; return data
}
//获取列表 //获取列表
let gettrialList = () => { let gettrialList = () => {
filter.tableLoading = true; filter.tableLoading = true
let data = setHistoryListData(); let data = setHistoryListData()
Https.axiosPost(Https.httpUrls.getUserInfo, data).then( Https.axiosPost(Https.httpUrls.getUserInfo, data).then((rv: any) => {
(rv: any) => {
if (rv) { if (rv) {
// this.dataList = rv // this.dataList = rv
filter.dataList = rv.records; filter.dataList = rv.records
filterData.total = rv.total; filterData.total = rv.total
filter.tableLoading = false; filter.tableLoading = false
// this.workspaceItem.position = this.singleTypeList[0].label // this.workspaceItem.position = this.singleTypeList[0].label
} }
})
} }
);
};
let lastGeTrialList = (str: string) => { let lastGeTrialList = (str: string) => {
clearHistoryList(); clearHistoryList()
let currentDate = new Date(); let currentDate = new Date()
let currentTimestamp = Math.floor(currentDate.getTime() / 1000); let currentTimestamp = Math.floor(currentDate.getTime() / 1000)
// 计算30天前的时间戳 // 计算30天前的时间戳
let thirtyDaysAgoTimestamp; let thirtyDaysAgoTimestamp
if (str == "year") { if (str == "year") {
thirtyDaysAgoTimestamp = currentTimestamp - 360 * 24 * 60 * 60; thirtyDaysAgoTimestamp = currentTimestamp - 360 * 24 * 60 * 60
} else if (str == "month") { } else if (str == "month") {
thirtyDaysAgoTimestamp = currentTimestamp - 30 * 24 * 60 * 60; thirtyDaysAgoTimestamp = currentTimestamp - 30 * 24 * 60 * 60
} else if (str == "week") { } else if (str == "week") {
thirtyDaysAgoTimestamp = currentTimestamp - 7 * 24 * 60 * 60; thirtyDaysAgoTimestamp = currentTimestamp - 7 * 24 * 60 * 60
}
filterData.rangePickerValue[0] = formatTime(thirtyDaysAgoTimestamp, "YYYY-MM-DD")
gettrialList()
} }
filterData.rangePickerValue[0] = formatTime(
thirtyDaysAgoTimestamp,
"YYYY-MM-DD"
);
gettrialList();
};
let filterOption = (input: any, option: any) => { let filterOption = (input: any, option: any) => {
// 使用 option.label 进行搜索 // 使用 option.label 进行搜索
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0; return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
}; }
let addhHistoryList = () => { let addhHistoryList = () => {
allUserPoerationsVue.value.init('Add','') allUserPoerationsVue.value.init("Add", "")
}; }
let allUserPoerationsVue = ref() let allUserPoerationsVue = ref()
let setAagree = (data:any) =>{ let setAagree = (data: any) => {
allUserPoerationsVue.value.init('Edit',data) allUserPoerationsVue.value.init("Edit", data)
} }
const organizationOptions = ref([])
const organizationParams = reactive({
page: 1,
size: 10,
total: 0
})
const organizationLoading = ref(false)
const getOrganizationList = async (isLoadMore = false) => {
console.log("111111")
if (organizationLoading.value) return
if (isLoadMore) {
const loaded = organizationParams.page * organizationParams.size
if (organizationParams.total && loaded >= organizationParams.total) return
organizationParams.page += 1
} else {
organizationParams.page = 1
organizationOptions.value = []
}
organizationLoading.value = true
try {
const { total, ...requestParams } = organizationParams
const rv: any = await Https.axiosPost(
Https.httpUrls.queryOrganization,
requestParams
)
if (rv) {
const newRecords = rv.records || []
// 遍历新数据,如果已存在则覆盖,不存在则追加
newRecords.forEach((newOrg: any) => {
const newOrgId = String(newOrg.id)
const existingIndex = organizationOptions.value.findIndex(
(org: any) => String(org.id) === newOrgId
)
if (existingIndex !== -1) {
// 如果已存在,用新数据覆盖旧项
organizationOptions.value[existingIndex] = newOrg
} else {
// 如果不存在,追加到末尾
organizationOptions.value.push(newOrg)
}
})
organizationParams.total = rv.total || 0
}
} finally {
organizationLoading.value = false
}
}
const handleOrganizationScroll = (e: any) => {
const target = e?.target
if (!target) return
const nearBottom = target.scrollTop + target.clientHeight >= target.scrollHeight - 20
if (nearBottom) {
getOrganizationList(true)
}
}
onMounted(() => { onMounted(() => {
let allCountry: any = sessionStorage.getItem("allCountry"); let allCountry: any = sessionStorage.getItem("allCountry")
if (allCountry) { if (allCountry) {
filter.allCountry = JSON.parse(allCountry); filter.allCountry = JSON.parse(allCountry)
} }
gettrialList(); gettrialList()
}); getOrganizationList()
})
return { return {
...toRefs(filter), ...toRefs(filter),
...toRefs(filterData), ...toRefs(filterData),
@@ -501,29 +554,32 @@ export default defineComponent({
filterOption, filterOption,
allUserPoerationsVue, allUserPoerationsVue,
setAagree, setAagree,
}; handleOrganizationScroll,
getOrganizationList,
organizationOptions,
organizationParams
}
}, },
data() { data() {
return { return {
historyTableHeight: 0, historyTableHeight: 0,
handleResizeColumn: (w: any, col: any) => { handleResizeColumn: (w: any, col: any) => {
col.width = w; col.width = w
}, }
}; }
}, },
mounted() { mounted() {
let historyTable: any = this.$refs.historyTable; let historyTable: any = this.$refs.historyTable
this.historyTableHeight = historyTable.clientHeight - 200; this.historyTableHeight = historyTable.clientHeight - 200
}, },
methods: {}, methods: {}
}); })
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.admin_page .admin_table_search .admin_state { .admin_page .admin_table_search .admin_state {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
} }
.admin_page{ .admin_page {
} }
</style> </style>

File diff suppressed because it is too large Load Diff