<template> <div class="com-main com-margin-auto com-fixationwidth-1400"> <el-breadcrumb separator-class="el-icon-arrow-right"> <el-breadcrumb-item :to="{ path: '/' }">Home</el-breadcrumb-item> <el-breadcrumb-item>{{ tabName }}</el-breadcrumb-item> </el-breadcrumb> <div class="content"> <el-menu background-color="#e8eaee" text-color="#4a596c" ref="menu" active-text-color="#fff" class="el-menu-vertical" :default-active="activeMenu" @select="handleClick"> <el-menu-item index="profile"> <i class="iconfont"></i> <span slot="title">My Profile</span> </el-menu-item> <!-- <el-menu-item index="enquiry"> <i class="iconfont"></i> <span slot="title">My Enquiry</span> </el-menu-item> --> <!-- <el-menu-item index="address"> <i class="iconfont"></i> <span slot="title">My Addresses</span> </el-menu-item> --> <el-submenu index="order"> <template slot="title"> <i class="iconfont"></i> <span slot="title">My Orders</span> </template> <el-menu-item index="all-orders">All Orders</el-menu-item> <el-menu-item index="open-orders">Open Orders</el-menu-item> <el-menu-item index="closed-orders">Closed Orders</el-menu-item> </el-submenu> <!-- <el-menu-item index="account"> <i class="iconfont"></i> <span slot="title">Account And Password</span> </el-menu-item> --> </el-menu> <div class="content-right"> <div v-show="activeMenu === 'profile'"> <div class="content-form"> <p class="content-title">{{ tabName }}</p> <el-form ref="form" :model="profileform" :rules="rules" label-width="220px"> <el-row> <el-col :span="15"> <el-form-item label="Email Address" prop="email"> <el-input v-model="profileform.email" :disabled="true"></el-input> </el-form-item> </el-col> <el-col :span="9"> <el-form-item class='upload-item' label="Your Logo"> <image-upload :list.sync="profileform.logo" :disablePreview="true" :max="1"></image-upload> </el-form-item> </el-col> </el-row> <el-form-item label="Company Name" prop="company"> <el-input v-model="profileform.company"></el-input> </el-form-item> <el-form-item label="First Name" prop="contacts"> <el-input v-model="profileform.contacts"></el-input> </el-form-item> <el-form-item label="Last Name" prop="last_name"> <el-input v-model="profileform.last_name"></el-input> </el-form-item> <el-form-item label="Contact Phone Number" prop="phone"> <el-input v-model="profileform.phone"></el-input> </el-form-item> <!-- <el-form-item> <el-button class="saveBtn" @click="onSave('form')" >Save</el-button> </el-form-item> --> </el-form> </div> <div class="content-form" style="margin-top:20px;"> <p class="content-title">Account And Password</p> <el-form ref="ruleForm" :model="accountPasswordForm" label-width="220px" class="accountPasswordForm"> <el-form-item label="Enter the new password" prop="password"> <el-input v-model="accountPasswordForm.password"></el-input> </el-form-item> <el-form-item label="Retype the password" prop="confirm_password"> <el-input v-model="accountPasswordForm.confirm_password"></el-input> </el-form-item> <el-form-item> <el-button class="saveBtn" @click="onSave('form')"> Save </el-button> </el-form-item> </el-form> </div> </div> <div v-show="activeMenu === 'enquiry'" class="content-form"> <p class="content-title">{{ tabName }}</p> <div class="searchInput"> <el-input placeholder="Search your job name" v-model="enquiryKeyword" clearable @keyup.enter.native="getEnquiryList" @clear="getEnquiryList" ><i slot="suffix" class="el-input__icon el-icon-search" @click="getEnquiryList"></i> </el-input> </div> <el-table :data="enquiryList" stripe style="width: 100%" @row-click="goEnquiryDetail" :header-cell-style="{ background: '#00213b', color: '#ffffff' }" v-loading="tableLoading"> <el-table-column prop="Auto_Number" label="Enquiry No"> </el-table-column> <el-table-column prop="Enquiry_Title" label="Job Name" width="300"> </el-table-column> <el-table-column prop="Customize_Pipeline_Stage" label="Status"></el-table-column> <!-- <el-table-column prop="Rating" label="Ratiing"></el-table-column> --> <el-table-column prop="Enquiry_Created" label="Date"> <template slot-scope="scope"> <div> {{ $utils.formatTime( scope.row.Sales_Order_Created, 'DD/MM/YYYY', true ) }} </div> </template> </el-table-column> <el-table-column label="Action" width="90" align="center"> <template> <el-button size="small" style="background-color: rgb(0, 33, 59); color: #fff" plain >View</el-button > </template> </el-table-column> <!-- <el-table-column label="Quote PDF"> <template> <el-button>Download</el-button> </template> </el-table-column> --> </el-table> <pagination v-show="enquiryTotal > 0" :total="enquiryTotal" :page.sync="enquiryListQuery.page" :limit.sync="enquiryListQuery.limit" @pagination="getEnquiryList" /> </div> <div v-show="activeMenu === 'address'" class="content-form"> <p class="content-title">{{ tabName }}</p> <div class="address-content"> <div class="my-addresses add-address" @click="addAddress(2)"> <img src="@/assets/img/myAccount/add-address.png" alt="" /> <p>Add address</p> </div> <div class="my-addresses address" v-for="item in addressList" :key="item.id"> <div class="username"> <p>{{ item.name }}</p> <span v-show="item.is_default">Default</span> </div> <div class="my-address-content"> <p>{{ item.state }}</p> <p>{{ item.city }}</p> <p>{{ item.address }}</p> <p>{{ item.post_code }}</p> <p>{{ item.country }}</p> <p>Phone number: {{ item.phone }}</p> </div> <div class="edit-btns"> <el-button size="mini" @click="editAddress(3, item.id)"> Edit </el-button> <el-button size="mini" @click="delAddress(item.id)"> Remove </el-button> <el-button size="mini" @click="setDefault(item.id)" v-show="!item.is_default"> Set as Default </el-button> </div> </div> </div> <pagination v-show="addressTotal > 0" :total="addressTotal" :page.sync="addressListQuery.page" :limit.sync="addressListQuery.limit" @pagination="getAddressList" /> </div> <!-- My Orders --> <div v-show="activeMenu.includes('orders')" class="content-form"> <p class="content-title">{{ tabName }}</p> <div class="searchInput"> <el-input placeholder="Search your job name" v-model="orderKeyword" clearable @keyup.enter.native="getOrdersList" @clear="getOrdersList" ><i slot="suffix" class="el-input__icon el-icon-search" @click="getOrdersList"></i> </el-input> <el-select v-if="selShow" v-model="selword" filterable clearable default-first-option placeholder="Select the status"> <el-option v-for="option in orderSelList" :label="option" :value="option" :key="option" ></el-option> </el-select> <el-select v-if="$store.state.userInfo?.memberCrmcomList?.length > 1" v-model="accounts_id" filterable clearable default-first-option placeholder="Select the CRM"> <el-option v-for="option in $store.state.userInfo?.memberCrmcomList" :label="option.name" :value="option.id" :key="option.id" ></el-option> </el-select> <el-button type="primary" @click="getOrdersList" style='background-color: rgb(0, 33, 59);border-color:rgb(0, 33, 59)'>Submit</el-button> </div> <el-table :data="tableData" v-loading="tableLoading" stripe style="width: 100%" :header-cell-style="{ background: '#00213b', color: '#ffffff' }"> <el-table-column prop="Sales_Order_Title_Job_Name" label="Job Name"> </el-table-column> <el-table-column width="100" prop="Reference" label="Order No"> </el-table-column> <el-table-column width="120" prop="Sales_Order_Created" label="Order Date"> <template slot-scope="scope"> <div> {{ $utils.formatTime( scope.row.Sales_Order_Created, 'DD/MM/YYYY' ) }} </div> </template> </el-table-column> <el-table-column width="140" prop="Order_Stage_new" label="Order Status"> </el-table-column> <el-table-column width="160" prop="Tracking_No_arr" label="Tracking No#"> <template slot-scope="scope"> <ul class="location"> <li v-for="item in scope.row.Tracking_No_arr" :key="item.Tracking_No" @click="openTracking_URL(item.Tracking_URL)"><i class="el-icon-location"></i>{{item.Tracking_No}}</li> </ul> </template> </el-table-column> <el-table-column width="110" prop="Grand_Total" label="Amount"> <template slot-scope="scope"> ${{ transformNumber(scope.row.Grand_Total) }} </template> </el-table-column> <el-table-column label="Action" width="80" align="center"> <template slot-scope="scope"> <el-button @click="goOrderDetail(scope.row)" size="small" style="background-color: rgb(0, 33, 59); color: #fff" plain >View</el-button > </template> </el-table-column> </el-table> <pagination v-show="orderTotal > 0" :total="orderTotal" :page.sync="orderListQuery.page" :limit.sync="orderListQuery.limit" @pagination="getOrdersList" /> </div> </div> </div> <add-address-dialog :dialogVisible.sync="dialogVisible" :data="addressDetail" :componentVisible="componentVisible" @close="closeAddressDialog" @update="update" /> <dialog-XX-success :visible.sync="xxContentVisible" :content="xxContent" @notify-parent="handleNotification"></dialog-XX-success> <el-dialog :lock-scroll="false" :visible.sync="urlDialogShow" center width="850px" top="20vh"> <iframe :src="Tracking_URL" style="width:100%;height:500px;" frameborder="0"></iframe> </el-dialog> </div> </template> <script> import { mapMutations } from 'vuex' import addAddressDialog from '../../../components/addAddressDialog.vue' import dialogXXSuccess from '@/components/DIalogXXSuccess.vue' import imageUpload from '@/components/ImageUpload' import { round } from '@/utils/price.js' export default { components: { addAddressDialog, 'dialog-XX-success': dialogXXSuccess,imageUpload }, data() { return { xxContentVisible: false, xxContent: 'success', componentVisible: 1, // 2:add 3:edit 4:audit tabName: '', tableLoading: true, // 表单配置项 profileform: {}, rules: { email: [ { required: true, message: 'Please enter the email', trigger: 'blur', }, ], company: [ { required: true, message: 'Please enter the company', trigger: 'blur', }, ], contacts: [ { required: true, message: 'Please enter first name', trigger: 'blur', }, ], last_name: [ { required: true, message: 'Please enter last name', trigger: 'blur', }, ], phone: [ { required: true, message: 'Please enter the phone', trigger: 'blur', }, ], password: [ { required: true, message: 'Please enter the password', trigger: 'blur', }, ], confirm_password: [ { required: true, message: 'Please enter the confirm_password', trigger: 'blur', }, ], }, accountPasswordForm: { password: '', confirm_password: '', }, orderKeyword: '', selword: '', accounts_id: '', orderTotal: 0, orderListQuery: { page: 1, limit: 20, }, tableData: [], dialogVisible: false, addressTotal: 0, addressListQuery: { page: 1, limit: 8, }, addressList: [], addressDetail: {}, enquiryKeyword: '', enquiryList: [], enquiryListQuery: { page: 1, limit: 20, }, enquiryTotal: 0, orderSelList:[], Tracking_URL: '', urlDialogShow: false, } }, computed: { activeMenu() { return this.$route.query.type ?? 'profile'; }, selShow(){ return this.activeMenu === 'all-orders' || this.activeMenu === 'open-orders' } }, watch: { $route: { handler(to) { if (process.client) { if (this.$utils.checkLogin()) { this.updateType() } } }, }, orderKeyword() { this.orderListQuery.page = 1; }, enquiryKeyword() { this.enquiryListQuery.page = 1; } }, mounted() { if (this.$utils.checkLogin()) { this.getMemberDetail() this.updateType() } else { this.$router.replace('/') } }, methods: { transformNumber(value) { return round(Number(value)).toFixed(2) }, handleClick(key, keyPath) { if (key) { this.$router.push({ path: '/home/myDetail', query: { type: key }, }) } }, updateType() { if (this.activeMenu === 'profile') { this.tabName = 'My Profile' } else if (this.activeMenu === 'enquiry') { this.tabName = 'My Enquiry' this.getEnquiryList() } else if (this.activeMenu === 'address') { this.tabName = 'My Address' this.getAddressList() } else { this.selword = '' if(this.activeMenu === 'all-orders'){ this.orderSelList= ['Order Confirmed','In Production','In Transit','Order Completed'] } if(this.activeMenu === 'open-orders'){ this.orderSelList = ['Order Confirmed','In Production','In Transit'] } this.tabName = 'My Orders' this.getOrdersList() } }, closeAddressDialog() { this.dialogVisible = false }, // 获取用户信息 getMemberDetail() { this.$axios .get('/au/member/detail') .then(res => { if (res.code === 1) { this.profileform = res.result this.profileform.logo = this.profileform.logo?this.formatLogo(this.profileform.logo):[]; } }) .catch(() => {}) }, formatLogo(params){ return [{ 'url': params }]; }, onSave(form) { if ( this.accountPasswordForm.confirm_password !== this.accountPasswordForm.password ) { this.$message.error('The second password is inconsistent!') return } this.$refs[form].validate(valid => { if (valid) { const requestBody = { email: this.profileform.email, company: this.profileform.company, contacts: this.profileform.contacts, last_name: this.profileform.last_name, phone: this.profileform.phone, logo: this.profileform.logo[0]?.url ?? '', }; let needLogout = false if (this.accountPasswordForm.password.trim() !== '') { requestBody.password = this.accountPasswordForm.password; requestBody.confirm_password = this.accountPasswordForm.confirm_password; needLogout = true } this.$axios .post('/au/member/edit', requestBody) .then(res => { if (res.code === 1) { this.$notify({ customClass: 'custom-notify-class', title: 'success', message: 'The profile information is modified successfully', type: 'success', }) if(needLogout){ setTimeout(() => { this.$store.dispatch('logout').then(() => { this.$router.push('/') }) }, 500) } } }) .catch(() => {}) } else { console.log('error submit!!') return false } }) }, // 获取订单列表 getOrdersList() { const accounts_id = this.accounts_id ? this.accounts_id : this.$store.state.userInfo?.memberCrmcomList.map((i)=>i.id).join() const type = this.activeMenu === 'all-orders'?'':this.activeMenu === 'open-orders'? 'Open Orders':'Closed Orders' this.tableLoading = true this.$axios .post('/crmdata/order_lists', { keyword: this.orderKeyword, page: this.orderListQuery.page, limit: this.orderListQuery.limit, accounts_id, Order_Stage: this.selword, type }) .then(res => { if (res.code === 1) { this.tableData = res.result.data this.orderTotal = res.result.total this.tableLoading = false } if (process.client) { this.$nextTick(() => { window.scroll(0, 0) }) } }) .catch(() => {}) }, goOrderDetail(row) { const routeUrl = this.$router.resolve({ path: '/home/myDetail/orderDetail', query: { id: row.sales_orders_id,crm: row.Account_Name_id }, }) window.open(routeUrl.href, '_blank') }, getEnquiryList() { this.tableLoading = true this.$axios .post('/crmdata/enquiries_lists', { keyword: this.enquiryKeyword, page: this.enquiryListQuery.page, limit: this.enquiryListQuery.limit, accounts_id: this.$store.state.userInfo?.crm_accounts_id || '', }) .then(res => { if (res.code === 1) { this.enquiryList = res.result.data this.enquiryTotal = res.result.total this.tableLoading = false } if (process.client) { this.$nextTick(() => { window.scroll(0, 0) }) } }) }, goEnquiryDetail(row) { const routeUrl = this.$router.resolve({ path: '/home/myDetail/enquiryDetail', query: { id: row.enquiries_id }, }) window.open(routeUrl.href, '_blank') }, // 获取地址列表 getAddressList() { this.$axios .get('address/list', { params: { page: this.addressListQuery.page, limit: this.addressListQuery.limit, }, }) .then(res => { if (res.code === 1) { this.addressList = res.result.data this.addressTotal = res.result.total } if (process.client) { this.$nextTick(() => { window.scroll(0, 0) }) } }) .catch(() => {}) }, addAddress(num) { this.addressDetail = {} this.componentVisible = num this.dialogVisible = true }, editAddress(num, id) { this.$axios .get('address/detail/' + id) .then(res => { this.addressDetail = res.result this.addressDetail.is_default = res.result.is_default === 1 this.componentVisible = num this.dialogVisible = true }) .catch(() => {}) }, delAddress(id) { this.$axios.get('address/delete/' + id).then(res => { this.$notify({ title: 'success', message: 'Deleted successfully', type: 'success', duration: 3000, }) this.getAddressList() }) // .catch((error) => {}); }, setDefault(id) { this.$axios.get('address/set_default/' + id).then(res => { this.$notify({ title: 'success', message: 'Default address is set successfully', type: 'success', duration: 3000, }) this.getAddressList() }) // .catch((error) => {}); }, update() { this.getAddressList() }, resetPassword() { if ( this.accountPasswordForm.confirm_password !== this.accountPasswordForm.password ) { this.$message.error('The second password is inconsistent!') } else { this.$axios({ url: 'au/member/reset', method: 'POST', data: this.accountPasswordForm, }) .then(res => { if (res.code === 1) { this.xxContentVisible = true this.xxContent = 'Password Reset Successful' } }) .catch(() => { // this.$message.error(error.response.data.msg); }) } }, openTracking_URL(url){ this.Tracking_URL= url this.urlDialogShow= true }, handleNotification() { this.$router.push('/') this.$store.dispatch('logout') this.openDialog() }, ...mapMutations(['openDialog']), }, } </script> <style lang="scss"> .custom-notify-class { .el-notification__content { text-align: left; } } </style> <style lang="scss" scoped> .content{ display: flex; .el-menu-vertical{ width: 260px; min-height: 606px; background: #e8eaee; .iconfont { font-size: 22px; } :deep(.el-menu-item){ font-size: 16px; &:hover { background-color: #e8eaee !important; } &.is-active { background-color: #00213b !important; } } :deep(.el-submenu__title){ font-size: 16px; &:hover { background-color: #e8eaee !important; } } } :deep(.content-right){ flex:1; margin-left: 15px; &>div{ min-height: 606px; } .content-title { margin: 15px 0px 25px 15px; position: relative; width: 282px; height: 27px; font-size: 24px; font-weight: bold; color: #102f47; &::before { content: ""; position: absolute; left: -14px; top: 50%; transform: translateY(-50%); width: 4px; height: 17px; background: #e90000; border-radius: 2px; margin-right: 10px; } } .content-form{ border: 1px solid #c7c7c7; padding: 0 20px; .avatar-uploader .el-upload { border: 1px dashed #d9d9d9; border-radius: 6px; cursor: pointer; position: relative; overflow: hidden; } } .searchInput { margin-bottom: 10px; display: grid; grid-template-columns: 1fr 1fr 1fr 0.5fr 1fr; gap: 10px; .el-input { .el-input__inner { border-radius: 30px; } .el-input__suffix { .el-input__icon { font-size: 16px; font-weight: bold; } .el-icon-search { cursor: pointer; } } } } .upload-item{ .el-form-item__content{ z-index: 1; } } .el-form-item { margin-bottom: 20px; height: 40px; .el-form-item__label { font-size: 16px; font-weight: 400; color: #333333; line-height: 35px; } .el-input__inner { width: 460px; background: #ffffff; border: 1px solid #bebebe; border-radius: 4px; } .saveBtn { min-width: 140px; height: 40px; background: #00213b; border-radius: 6px; font-size: 18px; font-weight: 400; color: #ffffff; margin-left: 180px; } } .el-table { margin-bottom: 10px; border: 1px solid #c7c7c7; .el-table__header { height: 57px; } .el-table__row { height: 57px; } } .address-content { display: flex; flex-wrap: wrap; .my-addresses { display: inline-block; width: 350px; height: 300px; box-sizing: border-box; margin-bottom: 15px; background: #f9fcfe; border: 1px solid #c7c7c7; border-radius: 10px; margin-right: 13px; &:nth-of-type(3), &:nth-of-type(6), &:nth-of-type(9) { margin-right: 0; } } .add-address { display: flex; flex-direction: column; justify-content: space-evenly; align-items: center; img { width: 77px; height: 77px; } p { width: 330px; height: 21px; font-size: 30px; font-family: Proxima Nova; font-weight: 400; color: #00213b; line-height: 30px; text-align: center; } } .address { padding: 15px; .username { display: flex; justify-content: space-between; align-items: center; height: 35px; p { height: 35px; font-size: 24px; font-family: Proxima Nova; font-weight: bold; color: #102f47; line-height: 35px; } span { height: 22px; font-size: 14px; font-family: Proxima Nova; font-weight: 400; color: #ef1f1f; line-height: 22px; } } .my-address-content { margin: 10px 0px; p { font-size: 16px; font-family: Proxima Nova; font-weight: 400; color: #666666; line-height: 30px; } } .edit-btns { display: flex; justify-content: flex-end; .el-button { font-size: 16px; font-family: Proxima Nova; font-weight: 400; color: #00213b; border: 1px solid #00213b; border-radius: 4px; } .el-button--mini { padding: 3px 10px; } } } } .location{ color: #004A97; li{ cursor: pointer; } } .center{ text-align: center; } } } :deep(.el-pagination.is-background) { .el-pager { li.number { background-color: #f8f8f8; border-radius: 50%; color: #a7a7a7; } li:not(.disabled).active { background-color: #00213b; color: #d4d7da; } } .btn-prev, .btn-next { border-radius: 50%; background-color: #fff; .el-icon-arrow-left:before { content: ''; } .el-icon-arrow-right:before { content: ''; } } } </style>