TASK
This commit is contained in:
241
src/views/childView/exportExcil.vue
Normal file
241
src/views/childView/exportExcil.vue
Normal file
@@ -0,0 +1,241 @@
|
||||
<template>
|
||||
<div class="export_manage_page list_page">
|
||||
<div class="list_page_content">
|
||||
<div class="list_top_content">
|
||||
<div class="list_top_search_content">
|
||||
<div class="search_content_left">
|
||||
<filterComponent :title="'Role Name or Id'"><a-input v-model:value="name" size="large" placeholder="Please input Role Name or Id" @keydown.enter="searchList()"/></filterComponent>
|
||||
<filterComponent :title="'Period'">
|
||||
<a-select
|
||||
v-model:value="type"
|
||||
size="large"
|
||||
style="width:280px"
|
||||
:options="labelTypeList"
|
||||
allowClear
|
||||
></a-select>
|
||||
</filterComponent>
|
||||
<filterComponent :title="'Export Time'"> <a-range-picker size="large" v-model:value="date" :placeholder="['Start Time', 'End Time']" format="YYYY-MM-DD" valueFormat="YYYY-MM-DD"/></filterComponent>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list_top_button_content">
|
||||
<a-button class="primary_button btn-margin-r-20" type="primary" size="large" @click="searchList()">Seach</a-button>
|
||||
<a-button class="default_button" size="large" @click="resetList()">Reset</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list_table_content">
|
||||
<a-table :columns="columns" :data-source="collectionList" @change="changePage" :loading="tableLoading"
|
||||
:pagination="{
|
||||
showSizeChanger:true,
|
||||
current: currentPage,
|
||||
pageSize:pageSize,
|
||||
total: total,
|
||||
showQuickJumper:true,
|
||||
bordered:false,
|
||||
pageSizeOptions:['10','20','50'],
|
||||
}">
|
||||
<template v-slot:bodyCell="{column,record, index}" >
|
||||
<template v-if="column.dataIndex === 'operation'">
|
||||
<div class="operate_list">
|
||||
<div class="operate_item" @click="setExport(record,index)">Export</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent,ref,reactive,toRefs,UnwrapRef,onMounted,createVNode } from "vue";
|
||||
import filterComponent from '@/component/filterComponent.vue'
|
||||
import { message,Modal } from "ant-design-vue";
|
||||
import { Moment } from 'moment';
|
||||
import { Https } from "@/tool/https";
|
||||
import { WarningOutlined } from '@ant-design/icons-vue';
|
||||
|
||||
export default defineComponent({
|
||||
name:'roleManage',
|
||||
components:{filterComponent},
|
||||
setup(){
|
||||
let filter = reactive({
|
||||
name:'',
|
||||
type:'',
|
||||
date:ref<Moment[]>([])
|
||||
})
|
||||
let tableLoading = ref(false)
|
||||
let columns = reactive([
|
||||
{ title: 'Name', align:'center', ellipsis: true, dataIndex: 'exportName', key: 'exportName', width:250 },
|
||||
{ title: 'Create Time', align:'center', ellipsis: true, dataIndex: 'createTime', key: 'createTime'},
|
||||
{ title: 'Type', align:'center', ellipsis: true, dataIndex: 'span', key: 'span'},
|
||||
{
|
||||
title: 'Operations',
|
||||
key: 'operation',
|
||||
align:'center',
|
||||
fixed: 'right',
|
||||
// width: 250,
|
||||
dataIndex:'operation',
|
||||
|
||||
},
|
||||
])
|
||||
let collectionList = ref([])
|
||||
let labelTypeList:any = ref([
|
||||
{ value:'week',label:'Week'},
|
||||
{ value:'month',label:'Month'},
|
||||
{ value:'year',label:'Year'},
|
||||
])
|
||||
let currentPage = ref(1)
|
||||
let pageSize = ref(10)
|
||||
let total = ref(1)
|
||||
let changePage = (e:any) =>{
|
||||
currentPage.value = e.current
|
||||
pageSize.value = e.pageSize
|
||||
getExportList()
|
||||
}
|
||||
|
||||
let getExportList = () =>{
|
||||
|
||||
let data = {
|
||||
page:currentPage.value,
|
||||
size:pageSize.value,
|
||||
fileName:filter.name,
|
||||
span:filter.type,
|
||||
endTime:filter.date[1]?filter.date[1]:'',
|
||||
startTime:filter.date[0]?filter.date[0]:'',
|
||||
}
|
||||
tableLoading.value = true
|
||||
Https.axiosPost(Https.httpUrls.miTuExportPage, data).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
tableLoading.value = false
|
||||
if(currentPage.value > 1 && rv.content.length == 0){
|
||||
currentPage.value = 1
|
||||
getExportList()
|
||||
}else{
|
||||
collectionList.value = rv.content
|
||||
|
||||
total = rv.total
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
).catch((res:any)=>{
|
||||
tableLoading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
let searchList = () =>{
|
||||
currentPage.value = 1
|
||||
getExportList()
|
||||
}
|
||||
|
||||
let resetList = () =>{
|
||||
currentPage.value = 1
|
||||
filter.name = ''
|
||||
getExportList()
|
||||
}
|
||||
|
||||
let setExport = (data:any,index:any) =>{
|
||||
Https.axiosGet(Https.httpUrls.miTuExportExport+`/${data.id}`,{responseType: 'blob'}).then((rv)=>{
|
||||
let name = rv.name.split('=')[1];
|
||||
let url = window.URL.createObjectURL(new Blob([rv.data], { type: rv.type }));
|
||||
const link = document.createElement('a');
|
||||
link.download = name; //定义表格名称,后缀是文件格式
|
||||
link.style.display = 'none';
|
||||
link.href = url;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
URL.revokeObjectURL(link.href)
|
||||
document.body.removeChild(link);
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
getExportList()
|
||||
})
|
||||
|
||||
|
||||
return {
|
||||
...toRefs(filter),
|
||||
tableLoading,
|
||||
columns,
|
||||
labelTypeList,
|
||||
collectionList,
|
||||
currentPage,
|
||||
pageSize,
|
||||
total,
|
||||
changePage,
|
||||
searchList,
|
||||
resetList,
|
||||
setExport,
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.export_manage_page{
|
||||
padding-left: 28px;
|
||||
|
||||
.export_pic{
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.operate_list{
|
||||
display: flex;
|
||||
// justify-content: space-between;
|
||||
justify-content: center;
|
||||
padding: 0 50px;
|
||||
|
||||
.operate_item{
|
||||
font-size: 14px;
|
||||
font-family: Roboto;
|
||||
font-weight: 400;
|
||||
color: #343579;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form_check_all{
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.permission_table{
|
||||
width: 100%;
|
||||
margin-top: 10px;
|
||||
border-left:1px solid #DFDFDF;
|
||||
border-top:1px solid #DFDFDF;
|
||||
|
||||
td{
|
||||
border-bottom: 1px solid #DFDFDF;
|
||||
border-right: 1px solid #DFDFDF;
|
||||
|
||||
.table_td_block{
|
||||
padding: 16px 0 16px 20px;
|
||||
border-bottom: 1px solid #DFDFDF;
|
||||
|
||||
&:last-child{
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
.table_td_permission{
|
||||
display: flex;
|
||||
min-height: 23px;
|
||||
}
|
||||
}
|
||||
|
||||
.first_td{
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.second_td{
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
533
src/views/childView/exportExcil/userManage.vue
Normal file
533
src/views/childView/exportExcil/userManage.vue
Normal file
@@ -0,0 +1,533 @@
|
||||
<template>
|
||||
<div class="user_manage_page list_page">
|
||||
<div class="list_page_content">
|
||||
<div class="list_top_content">
|
||||
<div class="list_top_search_content">
|
||||
<div class="search_content_left">
|
||||
<filterComponent :title="'User Name'"><a-input v-model:value="userName" size="large" placeholder="Please input User Name" @keydown.enter="searchList()"/></filterComponent>
|
||||
<filterComponent :title="'User Phone'"><a-input v-model:value="userPhone" size="large" placeholder="Please input User Phone" @keydown.enter="searchList()" /></filterComponent>
|
||||
<filterComponent :title="'User Role'">
|
||||
<a-select v-model:value="roleId" size="large" style="width:280px" placeholder="Please select" :options="userRoleList" allowClear></a-select>
|
||||
</filterComponent>
|
||||
<filterComponent :title="'User State'">
|
||||
<a-select v-model:value="state" size="large" style="width:280px" placeholder="Please select" :options="userStateList" allowClear></a-select>
|
||||
</filterComponent>
|
||||
<filterComponent :title="'Add Time'"><a-range-picker v-model:value="addTime" size="large" :placeholder="['Start Time', 'End Time']" format="YYYY-MM-DD" valueFormat="YYYY-MM-DD"/></filterComponent>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list_top_button_content">
|
||||
<a-button class="primary_button btn-margin-r-20" type="primary" size="large" @click="searchList()">Seach</a-button>
|
||||
<a-button class="default_button" size="large" @click="resetList()">Reset</a-button>
|
||||
<a-button class="primary_button btn-margin-t-35" type="primary" size="large" @click="addUser()">+Add User</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list_table_content">
|
||||
<a-table :columns="columns" :data-source="collectionList" @change="changePage" :loading="tableLoading"
|
||||
:pagination="{
|
||||
showSizeChanger:true,
|
||||
current: currentPage,
|
||||
pageSize:pageSize,
|
||||
total: total,
|
||||
showQuickJumper:true,
|
||||
bordered:false,
|
||||
pageSizeOptions:['10','20','50'],
|
||||
}">
|
||||
<template v-slot:bodyCell="{column,record, index}" >
|
||||
<template v-if="column.dataIndex === 'stateName'">
|
||||
<div :class="['state_name_block', record.state == 1 ? 'enable_state' :'disable_state']">
|
||||
<div class="state_round"></div>
|
||||
<div>{{record.stateName}}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'operation'">
|
||||
<div class="operate_list">
|
||||
<div class="operate_item" @click="editUser(record)">Edit</div>
|
||||
<div :class="['operate_item', record.state == 0 ? '' :'operate_disable_state']" @click="enableUser(record,index)">
|
||||
<div v-if="record.state == 0">Enable</div>
|
||||
<div v-else>Disable</div>
|
||||
</div>
|
||||
<div class="operate_item" @click="deleteUser(record,index)">Delete</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a-modal class="edit_modal_component"
|
||||
:destroyOnClose="true"
|
||||
v-model:visible="editUserModal"
|
||||
:footer="null"
|
||||
:title="editUserTitle"
|
||||
width="680px"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
@cancel="closeUser"
|
||||
>
|
||||
<a-form ref="formRef" :model="formState" :rules="rules" :layout="'vertical'" >
|
||||
<a-row :gutter="[16,16]">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="User Name" name="userName">
|
||||
<a-input v-model:value="formState.userName" size="large" placeholder="Please input user name"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="User Account" name="userAccount">
|
||||
<a-input v-model:value="formState.userAccount" size="large" placeholder="Please input user account"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="[16,16]">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="User Code" name="userPassword">
|
||||
<a-input v-model:value="formState.userPassword" size="large" placeholder="Please input user code" type="password"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="User Phone" name="userPhone">
|
||||
<a-input v-model:value="formState.userPhone" size="large" placeholder="Please input user phone"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="[16,16]">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="App User" name="appUser">
|
||||
<a-select v-model:value="formState.appUser" size="large" :options="appUserList" placeholder="Please select"></a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="User Role" name="roleId">
|
||||
<a-select v-model:value="formState.roleId" size="large" :options="userRoleList" placeholder="Please select"></a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="[16,16]">
|
||||
<a-col :span="24">
|
||||
<a-form-item label="Owner Store" name="storeIds">
|
||||
<a-select v-model:value="formState.storeIds" size="large" :options="ownerStoreList" mode="multiple" placeholder="Please select"></a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="[16,16]">
|
||||
<a-col :span="24">
|
||||
<a-form-item label ="Remarks" name="remarks">
|
||||
<a-input v-model:value="formState.remarks" size="large" placeholder="Please input remarks"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
<div class="modal_button_list">
|
||||
<a-button class="default_button btn-margin-r-20" size="large" @click="closeUser">Cancel</a-button>
|
||||
<a-button class="primary_button" type="primary" size="large" @click="confirmSubmit">Submit</a-button>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent,ref,reactive,toRefs,UnwrapRef,onMounted,createVNode } from "vue";
|
||||
import filterComponent from '@/component/filterComponent.vue'
|
||||
import { Moment } from 'moment';
|
||||
import { message,Modal } from "ant-design-vue";
|
||||
import { Https } from "@/tool/https";
|
||||
import { WarningOutlined } from '@ant-design/icons-vue';
|
||||
import { encode, decode } from 'js-base64';
|
||||
import { useRoute } from 'vue-router'
|
||||
import { formatTime, startTime, endTime, exportExcil } from "@/tool/util"
|
||||
export default defineComponent({
|
||||
name:'userManage',
|
||||
components:{filterComponent},
|
||||
setup(){
|
||||
const route = useRoute()
|
||||
let filter:any = reactive({
|
||||
userName:'',
|
||||
userPhone:'',
|
||||
roleId:[],
|
||||
state:[],
|
||||
addTime:ref<Moment[]>([]),
|
||||
})
|
||||
let tableLoading = ref(false)
|
||||
let userRoleList:any = ref([])
|
||||
let userStateList:any = ref([
|
||||
{value:'1',label:'Activated'},
|
||||
{value:'0',label:'Deactivated'},
|
||||
])
|
||||
let appUserList:any = ref([
|
||||
{value:1,label:'Yes'},
|
||||
{value:0,label:'No'},
|
||||
])
|
||||
let ownerStoreList:any = ref([])
|
||||
let columns = reactive([
|
||||
{ title: 'User Name', align:'center', ellipsis: true, dataIndex: 'userName', key: 'userName' },
|
||||
{ title: 'User Account', align:'center', ellipsis: true, dataIndex: 'userAccount', key: 'userAccount'},
|
||||
{ title: 'Add Role', align:'center', ellipsis: true, dataIndex: 'roleName', key: 'roleName' },
|
||||
{ title: 'User Phone', align:'center', ellipsis: true, dataIndex: 'userPhone', key: 'userPhone' },
|
||||
{ title: 'Owned Store', align:'center', ellipsis: true, dataIndex: 'storeName', key: 'storeName',customRender:(record:any)=>{
|
||||
let storeNameNew = record.text.join(',')
|
||||
return storeNameNew
|
||||
}
|
||||
},
|
||||
{ title: 'Add Time', align:'center', ellipsis: true, dataIndex: 'createDate', key: 'createDate' ,customRender:(record:any)=>{
|
||||
let time = formatTime(record.text / 1000, 'YYYY-MM-DD hh:mm:ss')
|
||||
return time
|
||||
},
|
||||
},
|
||||
{ title: 'Activated', align:'center', ellipsis: true, dataIndex: 'appUserName', key: 'appUserName' },
|
||||
{ title: 'User State', align:'center', ellipsis: true, dataIndex: 'stateName', key: 'stateName' },
|
||||
{
|
||||
title: 'Operations',
|
||||
key: 'operation',
|
||||
align:'center',
|
||||
fixed: 'right',
|
||||
width: 150,
|
||||
dataIndex:'operation',
|
||||
|
||||
},
|
||||
])
|
||||
let collectionList:any = ref([])
|
||||
let currentPage = ref(1)
|
||||
let pageSize = ref(10)
|
||||
let total = ref(1)
|
||||
let editUserModal = ref(false)
|
||||
let editUserTitle = ref('Add user')
|
||||
let formRef = ref();
|
||||
let formState:any = ref({
|
||||
id: '',
|
||||
userName: '',
|
||||
userAccount: '',
|
||||
userPassword:'',
|
||||
userPhone:'',
|
||||
appUser:null,
|
||||
roleId:null,
|
||||
storeIds:[],
|
||||
remarks:'',
|
||||
});
|
||||
let rules = {
|
||||
userName: [
|
||||
{ required: true, message: 'Please input user name', trigger: 'blur' },
|
||||
],
|
||||
userAccount: [
|
||||
{ required: true, message: 'Please input user account', trigger: 'blur' },
|
||||
{ min: 6, max: 20, message: 'Length should be 6 to 20', trigger: 'blur' },
|
||||
],
|
||||
userPassword: [
|
||||
{ required: true, message: 'Please input user code', trigger: 'blur' },
|
||||
{ min: 6, max: 20, message: 'Length should be 6 to 20', trigger: 'blur' },
|
||||
],
|
||||
userPhone: [
|
||||
{ required: true, message: 'Please input user phone', trigger: 'blur' },
|
||||
{ pattern: /^\d*$/, message: 'The format of the mobile phone number is incorrect', trigger: 'blur' },
|
||||
],
|
||||
appUser: [
|
||||
{ required: true, message: 'Please select app user', trigger: 'blur' },
|
||||
],
|
||||
userRole: [
|
||||
{ required: true, message: 'Please select user role', trigger: 'blur' },
|
||||
],
|
||||
ownerStore: [
|
||||
{ required: true, message: 'Please select owner store', trigger: 'blur' },
|
||||
],
|
||||
}
|
||||
|
||||
let changePage = (e:any) =>{
|
||||
currentPage.value = e.current
|
||||
pageSize.value = e.pageSize
|
||||
getUserlist()
|
||||
}
|
||||
|
||||
let closeUser = () =>{
|
||||
formState.value = {
|
||||
id: '',
|
||||
userName: '',
|
||||
userAccount: '',
|
||||
userPassword:'',
|
||||
userPhone:'',
|
||||
appUser:null,
|
||||
roleId:null,
|
||||
storeIds:[],
|
||||
remarks:'',
|
||||
}
|
||||
editUserModal.value = false
|
||||
}
|
||||
|
||||
let addUser = () =>{
|
||||
editUserTitle.value = 'Add user'
|
||||
editUserModal.value = true
|
||||
|
||||
// const data = [
|
||||
// [
|
||||
// ['12312312312'],
|
||||
// ['姓名', '年龄', '性别'],
|
||||
// ['张三', 20, '男'],
|
||||
// ['李四', 25, '女']
|
||||
// ],
|
||||
// [
|
||||
// ['城市', '人口'],
|
||||
// ['北京', 21540000],
|
||||
// ['上海', 24240000]
|
||||
// ]
|
||||
// ];
|
||||
// const sheetNames = ['Sheet1', 'Sheet2'];
|
||||
// const fileName = 'output.xlsx';
|
||||
// const configuration = {
|
||||
// width:15,
|
||||
// titleCell:2,
|
||||
// }
|
||||
// exportExcil(data,sheetNames,fileName,configuration)
|
||||
}
|
||||
|
||||
let editUser = (data:any,) =>{
|
||||
editUserModal.value = true
|
||||
editUserTitle.value = 'Eidt user'
|
||||
formState.value = {
|
||||
id: data.id,
|
||||
userName: data.userName,
|
||||
userAccount:data.userAccount,
|
||||
userPassword:data.userPassword ? decode(data.userPassword) : '',
|
||||
userPhone:data.userPhone,
|
||||
appUser:data.appUser,
|
||||
roleId:String(data.roleId),
|
||||
storeIds:data.storeIds,
|
||||
remarks:data.remarks,
|
||||
}
|
||||
}
|
||||
|
||||
let getUserlist = () =>{
|
||||
let data = {
|
||||
userName : filter.userName,
|
||||
userPhone:filter.userPhone,
|
||||
state:filter.state && filter.state.length ? filter.state : '',
|
||||
roleId:filter.roleId && filter.roleId.length ? filter.roleId : '',
|
||||
createDateStart:filter.addTime && filter.addTime.length ? startTime(filter.addTime[0]) :'',
|
||||
createDateEnd:filter.addTime && filter.addTime.length ? endTime(filter.addTime[1]) :'',
|
||||
page:currentPage.value,
|
||||
size:pageSize.value
|
||||
}
|
||||
tableLoading.value = true
|
||||
Https.axiosPost(Https.httpUrls.accountQueryUserPage, data).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
tableLoading.value = false
|
||||
collectionList.value = rv.content
|
||||
total.value = rv.total
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let getRolelist = () =>{
|
||||
Https.axiosPost(Https.httpUrls.roleQueryAll, {}).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
userRoleList.value = rv.map((v:any)=>{
|
||||
let data = {
|
||||
...v,
|
||||
value:v.id,
|
||||
label:v.name
|
||||
}
|
||||
return data
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let searchList = () =>{
|
||||
currentPage.value = 1
|
||||
getUserlist()
|
||||
}
|
||||
|
||||
let resetList = () =>{
|
||||
currentPage.value = 1
|
||||
filter.userName = ''
|
||||
filter.userPhone = ''
|
||||
filter.roleId = []
|
||||
filter.state = []
|
||||
filter.addTime = ref<Moment[]>([])
|
||||
getUserlist()
|
||||
}
|
||||
|
||||
let confirmSubmit = () =>{
|
||||
let data = {
|
||||
...formState.value,
|
||||
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
}
|
||||
data.userPassword = encode(data.userPassword)
|
||||
let submit = () =>{
|
||||
Https.axiosPost(Https.httpUrls.accountSaveOrEdit, data).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
let tip = !formState.value.id ? 'User added successfully' :'Edit user successfully'
|
||||
message.success(tip)
|
||||
resetList()
|
||||
closeUser()
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
formRef.value.validate().then(()=>{
|
||||
submit()
|
||||
})
|
||||
}
|
||||
|
||||
let enableUser = (record:any,index:any) =>{
|
||||
let data ={
|
||||
id:record.id,
|
||||
enable:record.state == 1 ? 0 : 1
|
||||
}
|
||||
Https.axiosPost(Https.httpUrls.accountEnable, data).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
let tip = record.state == 0? 'Enable successfully' :'Disable successfully'
|
||||
message.success(tip)
|
||||
collectionList.value[index].state = data.enable
|
||||
collectionList.value[index].stateName = data.enable == 1 ? 'Activated' :'Deactivated'
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let deleteUser = (data:any,index:any) =>{
|
||||
let confirmDelete = (data:any,index:any) =>{
|
||||
let newData = {
|
||||
id:data.id
|
||||
}
|
||||
Https.axiosPost(Https.httpUrls.accountDelete, newData).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
message.success('Delete success')
|
||||
collectionList.value.splice(index,1)
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
Modal.confirm({
|
||||
title: "Are you sure delete the user?",
|
||||
icon: createVNode(WarningOutlined),
|
||||
class:'confirm_style',
|
||||
okText: 'Ok',
|
||||
cancelText: 'Cancel',
|
||||
// centered:true,
|
||||
onOk() {
|
||||
confirmDelete(data,index)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let storeQueryAll = () =>{
|
||||
Https.axiosPost(Https.httpUrls.storeQueryAll,{}).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
ownerStoreList.value = rv.map((v:any)=>{
|
||||
let data = {
|
||||
...v,
|
||||
value:v.id,
|
||||
label:v.name
|
||||
}
|
||||
return data
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if(route.query && route.query.type === 'add'){
|
||||
addUser()
|
||||
}
|
||||
getUserlist()
|
||||
storeQueryAll()
|
||||
getRolelist()
|
||||
})
|
||||
|
||||
|
||||
return {
|
||||
...toRefs(filter),
|
||||
tableLoading,
|
||||
userRoleList,
|
||||
userStateList,
|
||||
appUserList,
|
||||
ownerStoreList,
|
||||
columns,
|
||||
collectionList,
|
||||
currentPage,
|
||||
pageSize,
|
||||
total,
|
||||
editUserModal,
|
||||
editUserTitle,
|
||||
formRef,
|
||||
formState,
|
||||
rules,
|
||||
changePage,
|
||||
closeUser,
|
||||
addUser,
|
||||
editUser,
|
||||
searchList,
|
||||
resetList,
|
||||
confirmSubmit,
|
||||
enableUser,
|
||||
deleteUser
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.user_manage_page{
|
||||
padding-left: 28px;
|
||||
|
||||
.user_pic{
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.state_name_block{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
justify-content: center;
|
||||
|
||||
&.enable_state{
|
||||
color: #47E417;
|
||||
|
||||
.state_round{
|
||||
background: #47E417;
|
||||
}
|
||||
}
|
||||
|
||||
&.disable_state{
|
||||
color: #E41335;
|
||||
|
||||
.state_round{
|
||||
background: #E41335;
|
||||
}
|
||||
}
|
||||
|
||||
.state_round{
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 50%;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.operate_list{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.operate_item{
|
||||
font-size: 14px;
|
||||
font-family: Roboto;
|
||||
font-weight: 400;
|
||||
color: #343579;
|
||||
cursor: pointer;
|
||||
|
||||
&.operate_disable_state{
|
||||
color: #E41335;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
321
src/views/childView/labelManage.vue
Normal file
321
src/views/childView/labelManage.vue
Normal file
@@ -0,0 +1,321 @@
|
||||
<template>
|
||||
<div class="label_manage_page list_page">
|
||||
<div class="list_page_content">
|
||||
<div class="list_top_content">
|
||||
<div class="list_top_search_content">
|
||||
<div class="search_content_left">
|
||||
<filterComponent :title="'Label Name'"><a-input v-model:value="name" size="large" placeholder="Please input Label Name or Id" @keydown.enter="searchList"/></filterComponent>
|
||||
<filterComponent :title="'Label attributes'">
|
||||
<a-select
|
||||
v-model:value="type"
|
||||
size="large"
|
||||
style="width:280px"
|
||||
:options="labelTypeList"
|
||||
placeholder="Please select"
|
||||
allowClear
|
||||
></a-select>
|
||||
</filterComponent>
|
||||
<filterComponent :title="'Add Time'"><a-range-picker v-model:value="addTime" size="large" :placeholder="['Start Time', 'End Time']" format="YYYY-MM-DD" valueFormat="YYYY-MM-DD"/></filterComponent>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list_top_button_content">
|
||||
<a-button class="primary_button btn-margin-r-20" type="primary" size="large" @click="searchList()">Seach</a-button>
|
||||
<a-button class="default_button" size="large" @click="resetList()">Reset</a-button>
|
||||
<a-button class="primary_button btn-margin-t-35" type="primary" size="large" @click="addLabel()">+Add Label</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list_table_content">
|
||||
<a-table :columns="columns" :data-source="collectionList" @change="changePage" :loading="tableLoading"
|
||||
:pagination="{
|
||||
showSizeChanger:true,
|
||||
current: currentPage,
|
||||
pageSize:pageSize,
|
||||
total: total,
|
||||
showQuickJumper:true,
|
||||
bordered:false,
|
||||
pageSizeOptions:['10','20','50'],
|
||||
}">
|
||||
<template v-slot:bodyCell="{column,record, index}" >
|
||||
<template v-if="column.dataIndex === 'operation'">
|
||||
<div class="operate_list">
|
||||
<div class="operate_item" @click="editLabel(record)">Edit</div>
|
||||
<div class="operate_item" @click="deleteLabel(record,index)">Delete</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a-modal class="edit_modal_component"
|
||||
:destroyOnClose="true"
|
||||
v-model:visible="editLabelModal"
|
||||
:footer="null"
|
||||
:title="editLabelTitle"
|
||||
width="560px"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
@cancel="closeLabel"
|
||||
>
|
||||
<a-form ref="formRef" :model="formState" :rules="rules" :layout="'vertical'" >
|
||||
<a-form-item label="Label Name" name="name">
|
||||
<a-input v-model:value="formState.name" size="large" placeholder="Please input label name" />
|
||||
</a-form-item>
|
||||
<a-form-item label="Label attributes" name="type">
|
||||
<a-select v-model:value="formState.type" size="large" :options="labelTypeList" placeholder="Please select label attributes"></a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="Remarks" name="remarks">
|
||||
<a-input v-model:value="formState.remarks" size="large" placeholder="Please input remarks"/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<div class="modal_button_list">
|
||||
<a-button class="default_button btn-margin-r-20" size="large" @click="closeLabel">Cancel</a-button>
|
||||
<a-button class="primary_button" type="primary" size="large" @click="confirmSubmit">Submit</a-button>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent,ref,reactive,toRefs,UnwrapRef,onMounted,createVNode } from "vue";
|
||||
import filterComponent from '@/component/filterComponent.vue'
|
||||
import { Moment } from 'moment';
|
||||
import { message,Modal } from "ant-design-vue";
|
||||
import { WarningOutlined } from '@ant-design/icons-vue';
|
||||
import { Https } from "@/tool/https";
|
||||
import { formatTime, startTime, endTime } from "@/tool/util"
|
||||
|
||||
export default defineComponent({
|
||||
name:'labelManage',
|
||||
components:{filterComponent},
|
||||
setup(){
|
||||
let filter:any = reactive({
|
||||
name:'',
|
||||
type:'',
|
||||
addTime:ref<Moment[]>([])
|
||||
})
|
||||
let tableLoading = ref(false)
|
||||
let labelTypeList:any = ref([
|
||||
{ value:'CUSTOM',label:'Custom tags'},
|
||||
{ value:'NEW_PRODUCT',label:'New in'},
|
||||
{ value:'SALE',label:'Discount'},
|
||||
])
|
||||
let labelTypeData:any = {
|
||||
'CUSTOM':'Custom tags',
|
||||
'NEW_PRODUCT':'New in',
|
||||
'SALE':'Discount'
|
||||
}
|
||||
let columns = reactive([
|
||||
{ title: 'Label Name', align:'center', ellipsis: true, dataIndex: 'name', key: 'name' },
|
||||
{ title: 'Label attributes', align:'center', ellipsis: true, dataIndex: 'type', key: 'type', customRender:(record:any)=>{
|
||||
let labelType = labelTypeData[record.text]
|
||||
return labelType },
|
||||
},
|
||||
{ title: 'Add User', align:'center', ellipsis: true, dataIndex: 'createUserName', key: 'createUserName' },
|
||||
{ title: 'Label Product Counts', align:'center', ellipsis: true, dataIndex: 'counts', key: 'counts' },
|
||||
{ title: 'Remarks', align:'center', ellipsis: true, dataIndex: 'remarks', key: 'remarks' },
|
||||
{ title: 'Add Time', align:'center', ellipsis: true, dataIndex: 'createDate', key: 'createDate',customRender:(record:any)=>{
|
||||
let time = formatTime(record.text / 1000, 'YYYY-MM-DD hh:mm:ss')
|
||||
return time },
|
||||
},
|
||||
{
|
||||
title: 'Operations',
|
||||
key: 'operation',
|
||||
align:'center',
|
||||
fixed: 'right',
|
||||
width: 150,
|
||||
dataIndex:'operation',
|
||||
|
||||
},
|
||||
])
|
||||
let collectionList = ref([])
|
||||
let currentPage = ref(1)
|
||||
let pageSize = ref(10)
|
||||
let total = ref(1)
|
||||
let editLabelModal = ref(false)
|
||||
let editLabelTitle = ref('Add Label')
|
||||
let formRef = ref();
|
||||
let formState = ref({
|
||||
id: '',
|
||||
name: '',
|
||||
type:[],
|
||||
remarks:'',
|
||||
});
|
||||
let rules = reactive({
|
||||
name: [
|
||||
{ required: true, message: 'Please input label name', trigger: 'blur' },
|
||||
],
|
||||
type: [
|
||||
{ required: true, message: 'Please select label attributes', trigger: 'blur' },
|
||||
],
|
||||
})
|
||||
|
||||
let changePage = (e:any) =>{
|
||||
currentPage.value = e.current
|
||||
pageSize.value = e.pageSize
|
||||
getLabelist()
|
||||
}
|
||||
|
||||
let closeLabel = () =>{
|
||||
formState.value = {
|
||||
id: '',
|
||||
name: '',
|
||||
type:[],
|
||||
remarks:''
|
||||
}
|
||||
editLabelModal.value = false
|
||||
}
|
||||
|
||||
let addLabel = () =>{
|
||||
editLabelTitle.value = 'Add Label'
|
||||
editLabelModal.value = true
|
||||
}
|
||||
|
||||
let editLabel = (data:any,) =>{
|
||||
editLabelModal.value = true
|
||||
editLabelTitle.value = 'Eidt Label'
|
||||
formState.value = {
|
||||
id: data.id,
|
||||
name: data.name,
|
||||
type:data.type,
|
||||
remarks:data.remarks,
|
||||
}
|
||||
}
|
||||
|
||||
let getLabelist = () =>{
|
||||
let data = {
|
||||
name : filter.name,
|
||||
type:filter.type,
|
||||
createDateStart:filter.addTime && filter.addTime.length ? startTime(filter.addTime[0]) : '',
|
||||
createDateEnd:filter.addTime && filter.addTime.length ? endTime(filter.addTime[1]) : '',
|
||||
page:currentPage.value,
|
||||
size:pageSize.value
|
||||
}
|
||||
tableLoading.value = true
|
||||
Https.axiosPost(Https.httpUrls.labelQueryStorePage, data).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
tableLoading.value = false
|
||||
collectionList.value = rv.content
|
||||
total.value = rv.total
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let confirmSubmit = () =>{
|
||||
let data = {
|
||||
...formState.value,
|
||||
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
}
|
||||
formRef.value.validate().then(()=>{
|
||||
submit()
|
||||
})
|
||||
let submit = () => {
|
||||
Https.axiosPost(Https.httpUrls.labelSaveOrEdit, data).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
let tip = !formState.value.id ? 'Label added successfully' :'Edit label successfully'
|
||||
message.success(tip)
|
||||
resetList()
|
||||
closeLabel()
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let searchList = () =>{
|
||||
currentPage.value = 1
|
||||
getLabelist()
|
||||
}
|
||||
|
||||
let resetList = () =>{
|
||||
currentPage.value = 1
|
||||
filter.name = ''
|
||||
filter.type = ''
|
||||
filter.addTime = ref<Moment[]>([])
|
||||
getLabelist()
|
||||
}
|
||||
|
||||
let deleteLabel = (data:any,index:any) =>{
|
||||
let confirmDelete = (data:any,index:any) =>{
|
||||
let newData = {
|
||||
id:data.id
|
||||
}
|
||||
Https.axiosPost(Https.httpUrls.labelDelete, newData).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
message.success('Delete success')
|
||||
collectionList.value.splice(index,1)
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
Modal.confirm({
|
||||
title: "Are you sure about the label? The label associated with the product will become invalid after deletion!",
|
||||
icon: createVNode(WarningOutlined),
|
||||
class:'confirm_style',
|
||||
okText: 'Ok',
|
||||
cancelText: 'Cancel',
|
||||
// centered:true,
|
||||
onOk() {
|
||||
confirmDelete(data,index)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getLabelist()
|
||||
})
|
||||
|
||||
|
||||
return {
|
||||
...toRefs(filter),
|
||||
tableLoading,
|
||||
labelTypeList,
|
||||
columns,
|
||||
collectionList,
|
||||
currentPage,
|
||||
pageSize,
|
||||
total,
|
||||
editLabelModal,
|
||||
editLabelTitle,
|
||||
formRef,
|
||||
formState,
|
||||
rules,
|
||||
changePage,
|
||||
closeLabel,
|
||||
addLabel,
|
||||
editLabel,
|
||||
confirmSubmit,
|
||||
searchList,
|
||||
resetList,
|
||||
deleteLabel
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.label_manage_page{
|
||||
padding-left: 28px;
|
||||
|
||||
.operate_list{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.operate_item{
|
||||
font-size: 14px;
|
||||
font-family: Roboto;
|
||||
font-weight: 400;
|
||||
color: #343579;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
485
src/views/childView/productDetail.vue
Normal file
485
src/views/childView/productDetail.vue
Normal file
@@ -0,0 +1,485 @@
|
||||
<template>
|
||||
<div class="productDetail_page">
|
||||
<div class="productDetail_page_cotent">
|
||||
<div class="productDetail_page_cotent_center">
|
||||
<div class="detail_item_block">
|
||||
<div class="detail_item_title_block">
|
||||
<span class="icon iconfont icon-a-gengduocaidangongneng detail_icon"></span>
|
||||
<div>Product image</div>
|
||||
</div>
|
||||
<div class="product_master_diagram">
|
||||
<img class="product_master_img" :src="formState.pictureUrl">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="detail_item_block">
|
||||
<div class="detail_item_title_block">
|
||||
<span class="icon iconfont icon-a-gengduocaidangongneng detail_icon"></span>
|
||||
<div>Product label(s)</div>
|
||||
</div>
|
||||
<div class="detail_item_content">
|
||||
<div class="productCategory_block">
|
||||
<div class="produce_label_item" :style="{background:colorMap[label.type]}" v-for="label in productLabelList" :key="label.id">{{label.name}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="detail_item_block">
|
||||
<div class="detail_item_title_block">
|
||||
<span class="icon iconfont icon-a-gengduocaidangongneng detail_icon"></span>
|
||||
<div>Pirce</div>
|
||||
</div>
|
||||
<div class="detail_item_content">
|
||||
<div class="productCategory_block">${{formState.price}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="detail_item_block">
|
||||
<div class="detail_item_title_block">
|
||||
<span class="icon iconfont icon-a-gengduocaidangongneng detail_icon"></span>
|
||||
<div>Inventory</div>
|
||||
</div>
|
||||
<div class="detail_item_content">
|
||||
<a-table class="form_width_100" :columns="columns" :data-source="formState.storeList" bordered
|
||||
:pagination="false" :scroll="{y: 400 }">
|
||||
</a-table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="detail_item_block">
|
||||
<div class="detail_item_title_block">
|
||||
<span class="icon iconfont icon-a-gengduocaidangongneng detail_icon"></span>
|
||||
<div>Label attributes</div>
|
||||
</div>
|
||||
<div class="detail_item_content">
|
||||
<div class="productCategory_block">{{formState.productCategory}}</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="detail_item_sec_title sec_title_margin">Attribute(s)</div>
|
||||
<div class="detail_item_content">
|
||||
<div class="attribute_block" v-if="formState.productAttribute?.length">
|
||||
<div class="attribute_block_item" v-for="attr in formState.productAttribute" :key="attr.value">
|
||||
<div class="attribute_block_item_content">
|
||||
<div class="attribute_item_title">{{attr.labelType}}</div>
|
||||
<div class="attribute_item_value" :title="attr.attributeValueList.join(',')">{{attr.attributeValueList.join(',')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="null_data_block">
|
||||
<img class="null_data_img" src="@/assets/images/null_img.png">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="detail_item_block">
|
||||
<div class="detail_item_title_block">
|
||||
<span class="icon iconfont icon-a-gengduocaidangongneng detail_icon"></span>
|
||||
<div>Mix and Match(es)</div>
|
||||
</div>
|
||||
<div class="detail_item_content">
|
||||
<div class="product_match_block">
|
||||
<div class="product_match_item" v-for="(match,index) in formState.assortmentList" :key="match.title" v-show="index<5 || assortmentShowMore">
|
||||
<div class="product_match_item_header">
|
||||
<div>Look{{index+1}}</div>
|
||||
</div>
|
||||
<div class="product_match_item_content">
|
||||
<div class="match_item_img_content" v-for="img in match" :key="img">
|
||||
<div class="match_item_img_block" @click="showMatchDetail(img.productId)">
|
||||
<img :src="img.generatePictureUrl">
|
||||
</div>
|
||||
<div class="product_price">${{img.price}}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a-button class="primary_button show_more_button" type="primary" @click="assortmentListShowMore()" v-show="formState.assortmentList.length>5">{{assortmentShowMore?'Hide':'See More'}}</a-button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<ProductDetailModal ref="productDetailModalDom"></ProductDetailModal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent,ref,onMounted,reactive } from "vue";
|
||||
import { message } from "ant-design-vue";
|
||||
import { useRouter,useRoute } from 'vue-router'
|
||||
import { Https } from "@/tool/https";
|
||||
import ProductDetailModal from '@/component/productComponent/productDetailModal.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name:'productDetail',
|
||||
components:{ProductDetailModal},
|
||||
setup(){
|
||||
const route = useRoute()
|
||||
let productDetail:any = ref([])
|
||||
let productDetailModalDom:any = ref()
|
||||
let formState:any = ref({
|
||||
productPic:'',
|
||||
productLabel:[],
|
||||
inventoryData:[],
|
||||
storeList:[],
|
||||
storeNameList:[],
|
||||
productCategory:'',
|
||||
productAttribute:[],
|
||||
assortmentList:[]
|
||||
});
|
||||
let assortmentShowMore = ref(false)
|
||||
let productCategoryList:any = ref([])
|
||||
let productAttributeList = ref([])
|
||||
let columns = reactive([
|
||||
{ title: 'Store', align:'center', ellipsis: true, dataIndex: 'storeName', key: 'storeName',width:"200px" },
|
||||
{
|
||||
title: 'Inventory',
|
||||
align:'center',
|
||||
ellipsis: true,
|
||||
dataIndex: 'inventory',
|
||||
key: 'inventory',
|
||||
children: [
|
||||
{title: 'XS',dataIndex: 'XS',key: 'XS', align:'center', },
|
||||
{title: 'S',dataIndex: 'S',key: 'S', align:'center',},
|
||||
{title: 'M',dataIndex: 'M',key: 'M', align:'center',},
|
||||
{title: 'L',dataIndex: 'L',key: 'L', align:'center',},
|
||||
{title: 'XL',dataIndex: 'XL',key: 'XL', align:'center',},
|
||||
{title: 'XXL',dataIndex: 'XXL',key: 'XXL', align:'center',},
|
||||
],
|
||||
},
|
||||
])
|
||||
let colorMap = ref({
|
||||
CUSTOM:'#798BD9',
|
||||
NEW_PRODUCT:'#FFC384',
|
||||
SALE:'#79D97C',
|
||||
})
|
||||
|
||||
|
||||
let productLabelList:any = ref([])
|
||||
|
||||
let getProductLabelList = () =>{
|
||||
Https.axiosPost(Https.httpUrls.queryProductLabel).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
productLabelList.value = rv.filter((v:any) => formState.value.productLabel.indexOf(v.id) > -1)
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let getStoreInfo = (storeInfo:any) =>{
|
||||
let storeList = []
|
||||
let storeNameList:any = []
|
||||
for(let item of storeInfo){
|
||||
let sizeData:any = {}
|
||||
for(let size of item.stock){
|
||||
sizeData[size.size] = size.num
|
||||
}
|
||||
let data = {
|
||||
storeName:item.storeName,
|
||||
storeId:item.storeId,
|
||||
...sizeData,
|
||||
}
|
||||
storeList.push(data)
|
||||
}
|
||||
storeInfo.forEach((item:any) => {
|
||||
item.stock.forEach((stockItem:any) => {
|
||||
storeNameList.push(stockItem.size);
|
||||
});
|
||||
});
|
||||
|
||||
// 排序并去重
|
||||
storeNameList = storeNameList.sort().filter((value:any, index:any, array:any) => {
|
||||
return array.indexOf(value) === index;
|
||||
});
|
||||
let children:any = []
|
||||
storeNameList.forEach((item:any) => {
|
||||
children.push({
|
||||
title:item,
|
||||
dataIndex:item,
|
||||
key:item,
|
||||
align:'center'
|
||||
})
|
||||
});
|
||||
columns[1].children = children
|
||||
return {storeList,storeNameList}
|
||||
}
|
||||
|
||||
let getProductDetail = (id:any) =>{
|
||||
return new Promise((resolve:any,rj:any)=>{
|
||||
Https.axiosGet(Https.httpUrls.productDetail+'?id='+id).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
let store = getStoreInfo(rv.storeInfoList)
|
||||
formState.value = {
|
||||
pictureUrl:rv.pictureUrl,
|
||||
productLabel:rv.productLabelInfo.map((v:any)=>v.id),
|
||||
price:rv.price,
|
||||
productCategory:rv.attributeItemInfo.labelItem,
|
||||
productAttribute:rv.attributeItemInfo.attributeTypeList,
|
||||
storeList:store.storeList,
|
||||
storeNameList:store.storeNameList,
|
||||
assortmentList:rv.assortmentList,
|
||||
}
|
||||
productDetail.value = rv
|
||||
resolve(rv)
|
||||
}
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
let showMatchDetail = (productId:any) =>{
|
||||
productDetailModalDom.value.openProductDetailModal(productId)
|
||||
}
|
||||
|
||||
let assortmentListShowMore = () =>{
|
||||
assortmentShowMore.value = !assortmentShowMore.value
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
getProductDetail(route.query.id).then(rv=>{
|
||||
getProductLabelList()
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
return {
|
||||
productDetailModalDom,
|
||||
columns,
|
||||
formState,
|
||||
assortmentShowMore,
|
||||
productCategoryList,
|
||||
productAttributeList,
|
||||
colorMap,
|
||||
productLabelList,
|
||||
showMatchDetail,
|
||||
assortmentListShowMore,
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.productDetail_page{
|
||||
padding-left: 28px;
|
||||
height: 100%;
|
||||
|
||||
.productDetail_page_cotent{
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
background: #fff;
|
||||
|
||||
.productDetail_page_cotent_center{
|
||||
width: 1150px;
|
||||
padding: 20px 70px 30px 30px;
|
||||
margin: 0 auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.detail_item_block{
|
||||
margin-bottom: 15px;
|
||||
|
||||
.detail_icon{
|
||||
color: #80B8F8;
|
||||
font-size: 24px;
|
||||
margin-right: 14px;
|
||||
}
|
||||
|
||||
.detail_item_title_block{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 16px;
|
||||
font-family: Adobe Heiti Std;
|
||||
font-weight: normal;
|
||||
color: #030303;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.detail_item_content{
|
||||
padding-left: 10px;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.produce_label_item{
|
||||
padding: 0 11px;
|
||||
margin: 9px 27px 9px 0;
|
||||
height: 27px;
|
||||
line-height: 27px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px;
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.productCategory_block{
|
||||
width: 100%;
|
||||
line-height: 46px;
|
||||
padding-left: 20px;
|
||||
font-size: 18px;
|
||||
color: #030303;
|
||||
height: 46px;
|
||||
border: 1px solid #DFDFDF;
|
||||
}
|
||||
|
||||
.detail_item_sec_title{
|
||||
padding-left: 38px;
|
||||
font-size: 16px;
|
||||
font-family: Adobe Heiti Std;
|
||||
font-weight: normal;
|
||||
color: #030303;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.sec_title_margin{
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.attribute_block{
|
||||
background: #F7F8FC;
|
||||
border: 1px solid #DFDFDF;
|
||||
padding-top: 30px;
|
||||
|
||||
.attribute_block_item{
|
||||
padding: 0 22px;
|
||||
display: inline-block;
|
||||
margin-bottom: 30px;
|
||||
width: 50%;
|
||||
|
||||
.attribute_block_item_content{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.attribute_item_title{
|
||||
width: 120px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.attribute_item_value{
|
||||
width: 200px;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
border: 1px solid #DFDFDF;
|
||||
border-radius: 4px;
|
||||
font-size: 16px;
|
||||
padding-left: 18px;
|
||||
color: #030303;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.null_data_block{
|
||||
background: #F7F8FC;
|
||||
border: 1px solid #DFDFDF;
|
||||
padding: 30px 0;
|
||||
text-align: center;
|
||||
|
||||
.null_data_img{
|
||||
width: 130px;
|
||||
}
|
||||
}
|
||||
|
||||
.product_match_block{
|
||||
|
||||
.product_match_item{
|
||||
background: #F7F8FC;
|
||||
border: 1px solid #DFDFDF;
|
||||
padding: 0 16px 26px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.product_match_item_header{
|
||||
height: 83px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 18px;
|
||||
color: #030303;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.product_match_item_content{
|
||||
display: flex;
|
||||
|
||||
.match_item_img_content{
|
||||
margin-right: 20px;
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
.match_item_img_block{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 160px;
|
||||
height: 100px;
|
||||
position: relative;
|
||||
border: 1px solid #DFDFDF;
|
||||
cursor: pointer;
|
||||
|
||||
img{
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
|
||||
&:last-child{
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.product_price{
|
||||
text-align: center;
|
||||
margin-top: 5px;
|
||||
color: #030303;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.show_more_button{
|
||||
margin: 20px auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.form_width_100{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.product_master_diagram{
|
||||
width: 400px;
|
||||
height: 400px;
|
||||
margin: 30px auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.product_master_img{
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
580
src/views/childView/productManage.vue
Normal file
580
src/views/childView/productManage.vue
Normal file
@@ -0,0 +1,580 @@
|
||||
<template>
|
||||
<div class="product_manage_page list_page">
|
||||
<div class="list_page_content">
|
||||
<div class="list_top_content">
|
||||
<div class="list_top_search_content">
|
||||
<div class="search_content_left">
|
||||
<filterComponent :title="'Product Label'">
|
||||
<a-select v-model:value="productLabelIds" size="large" style="width:280px" optionFilterProp="label" :options="productLabelList" placeholder="Please select" allowClear show-search></a-select>
|
||||
</filterComponent>
|
||||
<filterComponent :title="'Category'">
|
||||
<a-select v-model:value="labelItem" size="large" style="width:280px" :options="labelItemList" placeholder="Please select" allowClear @change="labelItemChange" optionFilterProp="label" show-search></a-select>
|
||||
</filterComponent>
|
||||
<filterComponent :title="'On Sale State'">
|
||||
<a-select v-model:value="onSaleState" size="large" style="width:280px" :options="onSaleStateList" placeholder="Please select" allowClear optionFilterProp="label" show-search></a-select>
|
||||
</filterComponent>
|
||||
<filterComponent :title="'Label attributes'">
|
||||
<a-select v-model:value="labelTypeMap" size="large" style="width:280px" :options="labelTypeList" placeholder="Please select" allowClear @change="labelTypeChange" optionFilterProp="label" show-search></a-select>
|
||||
</filterComponent>
|
||||
<filterComponent :title="'Add Time'"><a-range-picker v-model:value="addTime" size="large" :placeholder="['Start Time', 'End Time']" format="YYYY-MM-DD" valueFormat="YYYY-MM-DD"/></filterComponent>
|
||||
<filterComponent :title="'Store'">
|
||||
<a-select v-model:value="storeIds" size="large" style="width:280px" :options="shopList" placeholder="Please select" allowClear optionFilterProp="label" show-search></a-select>
|
||||
</filterComponent>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list_top_button_content" :style="{width: '255px'}">
|
||||
<a-button class="primary_button btn-margin-r-20" type="primary" size="large" @click="searchList()">Seach</a-button>
|
||||
<a-button class="default_button btn-margin-r-20" size="large" @click="resetList()">Reset</a-button>
|
||||
<a-button class="primary_button btn-margin-t-35 btn-margin-r-20" type="primary" size="large" @click="addProduct()" v-if="operatePermission.ADD">+Add product</a-button>
|
||||
<a-button class="primary_button btn-margin-t-35" type="primary" size="large" @click="exportProduct()" :loading="exportLoading">Export</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list_table_content">
|
||||
<a-table :columns="columns" :data-source="collectionList" @change="changePage" :loading="tableLoading"
|
||||
:getPopupContainer="(triggerNode) => getPopupContainer(triggerNode)"
|
||||
:pagination="{
|
||||
showSizeChanger:true,
|
||||
current: currentPage,
|
||||
pageSize:pageSize,
|
||||
total: total,
|
||||
showQuickJumper:true,
|
||||
bordered:false,
|
||||
pageSizeOptions:['10','20','50'],
|
||||
}">
|
||||
<template v-slot:bodyCell="{column,record, index}" >
|
||||
<template v-if="column.dataIndex === 'pictureUrl'">
|
||||
<img class="product_pic" :src="record.pictureUrl">
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'productLabel'">
|
||||
<a-popover placement="top" :getPopupContainer="(triggerNode) => getPopupContainer(triggerNode)" arrowPointAtCenter>
|
||||
<template #content>
|
||||
<div class="record_pop_block">{{record.productLabel}}</div>
|
||||
</template>
|
||||
<div class="record_pop_content">{{record.productLabel}}</div>
|
||||
</a-popover>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'labelType'">
|
||||
<a-popover placement="top" :getPopupContainer="(triggerNode) => getPopupContainer(triggerNode)">
|
||||
<template #content>
|
||||
<div class="record_pop_block">{{record.labelType}}</div>
|
||||
</template>
|
||||
<div class="record_pop_content">{{record.labelType}}</div>
|
||||
</a-popover>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'shop'" >
|
||||
<a-popover placement="top" :getPopupContainer="(triggerNode) => getPopupContainer(triggerNode)">
|
||||
<template #content>
|
||||
<div class="record_pop_block">{{record.shop}}</div>
|
||||
</template>
|
||||
<div class="record_pop_content">{{record.shop}}</div>
|
||||
</a-popover>
|
||||
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'onSaleState'">
|
||||
<a-switch checked-children="open" un-checked-children="close" v-model:checked="record.onSaleState" @change="change_on_sale(record)"/>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'operation'">
|
||||
<div class="operate_list">
|
||||
<div class="operate_item" @click="editProduct(record)" v-if="operatePermission.EDIT">Edit</div>
|
||||
<div class="operate_item" @click="toProductDteail(record)" v-if="operatePermission.DETAIL">Detail</div>
|
||||
<div class="operate_item" @click="deleteProduct(record,index)" v-if="operatePermission.DELETE">Delete</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<AddProduct ref="addproductComponent" :productLabelList="productLabelList" @confirmSubmitAdd="confirmSubmitAdd"></AddProduct>
|
||||
<EditProduct ref="editProductComponent" :productLabelList="productLabelList" @refreshList="getProductlist"></EditProduct>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent,ref,reactive,toRefs,UnwrapRef,onMounted,createVNode,computed } from "vue";
|
||||
import { useRouter,useRoute } from 'vue-router'
|
||||
import filterComponent from '@/component/filterComponent.vue'
|
||||
import AddProduct from '@/component/productComponent/addProduct.vue'
|
||||
import EditProduct from '@/component/productComponent/editProduct.vue'
|
||||
import { Moment } from 'moment';
|
||||
import { message,Modal } from "ant-design-vue";
|
||||
import { WarningOutlined } from '@ant-design/icons-vue';
|
||||
import { Https } from "@/tool/https";
|
||||
import { formatTime, startTime, endTime } from "@/tool/util"
|
||||
|
||||
type TableDataType = {
|
||||
key: string;
|
||||
name: string;
|
||||
age: number;
|
||||
createDate: string;
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
name:'productManage',
|
||||
components:{filterComponent,AddProduct,EditProduct},
|
||||
setup(){
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
let filter:any = reactive({
|
||||
productLabelIds:[],
|
||||
labelItem:[],
|
||||
onSaleState:[],
|
||||
labelTypeMap:[],
|
||||
addTime:ref<Moment[]>([]),
|
||||
storeIds:[],
|
||||
})
|
||||
let filterLabelTypeMap :any = ref({})
|
||||
let tableLoading = ref(false)
|
||||
let exportLoading = ref(false)
|
||||
let addproductComponent:any = ref(null)
|
||||
let editProductComponent:any = ref(null)
|
||||
let productLabelList:any = ref([])
|
||||
let labelItemList:any = ref([])
|
||||
let labelTypeList:any = ref([])
|
||||
let onSaleStateList:any = ref([{
|
||||
value:'1',label:'Open'
|
||||
},{
|
||||
value:'0',label:'Close'
|
||||
}])
|
||||
let shopList:any = ref([])
|
||||
const columns = computed(() => {
|
||||
const sorted = sortedInfo.value || {};
|
||||
return [
|
||||
{ title: 'Product Pic', align:'center', ellipsis: true, dataIndex: 'pictureUrl', key: 'pictureUrl' },
|
||||
{ title: 'Product Label', align:'center', dataIndex: 'productLabel', key: 'productLabel'},
|
||||
{ title: 'Category', align:'center', ellipsis: true, dataIndex: 'labelItem', key: 'labelItem'},
|
||||
{ title: 'Label attributes', align:'center', dataIndex: 'labelType', key: 'labelType'},
|
||||
{ title: 'Shop', align:'center', dataIndex: 'shop', key: 'shop' },
|
||||
{ title: 'Inventory', align:'center', ellipsis: true, dataIndex: 'total', key: 'total', sorter:()=>{},
|
||||
sortOrder: sorted.columnKey === 'total' && sorted.order,
|
||||
},
|
||||
{ title: 'price', align:'center', ellipsis: true, dataIndex: 'price', key: 'price',customRender:(record:any)=>{
|
||||
let newPrrice = '$' + record.text
|
||||
return newPrrice },
|
||||
sorter:()=>{},
|
||||
sortOrder: sorted.columnKey === 'price' && sorted.order,
|
||||
},
|
||||
{ title: 'Add Time', align:'center', ellipsis: true, dataIndex: 'createDate', key: 'createDate',customRender:(record:any)=>{
|
||||
let time = formatTime(record.text / 1000, 'YYYY-MM-DD hh:mm:ss')
|
||||
return time },
|
||||
sorter:()=>{},
|
||||
sortOrder: sorted.columnKey === 'createDate' && sorted.order,
|
||||
},
|
||||
{ title: 'On Sale State', align:'center', ellipsis: true, dataIndex: 'onSaleState', key: 'onSaleState' },
|
||||
{
|
||||
title: 'Operations',
|
||||
key: 'operation',
|
||||
align:'center',
|
||||
fixed: 'right',
|
||||
width: 150,
|
||||
dataIndex:'operation',
|
||||
|
||||
},
|
||||
]
|
||||
})
|
||||
let collectionList = ref([])
|
||||
let currentPage = ref(1)
|
||||
let pageSize = ref(10)
|
||||
let total = ref(1)
|
||||
let editProductTitle = ref('Add Product')
|
||||
let formState = ref({
|
||||
productId: '',
|
||||
productName: '',
|
||||
productType:'',
|
||||
remarks:'',
|
||||
});
|
||||
let columnSortListData:any = []; //排序参数
|
||||
let sortedInfo:any = ref()
|
||||
let typeMap:any = {
|
||||
dress:'Dress_Type',
|
||||
top:'Top_Type',
|
||||
bottom:'BTM_Type',
|
||||
outer:'Outer_Type',
|
||||
jumpsuit:'Jumpsuit_subtype'
|
||||
|
||||
}
|
||||
let rules = {
|
||||
productName: [
|
||||
{ required: true, message: 'Please input product name', trigger: 'blur' },
|
||||
],
|
||||
productType: [
|
||||
{ required: true, message: 'Please select product type', trigger: 'blur' },
|
||||
],
|
||||
}
|
||||
|
||||
let operatePermission:any = reactive({
|
||||
DETAIL:false,
|
||||
ADD:false,
|
||||
EDIT:false,
|
||||
DELETE:false,
|
||||
})
|
||||
|
||||
let getPopupContainer = (triggerNode:any) =>{
|
||||
return triggerNode.parentNode || document.body
|
||||
}
|
||||
|
||||
let changePage = (e:any, filters: any, sorter: any) =>{
|
||||
currentPage.value = e.current
|
||||
pageSize.value = e.pageSize
|
||||
if(sorter.order){
|
||||
columnSortListData = [{
|
||||
column:getSortField(sorter.field),
|
||||
style:sorter.order == 'ascend' ? 'asc' : 'desc'
|
||||
}]
|
||||
sortedInfo.value = sorter
|
||||
}else{
|
||||
columnSortListData = []
|
||||
sortedInfo.value = sorter
|
||||
}
|
||||
getProductlist()
|
||||
}
|
||||
|
||||
let getSortField = (field:string) =>{
|
||||
let fieldData:any = {
|
||||
createDate: 'create_date',
|
||||
price:'price',
|
||||
total:'total',
|
||||
}
|
||||
return fieldData[field]
|
||||
}
|
||||
|
||||
let closeProduct = () =>{
|
||||
formState.value = {
|
||||
productId: '',
|
||||
productName: '',
|
||||
productType:'',
|
||||
remarks:'',
|
||||
}
|
||||
}
|
||||
|
||||
let addProduct = () =>{
|
||||
addproductComponent.value.showModal()
|
||||
}
|
||||
|
||||
let change_on_sale = (record:any) =>{
|
||||
let data = {
|
||||
id:record.id,
|
||||
onSaleState:record.onSaleState ? 1 : 0
|
||||
}
|
||||
Https.axiosPost(Https.httpUrls.doOnSale, data).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let editProduct = (record:any) =>{
|
||||
editProductComponent.value.showModal({record:record,labelItemList:labelItemList.value})
|
||||
}
|
||||
|
||||
let toProductDteail = (record:any) =>{
|
||||
router.push({path:'/home/productDetail',query:{id:record.id}})
|
||||
}
|
||||
|
||||
let getProductlist = () =>{
|
||||
let data = {
|
||||
columnSortList:columnSortListData,
|
||||
productLabelIds:filter.productLabelIds && filter.productLabelIds.length ? [filter.productLabelIds] : [],
|
||||
labelItem:filter.labelItem && filter.labelItem.length ? filter.labelItem : '',
|
||||
onSaleState:filter.onSaleState && filter.onSaleState.length ? filter.onSaleState : '',
|
||||
labelTypeMap:filterLabelTypeMap.value,
|
||||
storeIds:filter.storeIds && filter.storeIds.length ? [filter.storeIds] : [],
|
||||
createDateStart:filter.addTime && filter.addTime.length ? startTime(filter.addTime[0]) : '',
|
||||
createDateEnd:filter.addTime && filter.addTime.length ? endTime(filter.addTime[1]) : '',
|
||||
page:currentPage.value,
|
||||
size:pageSize.value
|
||||
}
|
||||
tableLoading.value = true
|
||||
Https.axiosPost(Https.httpUrls.queryProductPage, data).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
tableLoading.value = false
|
||||
collectionList.value = rv.content.map((v:any)=>{
|
||||
return {
|
||||
...v,
|
||||
onSaleState:v.onSaleState == 1? true :false,
|
||||
productLabel:getProductLabel(v.productLabelInfo),
|
||||
labelItem:v.attributeItemInfo.labelItem,
|
||||
labelType:getLabelType(v.attributeItemInfo || []),
|
||||
shop:getStoreName(v.storeInfoList)
|
||||
}
|
||||
})
|
||||
getProductPromission()
|
||||
total.value = rv.total
|
||||
}
|
||||
}
|
||||
).catch((err:any)=>{
|
||||
tableLoading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
let getProductLabel = (productLabelInfo:any) =>{
|
||||
let productLabel = productLabelInfo.map((v:any) => v.name).join(',')
|
||||
return productLabel
|
||||
}
|
||||
|
||||
let getLabelType = (attributeItemInfo:any) => {
|
||||
// let labelType = attributeItemInfo.attributeTypeList ? attributeItemInfo.attributeTypeList.filter((v:any) => v.labelType === typeMap[attributeItemInfo.labelItem]) :[]
|
||||
// labelType = labelType.map(((v:any)=>v.attributeValueList)).join(',')
|
||||
let labelType = attributeItemInfo.labelTypeValueList && attributeItemInfo.labelTypeValueList.length ? attributeItemInfo.labelTypeValueList.join(',') : ''
|
||||
return labelType
|
||||
}
|
||||
|
||||
let getStoreName = (storeInfoList:any) =>{
|
||||
let storeName = storeInfoList.map((v:any) => v.storeName).join(',')
|
||||
return storeName
|
||||
}
|
||||
|
||||
|
||||
let getProductLabelList = () =>{
|
||||
Https.axiosPost(Https.httpUrls.queryProductLabel).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
productLabelList.value = rv.map((v:any)=>{
|
||||
return {
|
||||
...v,
|
||||
value:v.id,
|
||||
label:v.name
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let getStoreList = () =>{
|
||||
Https.axiosPost(Https.httpUrls.queryProductStore).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
shopList.value = rv.map((v:any)=>{
|
||||
return {
|
||||
...v,
|
||||
value:v.id,
|
||||
label:v.name
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let getAttributeList = () =>{
|
||||
Https.axiosGet(Https.httpUrls.attributeQueryAll).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
labelItemList.value = rv.map((v:any)=>{
|
||||
return {
|
||||
...v,
|
||||
value:v.labelItem,
|
||||
label:v.labelItem
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let labelItemChange = (event:any,selectedOptions:any) =>{
|
||||
filter.labelTypeMap =[]
|
||||
filterLabelTypeMap.value = {}
|
||||
if(selectedOptions){
|
||||
labelTypeList.value = selectedOptions.labelTypeValueList.map((v:any)=>{
|
||||
return {
|
||||
value:v,
|
||||
label:v
|
||||
}
|
||||
})
|
||||
}else{
|
||||
labelTypeList.value = []
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let labelTypeChange = (event:any,selectedOptions:any) => {
|
||||
let key = typeMap[filter.labelItem]
|
||||
if(selectedOptions){
|
||||
filterLabelTypeMap.value[key] = [event]
|
||||
}else{
|
||||
filterLabelTypeMap.value = {}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let searchList = () =>{
|
||||
currentPage.value = 1
|
||||
getProductlist()
|
||||
}
|
||||
|
||||
let exportProduct = () =>{
|
||||
let data = {
|
||||
columnSortList:columnSortListData,
|
||||
productLabelIds:filter.productLabelIds && filter.productLabelIds.length ? [filter.productLabelIds] : [],
|
||||
labelItem:filter.labelItem && filter.labelItem.length ? filter.labelItem : '',
|
||||
onSaleState:filter.onSaleState && filter.onSaleState.length ? filter.onSaleState : '',
|
||||
labelTypeMap:filterLabelTypeMap.value,
|
||||
storeIds:filter.storeIds && filter.storeIds.length ? [filter.storeIds] : [],
|
||||
createDateStart:filter.addTime && filter.addTime.length ? startTime(filter.addTime[0]) : '',
|
||||
createDateEnd:filter.addTime && filter.addTime.length ? endTime(filter.addTime[1]) : '',
|
||||
}
|
||||
exportLoading.value = true
|
||||
Https.axiosPost(Https.httpUrls.exportProduct, data).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
exportLoading.value = false
|
||||
window.location.href= rv
|
||||
}
|
||||
}
|
||||
).catch((err:any)=>{
|
||||
exportLoading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
let resetList = () =>{
|
||||
currentPage.value = 1
|
||||
filter.productLabelIds = []
|
||||
filter.labelItem = []
|
||||
filter.onSaleState = []
|
||||
filter.labelTypeMap = []
|
||||
filter.addTime = ref<Moment[]>([])
|
||||
filter.storeIds = []
|
||||
sortedInfo.value = null
|
||||
columnSortListData = []
|
||||
getProductlist()
|
||||
}
|
||||
|
||||
let deleteProduct = (data:any,index:any) =>{
|
||||
let confirmDelete = (data:any,index:any) =>{
|
||||
let newData = {
|
||||
id:data.id
|
||||
}
|
||||
Https.axiosPost(Https.httpUrls.productDelete, newData).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
message.success('Delete success')
|
||||
collectionList.value.splice(index,1)
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
Modal.confirm({
|
||||
title: "Are you sure about the product? The product associated with the product will become invalid after deletion!",
|
||||
icon: createVNode(WarningOutlined),
|
||||
class:'confirm_style',
|
||||
okText: 'Ok',
|
||||
cancelText: 'Cancel',
|
||||
// centered:true,
|
||||
onOk() {
|
||||
confirmDelete(data,index)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let getProductPromission = () =>{
|
||||
let menuList:any = sessionStorage.getItem('menuList')
|
||||
menuList= JSON.parse(menuList)
|
||||
for(let item of menuList){
|
||||
if(item.name === 'Product Management'){
|
||||
for(let operate of item.operationList){
|
||||
operatePermission[operate.code] = operate.select == 1 ? true :false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
let confirmSubmitAdd = () =>{
|
||||
resetList()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if(route.query && route.query.type === 'add'){
|
||||
addProduct()
|
||||
}
|
||||
getProductlist()
|
||||
getProductLabelList()
|
||||
getStoreList()
|
||||
getAttributeList()
|
||||
})
|
||||
|
||||
|
||||
return {
|
||||
...toRefs(filter),
|
||||
addproductComponent,
|
||||
editProductComponent,
|
||||
tableLoading,
|
||||
exportLoading,
|
||||
productLabelList,
|
||||
labelItemList,
|
||||
labelTypeList,
|
||||
onSaleStateList,
|
||||
shopList,
|
||||
columns,
|
||||
collectionList,
|
||||
currentPage,
|
||||
pageSize,
|
||||
total,
|
||||
editProductTitle,
|
||||
formState,
|
||||
rules,
|
||||
operatePermission,
|
||||
getPopupContainer,
|
||||
changePage,
|
||||
closeProduct,
|
||||
addProduct,
|
||||
change_on_sale,
|
||||
editProduct,
|
||||
toProductDteail,
|
||||
labelItemChange,
|
||||
labelTypeChange,
|
||||
searchList,
|
||||
exportProduct,
|
||||
resetList,
|
||||
deleteProduct,
|
||||
confirmSubmitAdd,
|
||||
getProductlist
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.product_manage_page{
|
||||
padding-left: 28px;
|
||||
|
||||
.product_pic{
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.operate_list{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.operate_item{
|
||||
font-size: 14px;
|
||||
font-family: Roboto;
|
||||
font-weight: 400;
|
||||
color: #343579;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.record_pop_block{
|
||||
max-width: 300px;
|
||||
// word-break: break-all;
|
||||
}
|
||||
|
||||
.record_pop_content{
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
292
src/views/childView/storeManage.vue
Normal file
292
src/views/childView/storeManage.vue
Normal file
@@ -0,0 +1,292 @@
|
||||
<template>
|
||||
<div class="store_manage_page list_page">
|
||||
<div class="list_page_content">
|
||||
<div class="list_top_content">
|
||||
<div class="list_top_search_content">
|
||||
<div class="search_content_left">
|
||||
<filterComponent :title="'Store Name'"><a-input v-model:value="name" size="large" placeholder="Please input Store Name or Id" @keydown.enter="searchList"/></filterComponent>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list_top_button_content">
|
||||
<a-button class="primary_button btn-margin-r-20" type="primary" size="large" @click="searchList">Seach</a-button>
|
||||
<a-button class="default_button" size="large" @click="resetList">Reset</a-button>
|
||||
<a-button class="primary_button btn-margin-t-35" type="primary" size="large" @click="addStore()">+Add Store</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list_table_content">
|
||||
<a-table :columns="columns" :data-source="collectionList" @change="changePage" :loading="tableLoading"
|
||||
:pagination="{
|
||||
showSizeChanger:true,
|
||||
current: currentPage,
|
||||
pageSize:pageSize,
|
||||
total: total,
|
||||
showQuickJumper:true,
|
||||
bordered:false,
|
||||
pageSizeOptions:['10','20','50'],
|
||||
}">
|
||||
<template v-slot:bodyCell="{column,record, index}" >
|
||||
<template v-if="column.dataIndex === 'operation'">
|
||||
<div class="operate_list">
|
||||
<div class="operate_item" @click="editStore(record)">Edit</div>
|
||||
<div class="operate_item" @click="deleteStore(record,index)">Delete</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a-modal class="edit_modal_component"
|
||||
:destroyOnClose="true"
|
||||
v-model:visible="editStoreModal"
|
||||
:footer="null"
|
||||
:title="editStoreTitle"
|
||||
width="560px"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
@cancel="closeStore"
|
||||
>
|
||||
<a-form ref="formRef" :model="formState" :rules="rules" :layout="'vertical'" >
|
||||
<a-form-item label="Store Name" name="name">
|
||||
<a-input v-model:value="formState.name" size="large" placeholder="Please input store name"/>
|
||||
</a-form-item>
|
||||
<a-form-item label="Store Adress" name="address">
|
||||
<a-input v-model:value="formState.address" size="large" placeholder="Please select"/>
|
||||
</a-form-item>
|
||||
<a-form-item label="Remarks" name="remarks">
|
||||
<a-input v-model:value="formState.remarks" size="large" placeholder="Please input remarks"/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<div class="modal_button_list">
|
||||
<a-button class="default_button btn-margin-r-20" size="large" @click="closeStore">Cancel</a-button>
|
||||
<a-button class="primary_button" type="primary" size="large" @click="confirmSubmit">Submit</a-button>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent,ref,reactive,toRefs,UnwrapRef, onMounted,createVNode } from "vue";
|
||||
import filterComponent from '@/component/filterComponent.vue'
|
||||
import { message,Modal } from "ant-design-vue";
|
||||
import { formatTime } from "@/tool/util"
|
||||
import { Https } from "@/tool/https";
|
||||
import { useRoute } from 'vue-router'
|
||||
import { WarningOutlined } from '@ant-design/icons-vue';
|
||||
|
||||
export default defineComponent({
|
||||
name:'storeManage',
|
||||
components:{filterComponent},
|
||||
setup(){
|
||||
const route = useRoute()
|
||||
let filter = reactive({
|
||||
name:''
|
||||
})
|
||||
let columns = reactive([
|
||||
{ title: 'Store Id', align:'center', ellipsis: true, dataIndex: 'id', key: 'id' },
|
||||
{ title: 'Store Name', align:'center', ellipsis: true, dataIndex: 'name', key: 'name',
|
||||
},
|
||||
{ title: 'Store Adress', align:'center', ellipsis: true, dataIndex: 'address', key: 'address' },
|
||||
{ title: 'Remarks', align:'center', ellipsis: true, dataIndex: 'remarks', key: 'remarks' },
|
||||
{ title: 'Add Time', align:'center', ellipsis: true, dataIndex: 'createDate', key: 'createDate',customRender:(record:any)=>{
|
||||
let time = formatTime(record.text / 1000, 'YYYY-MM-DD hh:mm:ss')
|
||||
return time },
|
||||
},
|
||||
{
|
||||
title: 'Operations',
|
||||
key: 'operation',
|
||||
align:'center',
|
||||
fixed: 'right',
|
||||
width: 150,
|
||||
dataIndex:'operation',
|
||||
|
||||
},
|
||||
])
|
||||
let tableLoading = ref(false)
|
||||
let collectionList = ref([])
|
||||
let currentPage = ref(1)
|
||||
let pageSize = ref(10)
|
||||
let total = ref(0)
|
||||
let editStoreModal = ref(false)
|
||||
let editStoreTitle = ref('Add Store')
|
||||
let formRef = ref()
|
||||
let formState = ref({
|
||||
id: '',
|
||||
name: '',
|
||||
address:'',
|
||||
remarks:'',
|
||||
});
|
||||
let rules = {
|
||||
name: [
|
||||
{ required: true, message: 'Please input store name', trigger: 'blur' },
|
||||
],
|
||||
address: [
|
||||
{ required: true, message: 'Please input store address', trigger: 'blur' },
|
||||
],
|
||||
}
|
||||
|
||||
let changePage = (e:any) =>{
|
||||
currentPage.value = e.current
|
||||
pageSize.value = e.pageSize
|
||||
getStoreList()
|
||||
}
|
||||
|
||||
let closeStore = () =>{
|
||||
formState.value = {
|
||||
id: '',
|
||||
name: '',
|
||||
address:'',
|
||||
remarks:'',
|
||||
}
|
||||
editStoreModal.value = false
|
||||
}
|
||||
|
||||
let addStore = () =>{
|
||||
editStoreTitle.value = 'Add Store'
|
||||
editStoreModal.value = true
|
||||
}
|
||||
|
||||
let editStore = (data:any,) =>{
|
||||
editStoreModal.value = true
|
||||
editStoreTitle.value = 'Eidt Store'
|
||||
formState.value = {
|
||||
id: data.id,
|
||||
name: data.name,
|
||||
address:data.address,
|
||||
remarks:data.remarks,
|
||||
}
|
||||
}
|
||||
|
||||
let getStoreList = () =>{
|
||||
let data = {
|
||||
name : filter.name,
|
||||
page:currentPage.value,
|
||||
size:pageSize.value
|
||||
}
|
||||
tableLoading.value = true
|
||||
Https.axiosPost(Https.httpUrls.queryStorePage, data).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
tableLoading.value = false
|
||||
collectionList.value = rv.content
|
||||
total.value = rv.total
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let searchList = () =>{
|
||||
currentPage.value = 1
|
||||
getStoreList()
|
||||
}
|
||||
|
||||
let resetList = () =>{
|
||||
currentPage.value = 1
|
||||
filter.name = ''
|
||||
getStoreList()
|
||||
}
|
||||
|
||||
let confirmSubmit = () =>{
|
||||
let data = {
|
||||
...formState.value,
|
||||
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
}
|
||||
formRef.value.validate().then(()=>{
|
||||
submit()
|
||||
})
|
||||
let submit = () =>{
|
||||
Https.axiosPost(Https.httpUrls.sotreSaveOrEdit, data).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
let tip = !formState.value.id ? 'Store added successfully' :'Edit store successfully'
|
||||
message.success(tip)
|
||||
resetList()
|
||||
closeStore()
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let deleteStore = (data:any,index:any) => {
|
||||
let confirmDelete = (data:any,index:any) =>{
|
||||
let newData = {
|
||||
id:data.id
|
||||
}
|
||||
Https.axiosPost(Https.httpUrls.storeDelete, newData).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
message.success('Delete success')
|
||||
collectionList.value.splice(index,1)
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
Modal.confirm({
|
||||
title: 'Are you sure to delete the store?',
|
||||
icon: createVNode(WarningOutlined),
|
||||
class:'confirm_style',
|
||||
okText: 'Yes',
|
||||
cancelText: 'No',
|
||||
// centered:true,
|
||||
onOk() {
|
||||
confirmDelete(data,index)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if(route.query && route.query.type === 'add'){
|
||||
addStore()
|
||||
}
|
||||
getStoreList()
|
||||
})
|
||||
|
||||
return {
|
||||
...toRefs(filter),
|
||||
columns,
|
||||
collectionList,
|
||||
currentPage,
|
||||
tableLoading,
|
||||
pageSize,
|
||||
total,
|
||||
editStoreModal,
|
||||
editStoreTitle,
|
||||
formRef,
|
||||
formState,
|
||||
rules,
|
||||
changePage,
|
||||
closeStore,
|
||||
addStore,
|
||||
editStore,
|
||||
searchList,
|
||||
resetList,
|
||||
confirmSubmit,
|
||||
deleteStore
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.store_manage_page{
|
||||
padding-left: 28px;
|
||||
|
||||
.operate_list{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.operate_item{
|
||||
font-size: 14px;
|
||||
font-family: Roboto;
|
||||
font-weight: 400;
|
||||
color: #343579;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
469
src/views/childView/systemSetting/roleManage.vue
Normal file
469
src/views/childView/systemSetting/roleManage.vue
Normal file
@@ -0,0 +1,469 @@
|
||||
<template>
|
||||
<div class="role_manage_page list_page">
|
||||
<div class="list_page_content">
|
||||
<div class="list_top_content">
|
||||
<div class="list_top_search_content">
|
||||
<div class="search_content_left">
|
||||
<filterComponent :title="'Role Name or Id'"><a-input v-model:value="name" size="large" placeholder="Please input Role Name or Id" @keydown.enter="searchList()"/></filterComponent>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list_top_button_content">
|
||||
<a-button class="primary_button btn-margin-r-20" type="primary" size="large" @click="searchList()">Seach</a-button>
|
||||
<a-button class="default_button" size="large" @click="resetList()">Reset</a-button>
|
||||
<a-button class="primary_button btn-margin-t-35" type="primary" size="large" @click="addRole()">+Add Role</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list_table_content">
|
||||
<a-table :columns="columns" :data-source="collectionList" @change="changePage" :loading="tableLoading"
|
||||
:pagination="{
|
||||
showSizeChanger:true,
|
||||
current: currentPage,
|
||||
pageSize:pageSize,
|
||||
total: total,
|
||||
showQuickJumper:true,
|
||||
bordered:false,
|
||||
pageSizeOptions:['10','20','50'],
|
||||
}">
|
||||
<template v-slot:bodyCell="{column,record, index}" >
|
||||
<template v-if="column.dataIndex === 'operation'">
|
||||
<div class="operate_list">
|
||||
<div class="operate_item" @click="editRole(record)">Edit</div>
|
||||
<div class="operate_item" @click="deleteRole(record,index)">Delete</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a-modal class="edit_modal_component"
|
||||
v-model:visible="editRoleModal"
|
||||
:footer="null"
|
||||
:title="editRoleTitle"
|
||||
width="680px"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
@cancel="closeRole"
|
||||
>
|
||||
<a-form ref="formRef" :model="formState" :rules="rules" :layout="'vertical'" >
|
||||
<a-form-item label="Role Name" name="name">
|
||||
<a-input v-model:value="formState.name" size="large" placeholder="Please input role name"/>
|
||||
</a-form-item>
|
||||
<div>
|
||||
<div class="form_item_title required">Role Permission</div>
|
||||
<a-checkbox class="form_check_all" size="large" v-model:checked="permissionCheckAll" @change="perCheckAll">All</a-checkbox>
|
||||
<table class="permission_table">
|
||||
<tr v-for="(role) in rolePermission" :key="role.code">
|
||||
<td class="first_td">
|
||||
<div class="table_td_block"><a-checkbox size="large" v-model:checked="role.select" @change="checkLevelFirst(role)">{{role.resource}}</a-checkbox></div>
|
||||
</td>
|
||||
<td class="second_td">
|
||||
<div class="table_td_block" v-for="(menu) in role.level2ResourceList" :key="menu.code"><a-checkbox size="large" v-model:checked="menu.select" @change="checkLevelSec(role,menu)">{{menu.resource}}</a-checkbox></div>
|
||||
</td>
|
||||
<td class="third_td">
|
||||
<div class="table_td_block" v-for="(menu) in role.level2ResourceList" :key="menu.code">
|
||||
<div class="table_td_permission">
|
||||
<div v-for="(per) in menu.operationList" :key="per.code"><a-checkbox :disabled="!menu.select" size="large" v-model:checked="per.select">{{per.resource}}</a-checkbox></div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</a-form>
|
||||
<div class="modal_button_list">
|
||||
<a-button class="default_button btn-margin-r-20" size="large" @click="closeRole()">Cancel</a-button>
|
||||
<a-button class="primary_button" type="primary" size="large" @click="confirmSubmit()">Submit</a-button>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent,ref,reactive,toRefs,UnwrapRef,onMounted,createVNode } from "vue";
|
||||
import filterComponent from '@/component/filterComponent.vue'
|
||||
import { message,Modal } from "ant-design-vue";
|
||||
import { Https } from "@/tool/https";
|
||||
import { WarningOutlined } from '@ant-design/icons-vue';
|
||||
|
||||
export default defineComponent({
|
||||
name:'roleManage',
|
||||
components:{filterComponent},
|
||||
setup(){
|
||||
let filter = reactive({
|
||||
name:'',
|
||||
})
|
||||
let tableLoading = ref(false)
|
||||
let columns = reactive([
|
||||
{ title: 'Role Name', align:'center', ellipsis: true, dataIndex: 'name', key: 'name', width:250 },
|
||||
{ title: 'Role Permission', align:'center', ellipsis: true, dataIndex: 'permission', key: 'permission'},
|
||||
{
|
||||
title: 'Operations',
|
||||
key: 'operation',
|
||||
align:'center',
|
||||
fixed: 'right',
|
||||
width: 250,
|
||||
dataIndex:'operation',
|
||||
|
||||
},
|
||||
])
|
||||
let collectionList = ref([])
|
||||
let currentPage = ref(1)
|
||||
let pageSize = ref(10)
|
||||
let total = ref(1)
|
||||
let editRoleModal = ref(false)
|
||||
let editRoleTitle = ref('Add Role')
|
||||
let permissionCheckAll=ref(false)
|
||||
let rolePermission:any = ref([])
|
||||
let backupRolePermission:any = ref([])
|
||||
let formRef = ref();
|
||||
let formState = ref({
|
||||
id: '',
|
||||
name: '',
|
||||
});
|
||||
let rules = {
|
||||
name: [
|
||||
{ required: true, message: 'Please input role name', trigger: 'blur' },
|
||||
],
|
||||
roleType: [
|
||||
{ required: true, message: '', trigger: 'blur' },
|
||||
],
|
||||
}
|
||||
|
||||
let changePage = (e:any) =>{
|
||||
currentPage.value = e.current
|
||||
pageSize.value = e.pageSize
|
||||
getRoleList()
|
||||
}
|
||||
|
||||
let closeRole = () =>{
|
||||
formState.value = {
|
||||
id: '',
|
||||
name: '',
|
||||
}
|
||||
permissionCheckAll.value = false
|
||||
rolePermission.value = JSON.parse(JSON.stringify(backupRolePermission.value))
|
||||
editRoleModal.value = false
|
||||
}
|
||||
|
||||
let addRole = () =>{
|
||||
editRoleTitle.value = 'Add Role'
|
||||
editRoleModal.value = true
|
||||
}
|
||||
|
||||
let editRole = (data:any,) =>{
|
||||
editRoleModal.value = true
|
||||
editRoleTitle.value = 'Eidt Role'
|
||||
formState.value = {
|
||||
id: data.id,
|
||||
name: data.name,
|
||||
}
|
||||
rolePermission.value = changeSelectBoolean(data.rolePermission.level1ResourceList)
|
||||
permissionCheckAll.value = data.rolePermission.allSelect
|
||||
}
|
||||
|
||||
let getRoleList = () =>{
|
||||
let data = {
|
||||
name : filter.name,
|
||||
page:currentPage.value,
|
||||
size:pageSize.value
|
||||
}
|
||||
tableLoading.value = true
|
||||
Https.axiosPost(Https.httpUrls.roleQueryRolePage, data).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
tableLoading.value = false
|
||||
collectionList.value = rv.content.map((v:any) =>{
|
||||
let data = {
|
||||
...v,
|
||||
permission:v.rolePermission.level1ResourceList.filter((v:any)=>v.select).map((per:any) => per.resource).join('、')
|
||||
}
|
||||
return data
|
||||
})
|
||||
total.value = rv.total
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let getMenuListPer = () =>{
|
||||
Https.axiosGet(Https.httpUrls.roleQueryPermissionList).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
rolePermission.value = changeSelectBoolean(rv)
|
||||
backupRolePermission.value = changeSelectBoolean(rv)
|
||||
console.log(rolePermission.value);
|
||||
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let changeSelectBoolean = (data:any) =>{
|
||||
let newData = JSON.parse(JSON.stringify(data))
|
||||
for(let first of newData){
|
||||
first.select = changeBooleanNumber(first.select)
|
||||
for(let sec of first.level2ResourceList){
|
||||
sec.select = changeBooleanNumber(sec.select)
|
||||
for(let third of sec.operationList){
|
||||
third.select = changeBooleanNumber(third.select)
|
||||
}
|
||||
}
|
||||
}
|
||||
return newData
|
||||
}
|
||||
|
||||
//判断是布尔值则转为数字,数字则转布尔值
|
||||
let changeBooleanNumber = (data:any) => {
|
||||
let newData = data
|
||||
if(newData.constructor === Boolean){
|
||||
newData = newData ? 1 :0
|
||||
}else{
|
||||
newData = newData ? true :false
|
||||
}
|
||||
return newData
|
||||
}
|
||||
|
||||
let searchList = () =>{
|
||||
currentPage.value = 1
|
||||
getRoleList()
|
||||
}
|
||||
|
||||
let resetList = () =>{
|
||||
currentPage.value = 1
|
||||
filter.name = ''
|
||||
getRoleList()
|
||||
}
|
||||
|
||||
|
||||
let deleteRole = (data:any,index:any) =>{
|
||||
let confirmDelete = (data:any,index:any) =>{
|
||||
let newData = {
|
||||
id:data.id
|
||||
}
|
||||
Https.axiosPost(Https.httpUrls.roleDelete, newData).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
message.success('Delete success')
|
||||
collectionList.value.splice(index,1)
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
Modal.confirm({
|
||||
title: "Are you sure delete the role?",
|
||||
icon: createVNode(WarningOutlined),
|
||||
class:'confirm_style',
|
||||
okText: 'Ok',
|
||||
cancelText: 'Cancel',
|
||||
// centered:true,
|
||||
onOk() {
|
||||
confirmDelete(data,index)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let perCheckAll = () =>{
|
||||
for(let first of rolePermission.value){
|
||||
first.select = permissionCheckAll.value
|
||||
for(let sec of first.level2ResourceList){
|
||||
sec.select = permissionCheckAll.value
|
||||
for(let third of sec.operationList){
|
||||
third.select = permissionCheckAll.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let checkLevelFirst = (firstDdata:any) =>{
|
||||
for(let sec of firstDdata.level2ResourceList){
|
||||
sec.select = firstDdata.select
|
||||
for(let third of sec.operationList){
|
||||
third.select = firstDdata.select
|
||||
}
|
||||
}
|
||||
checkIsAllPer()
|
||||
}
|
||||
|
||||
let checkLevelSec = (firstData:any, secondData:any) =>{
|
||||
for(let third of secondData.operationList){
|
||||
third.select = secondData.select
|
||||
}
|
||||
let status = false
|
||||
for(let item of firstData.level2ResourceList){
|
||||
if(item.select){
|
||||
status = true
|
||||
break
|
||||
}
|
||||
}
|
||||
firstData.select = status
|
||||
checkIsAllPer()
|
||||
}
|
||||
|
||||
//判断是否已经全部勾选
|
||||
let checkIsAllPer = () =>{
|
||||
let status = true
|
||||
for(let first of rolePermission.value){
|
||||
if(!first.select){
|
||||
status = false
|
||||
break
|
||||
}
|
||||
for(let sec of first.level2ResourceList){
|
||||
if(!sec.select){
|
||||
status = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if(!status){break}
|
||||
}
|
||||
permissionCheckAll.value = status
|
||||
}
|
||||
|
||||
let confirmSubmit = () =>{
|
||||
let data = {
|
||||
...formState.value,
|
||||
rolePermission:{
|
||||
allSelect:permissionCheckAll.value ? 1 : 0,
|
||||
level1ResourceList:changeSelectBoolean(rolePermission.value)
|
||||
},
|
||||
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
}
|
||||
formRef.value.validate().then(()=>{
|
||||
let status = false
|
||||
for(let first of rolePermission.value){
|
||||
if(first.select){
|
||||
status = true
|
||||
break
|
||||
}
|
||||
for(let sec of first.level2ResourceList){
|
||||
if(sec.select){
|
||||
status = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if(status){break}
|
||||
}
|
||||
if(!status){
|
||||
message.error('Please check role permission')
|
||||
return
|
||||
}
|
||||
submit()
|
||||
})
|
||||
let submit = () => {
|
||||
Https.axiosPost(Https.httpUrls.roleSaveOrEdit, data).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
let tip = !formState.value.id ? 'Role added successfully' :'Edit role successfully'
|
||||
message.success(tip)
|
||||
resetList()
|
||||
closeRole()
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getRoleList()
|
||||
getMenuListPer()
|
||||
})
|
||||
|
||||
|
||||
return {
|
||||
...toRefs(filter),
|
||||
tableLoading,
|
||||
columns,
|
||||
collectionList,
|
||||
currentPage,
|
||||
pageSize,
|
||||
total,
|
||||
permissionCheckAll,
|
||||
rolePermission,
|
||||
editRoleModal,
|
||||
editRoleTitle,
|
||||
formRef,
|
||||
formState,
|
||||
rules,
|
||||
changePage,
|
||||
closeRole,
|
||||
addRole,
|
||||
editRole,
|
||||
searchList,
|
||||
resetList,
|
||||
deleteRole,
|
||||
perCheckAll,
|
||||
checkLevelFirst,
|
||||
checkLevelSec,
|
||||
confirmSubmit,
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.role_manage_page{
|
||||
padding-left: 28px;
|
||||
|
||||
.role_pic{
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.operate_list{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0 50px;
|
||||
|
||||
.operate_item{
|
||||
font-size: 14px;
|
||||
font-family: Roboto;
|
||||
font-weight: 400;
|
||||
color: #343579;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form_check_all{
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.permission_table{
|
||||
width: 100%;
|
||||
margin-top: 10px;
|
||||
border-left:1px solid #DFDFDF;
|
||||
border-top:1px solid #DFDFDF;
|
||||
|
||||
td{
|
||||
border-bottom: 1px solid #DFDFDF;
|
||||
border-right: 1px solid #DFDFDF;
|
||||
|
||||
.table_td_block{
|
||||
padding: 16px 0 16px 20px;
|
||||
border-bottom: 1px solid #DFDFDF;
|
||||
|
||||
&:last-child{
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
.table_td_permission{
|
||||
display: flex;
|
||||
min-height: 23px;
|
||||
}
|
||||
}
|
||||
|
||||
.first_td{
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.second_td{
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
513
src/views/childView/systemSetting/userManage.vue
Normal file
513
src/views/childView/systemSetting/userManage.vue
Normal file
@@ -0,0 +1,513 @@
|
||||
<template>
|
||||
<div class="user_manage_page list_page">
|
||||
<div class="list_page_content">
|
||||
<div class="list_top_content">
|
||||
<div class="list_top_search_content">
|
||||
<div class="search_content_left">
|
||||
<filterComponent :title="'User Name'"><a-input v-model:value="userName" size="large" placeholder="Please input User Name" @keydown.enter="searchList()"/></filterComponent>
|
||||
<filterComponent :title="'User Phone'"><a-input v-model:value="userPhone" size="large" placeholder="Please input User Phone" @keydown.enter="searchList()" /></filterComponent>
|
||||
<filterComponent :title="'User Role'">
|
||||
<a-select v-model:value="roleId" size="large" style="width:280px" placeholder="Please select" :options="userRoleList" allowClear></a-select>
|
||||
</filterComponent>
|
||||
<filterComponent :title="'User State'">
|
||||
<a-select v-model:value="state" size="large" style="width:280px" placeholder="Please select" :options="userStateList" allowClear></a-select>
|
||||
</filterComponent>
|
||||
<filterComponent :title="'Add Time'"><a-range-picker v-model:value="addTime" size="large" :placeholder="['Start Time', 'End Time']" format="YYYY-MM-DD" valueFormat="YYYY-MM-DD"/></filterComponent>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list_top_button_content">
|
||||
<a-button class="primary_button btn-margin-r-20" type="primary" size="large" @click="searchList()">Seach</a-button>
|
||||
<a-button class="default_button" size="large" @click="resetList()">Reset</a-button>
|
||||
<a-button class="primary_button btn-margin-t-35" type="primary" size="large" @click="addUser()">+Add User</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list_table_content">
|
||||
<a-table :columns="columns" :data-source="collectionList" @change="changePage" :loading="tableLoading"
|
||||
:pagination="{
|
||||
showSizeChanger:true,
|
||||
current: currentPage,
|
||||
pageSize:pageSize,
|
||||
total: total,
|
||||
showQuickJumper:true,
|
||||
bordered:false,
|
||||
pageSizeOptions:['10','20','50'],
|
||||
}">
|
||||
<template v-slot:bodyCell="{column,record, index}" >
|
||||
<template v-if="column.dataIndex === 'stateName'">
|
||||
<div :class="['state_name_block', record.state == 1 ? 'enable_state' :'disable_state']">
|
||||
<div class="state_round"></div>
|
||||
<div>{{record.stateName}}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'operation'">
|
||||
<div class="operate_list">
|
||||
<div class="operate_item" @click="editUser(record)">Edit</div>
|
||||
<div :class="['operate_item', record.state == 0 ? '' :'operate_disable_state']" @click="enableUser(record,index)">
|
||||
<div v-if="record.state == 0">Enable</div>
|
||||
<div v-else>Disable</div>
|
||||
</div>
|
||||
<div class="operate_item" @click="deleteUser(record,index)">Delete</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a-modal class="edit_modal_component"
|
||||
:destroyOnClose="true"
|
||||
v-model:visible="editUserModal"
|
||||
:footer="null"
|
||||
:title="editUserTitle"
|
||||
width="680px"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
@cancel="closeUser"
|
||||
>
|
||||
<a-form ref="formRef" :model="formState" :rules="rules" :layout="'vertical'" >
|
||||
<a-row :gutter="[16,16]">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="User Name" name="userName">
|
||||
<a-input v-model:value="formState.userName" size="large" placeholder="Please input user name"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="User Account" name="userAccount">
|
||||
<a-input v-model:value="formState.userAccount" size="large" placeholder="Please input user account"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="[16,16]">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="User Code" name="userPassword">
|
||||
<a-input v-model:value="formState.userPassword" size="large" placeholder="Please input user code" type="password"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="User Phone" name="userPhone">
|
||||
<a-input v-model:value="formState.userPhone" size="large" placeholder="Please input user phone"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="[16,16]">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="App User" name="appUser">
|
||||
<a-select v-model:value="formState.appUser" size="large" :options="appUserList" placeholder="Please select"></a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="User Role" name="roleId">
|
||||
<a-select v-model:value="formState.roleId" size="large" :options="userRoleList" placeholder="Please select"></a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="[16,16]">
|
||||
<a-col :span="24">
|
||||
<a-form-item label="Owner Store" name="storeIds">
|
||||
<a-select v-model:value="formState.storeIds" size="large" :options="ownerStoreList" mode="multiple" placeholder="Please select"></a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="[16,16]">
|
||||
<a-col :span="24">
|
||||
<a-form-item label ="Remarks" name="remarks">
|
||||
<a-input v-model:value="formState.remarks" size="large" placeholder="Please input remarks"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
<div class="modal_button_list">
|
||||
<a-button class="default_button btn-margin-r-20" size="large" @click="closeUser">Cancel</a-button>
|
||||
<a-button class="primary_button" type="primary" size="large" @click="confirmSubmit">Submit</a-button>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent,ref,reactive,toRefs,UnwrapRef,onMounted,createVNode } from "vue";
|
||||
import filterComponent from '@/component/filterComponent.vue'
|
||||
import { Moment } from 'moment';
|
||||
import { message,Modal } from "ant-design-vue";
|
||||
import { Https } from "@/tool/https";
|
||||
import { WarningOutlined } from '@ant-design/icons-vue';
|
||||
import { encode, decode } from 'js-base64';
|
||||
import { useRoute } from 'vue-router'
|
||||
import { formatTime, startTime, endTime } from "@/tool/util"
|
||||
|
||||
export default defineComponent({
|
||||
name:'userManage',
|
||||
components:{filterComponent},
|
||||
setup(){
|
||||
const route = useRoute()
|
||||
let filter:any = reactive({
|
||||
userName:'',
|
||||
userPhone:'',
|
||||
roleId:[],
|
||||
state:[],
|
||||
addTime:ref<Moment[]>([]),
|
||||
})
|
||||
let tableLoading = ref(false)
|
||||
let userRoleList:any = ref([])
|
||||
let userStateList:any = ref([
|
||||
{value:'1',label:'Activated'},
|
||||
{value:'0',label:'Deactivated'},
|
||||
])
|
||||
let appUserList:any = ref([
|
||||
{value:1,label:'Yes'},
|
||||
{value:0,label:'No'},
|
||||
])
|
||||
let ownerStoreList:any = ref([])
|
||||
let columns = reactive([
|
||||
{ title: 'User Name', align:'center', ellipsis: true, dataIndex: 'userName', key: 'userName' },
|
||||
{ title: 'User Account', align:'center', ellipsis: true, dataIndex: 'userAccount', key: 'userAccount'},
|
||||
{ title: 'Add Role', align:'center', ellipsis: true, dataIndex: 'roleName', key: 'roleName' },
|
||||
{ title: 'User Phone', align:'center', ellipsis: true, dataIndex: 'userPhone', key: 'userPhone' },
|
||||
{ title: 'Owned Store', align:'center', ellipsis: true, dataIndex: 'storeName', key: 'storeName',customRender:(record:any)=>{
|
||||
let storeNameNew = record.text.join(',')
|
||||
return storeNameNew
|
||||
}
|
||||
},
|
||||
{ title: 'Add Time', align:'center', ellipsis: true, dataIndex: 'createDate', key: 'createDate' ,customRender:(record:any)=>{
|
||||
let time = formatTime(record.text / 1000, 'YYYY-MM-DD hh:mm:ss')
|
||||
return time
|
||||
},
|
||||
},
|
||||
{ title: 'Activated', align:'center', ellipsis: true, dataIndex: 'appUserName', key: 'appUserName' },
|
||||
{ title: 'User State', align:'center', ellipsis: true, dataIndex: 'stateName', key: 'stateName' },
|
||||
{
|
||||
title: 'Operations',
|
||||
key: 'operation',
|
||||
align:'center',
|
||||
fixed: 'right',
|
||||
width: 150,
|
||||
dataIndex:'operation',
|
||||
|
||||
},
|
||||
])
|
||||
let collectionList:any = ref([])
|
||||
let currentPage = ref(1)
|
||||
let pageSize = ref(10)
|
||||
let total = ref(1)
|
||||
let editUserModal = ref(false)
|
||||
let editUserTitle = ref('Add user')
|
||||
let formRef = ref();
|
||||
let formState:any = ref({
|
||||
id: '',
|
||||
userName: '',
|
||||
userAccount: '',
|
||||
userPassword:'',
|
||||
userPhone:'',
|
||||
appUser:null,
|
||||
roleId:null,
|
||||
storeIds:[],
|
||||
remarks:'',
|
||||
});
|
||||
let rules = {
|
||||
userName: [
|
||||
{ required: true, message: 'Please input user name', trigger: 'blur' },
|
||||
],
|
||||
userAccount: [
|
||||
{ required: true, message: 'Please input user account', trigger: 'blur' },
|
||||
{ min: 6, max: 20, message: 'Length should be 6 to 20', trigger: 'blur' },
|
||||
],
|
||||
userPassword: [
|
||||
{ required: true, message: 'Please input user code', trigger: 'blur' },
|
||||
{ min: 6, max: 20, message: 'Length should be 6 to 20', trigger: 'blur' },
|
||||
],
|
||||
userPhone: [
|
||||
{ required: true, message: 'Please input user phone', trigger: 'blur' },
|
||||
{ pattern: /^\d*$/, message: 'The format of the mobile phone number is incorrect', trigger: 'blur' },
|
||||
],
|
||||
appUser: [
|
||||
{ required: true, message: 'Please select app user', trigger: 'blur' },
|
||||
],
|
||||
userRole: [
|
||||
{ required: true, message: 'Please select user role', trigger: 'blur' },
|
||||
],
|
||||
ownerStore: [
|
||||
{ required: true, message: 'Please select owner store', trigger: 'blur' },
|
||||
],
|
||||
}
|
||||
|
||||
let changePage = (e:any) =>{
|
||||
currentPage.value = e.current
|
||||
pageSize.value = e.pageSize
|
||||
getUserlist()
|
||||
}
|
||||
|
||||
let closeUser = () =>{
|
||||
formState.value = {
|
||||
id: '',
|
||||
userName: '',
|
||||
userAccount: '',
|
||||
userPassword:'',
|
||||
userPhone:'',
|
||||
appUser:null,
|
||||
roleId:null,
|
||||
storeIds:[],
|
||||
remarks:'',
|
||||
}
|
||||
editUserModal.value = false
|
||||
}
|
||||
|
||||
let addUser = () =>{
|
||||
editUserTitle.value = 'Add user'
|
||||
editUserModal.value = true
|
||||
}
|
||||
|
||||
let editUser = (data:any,) =>{
|
||||
editUserModal.value = true
|
||||
editUserTitle.value = 'Eidt user'
|
||||
formState.value = {
|
||||
id: data.id,
|
||||
userName: data.userName,
|
||||
userAccount:data.userAccount,
|
||||
userPassword:data.userPassword ? decode(data.userPassword) : '',
|
||||
userPhone:data.userPhone,
|
||||
appUser:data.appUser,
|
||||
roleId:String(data.roleId),
|
||||
storeIds:data.storeIds,
|
||||
remarks:data.remarks,
|
||||
}
|
||||
}
|
||||
|
||||
let getUserlist = () =>{
|
||||
let data = {
|
||||
userName : filter.userName,
|
||||
userPhone:filter.userPhone,
|
||||
state:filter.state && filter.state.length ? filter.state : '',
|
||||
roleId:filter.roleId && filter.roleId.length ? filter.roleId : '',
|
||||
createDateStart:filter.addTime && filter.addTime.length ? startTime(filter.addTime[0]) :'',
|
||||
createDateEnd:filter.addTime && filter.addTime.length ? endTime(filter.addTime[1]) :'',
|
||||
page:currentPage.value,
|
||||
size:pageSize.value
|
||||
}
|
||||
tableLoading.value = true
|
||||
Https.axiosPost(Https.httpUrls.accountQueryUserPage, data).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
tableLoading.value = false
|
||||
collectionList.value = rv.content
|
||||
total.value = rv.total
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let getRolelist = () =>{
|
||||
Https.axiosPost(Https.httpUrls.roleQueryAll, {}).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
userRoleList.value = rv.map((v:any)=>{
|
||||
let data = {
|
||||
...v,
|
||||
value:v.id,
|
||||
label:v.name
|
||||
}
|
||||
return data
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let searchList = () =>{
|
||||
currentPage.value = 1
|
||||
getUserlist()
|
||||
}
|
||||
|
||||
let resetList = () =>{
|
||||
currentPage.value = 1
|
||||
filter.userName = ''
|
||||
filter.userPhone = ''
|
||||
filter.roleId = []
|
||||
filter.state = []
|
||||
filter.addTime = ref<Moment[]>([])
|
||||
getUserlist()
|
||||
}
|
||||
|
||||
let confirmSubmit = () =>{
|
||||
let data = {
|
||||
...formState.value,
|
||||
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
}
|
||||
data.userPassword = encode(data.userPassword)
|
||||
let submit = () =>{
|
||||
Https.axiosPost(Https.httpUrls.accountSaveOrEdit, data).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
let tip = !formState.value.id ? 'User added successfully' :'Edit user successfully'
|
||||
message.success(tip)
|
||||
resetList()
|
||||
closeUser()
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
formRef.value.validate().then(()=>{
|
||||
submit()
|
||||
})
|
||||
}
|
||||
|
||||
let enableUser = (record:any,index:any) =>{
|
||||
let data ={
|
||||
id:record.id,
|
||||
enable:record.state == 1 ? 0 : 1
|
||||
}
|
||||
Https.axiosPost(Https.httpUrls.accountEnable, data).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
let tip = record.state == 0? 'Enable successfully' :'Disable successfully'
|
||||
message.success(tip)
|
||||
collectionList.value[index].state = data.enable
|
||||
collectionList.value[index].stateName = data.enable == 1 ? 'Activated' :'Deactivated'
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let deleteUser = (data:any,index:any) =>{
|
||||
let confirmDelete = (data:any,index:any) =>{
|
||||
let newData = {
|
||||
id:data.id
|
||||
}
|
||||
Https.axiosPost(Https.httpUrls.accountDelete, newData).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
message.success('Delete success')
|
||||
collectionList.value.splice(index,1)
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
Modal.confirm({
|
||||
title: "Are you sure delete the user?",
|
||||
icon: createVNode(WarningOutlined),
|
||||
class:'confirm_style',
|
||||
okText: 'Ok',
|
||||
cancelText: 'Cancel',
|
||||
// centered:true,
|
||||
onOk() {
|
||||
confirmDelete(data,index)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let storeQueryAll = () =>{
|
||||
Https.axiosPost(Https.httpUrls.storeQueryAll,{}).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
ownerStoreList.value = rv.map((v:any)=>{
|
||||
let data = {
|
||||
...v,
|
||||
value:v.id,
|
||||
label:v.name
|
||||
}
|
||||
return data
|
||||
})
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if(route.query && route.query.type === 'add'){
|
||||
addUser()
|
||||
}
|
||||
getUserlist()
|
||||
storeQueryAll()
|
||||
getRolelist()
|
||||
})
|
||||
|
||||
|
||||
return {
|
||||
...toRefs(filter),
|
||||
tableLoading,
|
||||
userRoleList,
|
||||
userStateList,
|
||||
appUserList,
|
||||
ownerStoreList,
|
||||
columns,
|
||||
collectionList,
|
||||
currentPage,
|
||||
pageSize,
|
||||
total,
|
||||
editUserModal,
|
||||
editUserTitle,
|
||||
formRef,
|
||||
formState,
|
||||
rules,
|
||||
changePage,
|
||||
closeUser,
|
||||
addUser,
|
||||
editUser,
|
||||
searchList,
|
||||
resetList,
|
||||
confirmSubmit,
|
||||
enableUser,
|
||||
deleteUser
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.user_manage_page{
|
||||
padding-left: 28px;
|
||||
|
||||
.user_pic{
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.state_name_block{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
justify-content: center;
|
||||
|
||||
&.enable_state{
|
||||
color: #47E417;
|
||||
|
||||
.state_round{
|
||||
background: #47E417;
|
||||
}
|
||||
}
|
||||
|
||||
&.disable_state{
|
||||
color: #E41335;
|
||||
|
||||
.state_round{
|
||||
background: #E41335;
|
||||
}
|
||||
}
|
||||
|
||||
.state_round{
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 50%;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.operate_list{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.operate_item{
|
||||
font-size: 14px;
|
||||
font-family: Roboto;
|
||||
font-weight: 400;
|
||||
color: #343579;
|
||||
cursor: pointer;
|
||||
|
||||
&.operate_disable_state{
|
||||
color: #E41335;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
265
src/views/childView/worktable.vue
Normal file
265
src/views/childView/worktable.vue
Normal file
@@ -0,0 +1,265 @@
|
||||
<template>
|
||||
<div class="worktable_page">
|
||||
<div class="worktable_top_info">
|
||||
<img class="worktable_logo" src="@/assets/images/worktable_logo.png">
|
||||
<div class="worktable_top_left">
|
||||
<div class="top_left_header">{{nowHours > 12 ? 'Afternoon':'Morning'}},{{userName}}.Have a nice day!</div>
|
||||
<div class="work_user_info"><span class="user_info_margin">{{roleName}}</span><span class="user_info_margin">|</span><span>{{storeAddress}}{{storeName}}</span></div>
|
||||
</div>
|
||||
<div class="work_statistical_data_list">
|
||||
<div class="work_statistical_data_item">
|
||||
<div class="work_statistical_data_title">Store(s)</div>
|
||||
<div class="work_statistical_data_num color_FF6D60">{{storeCount}}</div>
|
||||
</div>
|
||||
<div class="work_statistical_data_item">
|
||||
<div class="work_statistical_data_title">Product(s)</div>
|
||||
<div class="work_statistical_data_num color_0CB4B3">{{onSaleProductCount}}</div>
|
||||
</div>
|
||||
<div class="work_statistical_data_item">
|
||||
<div class="work_statistical_data_title">Order(s)</div>
|
||||
<div class="work_statistical_data_num color_FEAD75">{{orderSuccessCount}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="worktable_content">
|
||||
<div class="worktable_content_header">
|
||||
<span class="icon iconfont icon-a-gengduocaidangongneng"></span>
|
||||
<div>Quick access</div>
|
||||
</div>
|
||||
<div class="worktable_content_entry_list">
|
||||
<div class="worktable_content_entry_item" @click="turnToPage({path:'/home/productmanage',type:''})" v-if="buttonShow.PRODUCT_LIST">
|
||||
<img class="entry_bg" src="@/assets/images/green_bg.png">
|
||||
<div class="entry_name">Product List</div>
|
||||
</div>
|
||||
<div class="worktable_content_entry_item" @click="turnToPage({path:'/home/productmanage',type:'add'})" v-if="buttonShow.PRODUCT_LIST">
|
||||
<img class="entry_bg" src="@/assets/images/purple_bg.png">
|
||||
<div class="entry_name">Add Product</div>
|
||||
</div>
|
||||
<div class="worktable_content_entry_item" @click="turnToPage({path:'/home/storemanage',type:''})" v-if="buttonShow.STORE_LIST">
|
||||
<img class="entry_bg" src="@/assets/images/pink_bg.png">
|
||||
<div class="entry_name">Store List</div>
|
||||
</div>
|
||||
<div class="worktable_content_entry_item" @click="turnToPage({path:'/home/storemanage',type:'add'})" v-if="buttonShow.STORE_LIST">
|
||||
<img class="entry_bg" src="@/assets/images/orange_bg.png">
|
||||
<div class="entry_name">Add Store</div>
|
||||
</div>
|
||||
<div class="worktable_content_entry_item" @click="turnToPage({path:'/home/usermanage',type:'add'})" v-if="buttonShow.USER_MANAGER">
|
||||
<img class="entry_bg" src="@/assets/images/blue_bg.png">
|
||||
<div class="entry_name">Add User</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent,reactive,ref,toRefs,onMounted } from "vue";
|
||||
import { message } from "ant-design-vue";
|
||||
import { useRouter,useRoute } from 'vue-router'
|
||||
import { Https } from "@/tool/https";
|
||||
|
||||
|
||||
export default defineComponent({
|
||||
name:'worktable',
|
||||
setup(){
|
||||
const router = useRouter()
|
||||
const workData = reactive({
|
||||
userName:'',
|
||||
roleName:'',
|
||||
storeAddress:'',
|
||||
storeName:'',
|
||||
storeCount:0,
|
||||
onSaleProductCount:0,
|
||||
orderSuccessCount:0,
|
||||
})
|
||||
let userInfo:any = ref({})
|
||||
let buttonShow:any = reactive({
|
||||
PRODUCT_LIST:false,
|
||||
STORE_LIST:false,
|
||||
USER_MANAGER:false,
|
||||
})
|
||||
let nowHours = ref(0)
|
||||
|
||||
const turnToPage = (data:any) =>{
|
||||
router.push({path:data.path,query:data.type?{type:data.type}:{}})
|
||||
}
|
||||
|
||||
const getWorkData = () =>{
|
||||
Https.axiosGet(Https.httpUrls.countWorkBench).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
workData.userName = rv.userName
|
||||
workData.roleName = rv.roleName
|
||||
workData.storeAddress = rv.storeAddress
|
||||
workData.storeName = rv.storeName
|
||||
workData.storeCount = rv.storeCount
|
||||
workData.onSaleProductCount = rv.onSaleProductCount
|
||||
workData.orderSuccessCount = rv.orderSuccessCount
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const getButtonRole = (menuList:any) =>{
|
||||
let keyList = ['PRODUCT_LIST',"STORE_LIST","USER_MANAGER"]
|
||||
for(let item of menuList){
|
||||
if(!item.children){
|
||||
if(keyList.includes(item.code)){
|
||||
buttonShow[item.code] = item.isShow
|
||||
}
|
||||
}else{
|
||||
getButtonRole(item.children)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
let menuList:any = sessionStorage.getItem('menuList')
|
||||
menuList = JSON.parse(menuList)
|
||||
let date = new Date()
|
||||
nowHours.value = date.getHours()
|
||||
getButtonRole(menuList)
|
||||
getWorkData()
|
||||
})
|
||||
|
||||
|
||||
|
||||
return {
|
||||
turnToPage,
|
||||
...toRefs(workData),
|
||||
userInfo,
|
||||
buttonShow,
|
||||
nowHours,
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.worktable_page{
|
||||
padding-left: 28px;
|
||||
|
||||
.worktable_top_info{
|
||||
background: #fff;
|
||||
height: 120px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-left: 117px;
|
||||
position: relative;
|
||||
margin-bottom: 30px;
|
||||
|
||||
.worktable_logo{
|
||||
width: 100px;
|
||||
height: 96px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.top_left_header{
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
color: #333333;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.work_user_info{
|
||||
font-size: 16px;
|
||||
color: #A0A1A6;
|
||||
|
||||
.user_info_margin{
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.work_statistical_data_list{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.work_statistical_data_item{
|
||||
padding: 8px 40px 0;
|
||||
height: 60px;
|
||||
border-right:1px solid #E7E7E7;
|
||||
|
||||
:last-child{
|
||||
border: none;
|
||||
}
|
||||
|
||||
.work_statistical_data_title{
|
||||
font-size: 16px;
|
||||
line-height: 16px;
|
||||
color: #333333;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.work_statistical_data_num{
|
||||
font-size: 24px;
|
||||
line-height: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
.color_FF6D60{
|
||||
color: #FF6D60;
|
||||
}
|
||||
.color_0CB4B3{
|
||||
color: #0CB4B3;
|
||||
}
|
||||
.color_FEAD75{
|
||||
color: #FEAD75;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.worktable_content{
|
||||
padding: 20px 25px 30px;
|
||||
background: #fff;
|
||||
|
||||
.worktable_content_header{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
margin-bottom: 40px;
|
||||
|
||||
.icon-a-gengduocaidangongneng{
|
||||
font-size: 24px;
|
||||
color: #80B8F8;
|
||||
margin-right: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.worktable_content_entry_list{
|
||||
display: flex;
|
||||
|
||||
|
||||
.worktable_content_entry_item{
|
||||
position: relative;
|
||||
width: 200px;
|
||||
height: 114px;
|
||||
padding-left: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
margin-right: 20px;
|
||||
|
||||
.entry_bg{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.entry_name{
|
||||
color: #fff;
|
||||
z-index: 2;
|
||||
font-size: 19px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user