当前位置: 首页 > news >正文

物流网络优化最新seo网站优化教程

物流网络优化,最新seo网站优化教程,申请网站空间怎么做,服务器吗放几个网站实现效果:(可拉代码下来看:vue-demo: vueDemo) 左侧表格为点击查询调用接口查询出来的数据,右侧表格为左侧表格所有选择的数据,由前端实现分页。 两个el-table勾选数据联动更新 实现逻辑: el-…

 实现效果:(可拉代码下来看:vue-demo: vueDemo)

左侧表格为点击查询调用接口查询出来的数据,右侧表格为左侧表格所有选择的数据,由前端实现分页。

两个el-table勾选数据联动更新

实现逻辑:

el-table表格的selection-change方法(element组件的table表格)结合分页组件,自定义一个用于存储(左侧表格)当前页的已勾选数据;一个用于存储所勾选的所有数据(右侧表格所有数据);一个用于存储(右侧表格)当前页的展示数据。

代码实现:

 所有代码:

<template><div><Search v-show="showSearch" label-width="100" :limit-height-param="false" @search="handleQuery" @clear="resetQuery"><div><span class="label">账号名称</span><el-selectv-model="queryParams.companyCodeList"placeholder="请选择账号名称"clearablefilterabledefault-first-optionmultiplesize="small"><el-optionv-for="item in companyCodeOptions":key="item.dictValue":label="`${item.dictLabel} | ${item.dictValue}`":value="item.dictValue"></el-option></el-select></div><div><span class="label">账户类型</span><el-selectv-model="queryParams.accountType"placeholder="请选择账户类型"clearablefilterabledefault-first-optionsize="small"><el-optionv-for="dict in accountTypeOptions":key="dict.dictValue":label="dict.dictLabel":value="dict.dictValue"></el-option></el-select></div><div><span class="label">银行卡号</span><el-inputv-model="queryParams.cardNum"placeholder="请输入银行卡号"clearablesize="small"@keyup.enter.native="handleQuery"/></div></Search><el-row :gutter="20"><el-col :span="12"><el-tablev-loading="tableLoading"ref="multipleTable":data="tableData":stripe="true":row-key="getRowKeys":row-style="{height: '54px'}"@selection-change="handleSelectionChange"><el-table-column type="selection" align="center" width="55" fixed /><el-table-column label="序号" type="index" align="center" width="55" fixed /><el-table-column label="公司名称" prop="companyCode" :formatter="tableFormat" align="center" min-width="120" show-overflow-tooltip /><el-table-column label="bankAccountId" prop="bankAccountId" align="center" min-width="130" show-overflow-tooltip /><el-table-column label="账户类型" prop="accountType" :formatter="tableFormat" align="center" min-width="100" show-overflow-tooltip /><el-table-column label="银行卡号" prop="cardNum" align="center" min-width="220" show-overflow-tooltip /><template v-for="(column, columIndex) in tableColumnOption"><el-table-column:key="columIndex":prop="column.prop":label="column.label":min-width="column.width":fixed="column.fixed || false":align="column.align || 'center'":sortable="column.sortable || false":index="columIndex":show-overflow-tooltip="column.tooltip || true"><!-- v-for="(column, columIndex) in tableColumnOption" --><template slot-scope="scope"><span v-if="column.prop === 'status'"><el-tag v-if="scope.row.status == 0" type="danger">禁用</el-tag><el-tag v-else-if="scope.row.status == 1" type="success">启用</el-tag></span><span v-else-if="column.prop === 'type'"><el-tag v-if="scope.row.type == 1">type1</el-tag><el-tag v-if="scope.row.type == 0" type="success">type0</el-tag></span><span v-else>{{ scope.row[column.prop] }}</span></template></el-table-column></template></el-table><paginationv-show="total > 0":total="total":page.sync="queryParams.pageNum":limit.sync="queryParams.pageSize":page-sizes="[3, 5, 10, 20, 30, 50]":pagerCount="5"@pagination="getList"/></el-col><el-col :span="12"><el-tablev-loading="tableLoading"ref="selectMultipleTable":data="selectTableData":row-style="{height: '54px'}"><el-table-column label="序号" type="index" align="center" width="55" fixed /><el-table-column label="账户名称" prop="companyCode" :formatter="tableFormat" align="center" min-width="120" show-overflow-tooltip /><el-table-column label="bankAccountId" prop="bankAccountId" align="center" min-width="130" show-overflow-tooltip /><el-table-column label="账户类型" prop="accountType" :formatter="tableFormat" align="center" min-width="100" show-overflow-tooltip /><el-table-column label="银行卡号" prop="cardNum" align="center" min-width="220" show-overflow-tooltip /><el-table-columnlabel="操作"align="center"fixed="right"width="100"><template slot-scope="scope"><el-buttonclass="delBtn"size="small"type="text"icon="el-icon-delete"@click="handleDelete(scope.row)">删除</el-button></template></el-table-column></el-table><paginationv-show="selectTotal > 0":total="selectTotal":page.sync="pageNum":limit.sync="pageSize":page-sizes="[3, 5, 10, 20, 30, 50]":pagerCount="5"@pagination="getSelectList"/></el-col></el-row></div>
</template><script>
import Search from '@/components/Search/index'
import {deepClone,
} from '@/utils'
import {getDepartmentsList
} from '@/api/tableLinkage'
import {geBasicAccountType,geBasicCompany,
} from '@/api/selectList'export default {components: {Search,},data() {return {// 遮罩层// loading: false,tableLoading: false,// 显示搜索条件showSearch: true,// 查询参数queryParams: {pageNum: 1,pageSize: 10,companyCodeList: [],cardNum: null,accountType: null,},companyCodeOptions: [],accountTypeOptions: [],codeBsOptions: [],allDataScopeOptions: [{dictValue: '1',dictLabel: '是'},{dictValue: '0',dictLabel: '否'}],total: 0, // 搜索表格(左侧)总条数selectTotal: 0, // 勾选表格(右侧)总条数pageNum: 1, // 勾选表格(右侧)当前页码pageSize: 10, // 勾选表格(右侧)每页数量tableData: [], // 搜索表格(左侧)数据selectedData: [], // 所勾选的所有数据selectTableData: [],  // 勾选表格(右侧)当前页展示的数据multipleSelection: [],  // 当前页选中的数据idKey: 'bankAccountId', // 标识列表数据中每一行的唯一键的名称// idKey: 'id', // 标识列表数据中每一行的唯一键的名称tableColumnOption: [{prop: 'preview',label: 'preview',width: '200',},{prop: 'status',label: 'status',width: '200',},{prop: 'jobType',label: 'jobType',width: '200',},{prop: 'type',label: 'type',width: '200',},],columnOption: [// { selection: true },// { type: 'index' },// {prop: 'name', label: '名称', width: 160},// { slot: 'action', label: '操作' }],}},created () {// 若初始就有选中数据,需要对选中数据分页// this.selectedData = [...]// this.handleSelectListPaging()this.geBasicAccountType()this.geBasicCompany()this.getList()},methods: {geBasicAccountType () {geBasicAccountType().then(res => {this.accountTypeOptions = res.data})},geBasicCompany () {geBasicCompany().then(res => {this.companyCodeOptions = res.data})},getList () {this.tableLoading = truegetDepartmentsList(this.queryParams).then(res => {console.log("🚀 ~ file: index.vue:24 ~ getDepartmentsList ~ res:", res)// console.log(res.data)this.tableData = res?.rows || []this.total = res?.total || 0// this.handleSelectListPaging()this.$nextTick(() => {// 设置选中this.setSelectRow()})this.tableLoading = false}).catch(() => { this.tableLoading = false })},/** 搜索按钮操作 */handleQuery() {this.queryParams.pageNum = 1this.getList()},/** 重置按钮操作 */resetQuery() {this.queryParams = this.$options.data().queryParamsthis.handleQuery()},tableFormat(row, { property }, value) {return this.selectDictLabel(this[`${property}Options`], value)},// 对表格数据分页getSelectList() {const start = Math.ceil(((this.pageNum - 1) * this.pageSize).toFixed(0)),end = Math.ceil((start + this.pageSize).toFixed(2))this.selectTableData = this.selectedData.slice(start >= 0 ? start : 0, end)// this.$refs.selectMultipleTable.bodyWrapper.scrollTo(0, 0)},handleSelectListPaging() {// 前端分页选中数据表格(左侧表格)this.selectTotal = this.selectedData.length// 总页数=(总数 - 1)/ 每页数量 + 1// 总页数=(总数 + 每页数量 - 1)/ 每页数量// 总页数 = Math.ceil(总条数 / 每页数量)// 使用Math.ceil()函数,返回大于或者等于指定表达式的最小整数,进1法取整const totalPage = Math.ceil(this.selectTotal / this.pageSize)// 原页码大于现数据的总页数,页码取总页数的值this.pageNum = this.pageNum > totalPage ? totalPage : this.pageNum// 页码最小值为1this.pageNum = this.pageNum < 1 ? 1 : this.pageNum// 对表格数据分页this.getSelectList()},// 设置选择表格行唯一标识getRowKeys(row) {return row[this.idKey]},// 设置选中的方法setSelectRow() {if (!this.selectedData || this.selectedData.length <= 0) {return}// 标识当前行的唯一键的名称let idKey = this.idKey// 获取所有选中数据的idconst selectAllIds = this.selectedData.map(row => row[idKey]) || []console.warn("🚀 ~ file: dataAuthenticationUpdateDetail.vue:558 ~ setSelectRow ~ selectAllIds:", selectAllIds)this.$refs.multipleTable.clearSelection() // 先清空原有选中数据this.tableData.forEach(item => {// 查找当前页中是否包含所有选中数据中的id,存在则设置选中(触发 handleSelectionChange ,进而触发记忆选择核心方法 changePageCoreRecordData)if (selectAllIds.indexOf(item[idKey]) >= 0) {this.$refs.multipleTable.toggleRowSelection(item, true)}})},// 多选框选中数据handleSelectionChange(selection) {this.multipleSelection = selectionthis.$nextTick(() => {this.changePageCoreRecordData()})},// 记忆选择核心方法(操作搜索表格——左侧,联动改变勾选表格——右侧)async changePageCoreRecordData() {// 标识当前行的唯一键的名称let idKey = this.idKey// 如果总记忆中还没有选择的数据,那么就直接取当前页选中的数据,不需要后面一系列计算if (this.selectedData.length <= 0) {this.selectedData = this.multipleSelection// 前端分页this.handleSelectListPaging()return}// 总选择里面的key集合const selectAllIds = this.selectedData.map(row => row[idKey]) || []// 获取当前页选中的idlet selectIds = []this.multipleSelection.forEach(row => {selectIds.push(row[idKey])// 如果总选择里面不包含当前页选中的数据,那么就加入到总选择集合里// (左侧表格勾选数据,加入到右侧表格中)if (selectAllIds.indexOf(row[idKey]) < 0) {this.selectedData.push(row)}})// 得到当前页没有选中的idlet noSelectIds = []this.tableData.map(row => {if (selectIds.indexOf(row[idKey]) < 0) {noSelectIds.push(row[idKey])}})noSelectIds.map(id => {if (selectAllIds.indexOf(id) >= 0) {for (let i = 0; i < this.selectedData.length; i++) {if (this.selectedData[i][idKey] === id) {console.warn('总选择中有未被选中的,那么就删除这条:', id)// 如果总选择中有未被选中的,那么就删除这条// (左侧表格取消勾选数据,从右侧表格中删除这条数据)this.selectedData.splice(i, 1)break}}}})// 前端分页this.handleSelectListPaging()},// 删除handleDelete(row) {// 标识当前行的唯一键的名称let idKey = this.idKey// 过滤所有选中数据,将要删除的这条数据过滤掉this.selectedData = this.selectedData.filter(item => {return item[idKey] !== row[idKey]})// 查找当前页是否存在需要删除的这条数据const findRow = this.tableData.find(item => { return row[idKey] === item[idKey] })if (findRow) {// 当前页存在要删除的这条数据,取消选中状态// (触发 handleSelectionChange ,进而触发记忆选择核心方法 changePageCoreRecordData)this.$refs.multipleTable.toggleRowSelection(findRow)} else {// 当前页不存在需要删除的这条数据,直接调用前端分页方法,对所有选中数据(已剔除需要删除的这条数据)重新进行分页this.handleSelectListPaging()}},// 处理参数handleParams() {const param = deepClone(this.form)const bankAccountIdList = this.selectedData.map(item => item.bankAccountId)const params = {id: param.id,codeBs: param.codeBs,allDataScope: param.allDataScope,bankAccountIdList: bankAccountIdList}return params},}
}
</script><style>
</style>

关键步骤:

 

当点击搜索查询左侧数据、或切换分页、切换页面大小,调用后端接口(this.getList())的时候,需要调用选中方法(this.setSelectRow()):

// 设置选中的方法setSelectRow() {if (!this.selectedData || this.selectedData.length <= 0) {return}// 标识当前行的唯一键的名称let idKey = this.idKey// 获取所有选中数据的idconst selectAllIds = this.selectedData.map(row => row[idKey]) || []console.warn("🚀 ~ file: dataAuthenticationUpdateDetail.vue:558 ~ setSelectRow ~ selectAllIds:", selectAllIds)this.$refs.multipleTable.clearSelection() // 先清空原有选中数据this.tableData.forEach(item => {// 查找当前页中是否包含所有选中数据中的id,存在则设置选中// (触发 handleSelectionChange ,进而触发记忆选择核心方法 changePageCoreRecordData)if (selectAllIds.indexOf(item[idKey]) >= 0) {this.$refs.multipleTable.toggleRowSelection(item, true)}})},

设置选中方法,先清空左侧表格原有选中数据,然后根据右侧表格所有选中数据的id(自己设定的key)来判断右侧表格当前页是否存在选中数据,存在则调用el-table的toggleRowSelection方法,将数据勾选上。(toggleRowSelection方法会触发el-table的selection-change【即触发handleSelectionChange】进而触发记忆选择核心方法 changePageCoreRecordData)

// 多选框选中数据handleSelectionChange(selection) {this.multipleSelection = selectionthis.$nextTick(() => {this.changePageCoreRecordData()})},

勾选右侧表格数据触发记忆选择核心方法 changePageCoreRecordData:

// 记忆选择核心方法(操作搜索表格——左侧,联动改变勾选表格——右侧)async changePageCoreRecordData() {// 标识当前行的唯一键的名称let idKey = this.idKey// 如果总记忆中还没有选择的数据,那么就直接取当前页选中的数据,不需要后面一系列计算if (this.selectedData.length <= 0) {this.selectedData = this.multipleSelection// 前端分页this.handleSelectListPaging()return}// 总选择里面的key集合const selectAllIds = this.selectedData.map(row => row[idKey]) || []// 获取当前页选中的idlet selectIds = []this.multipleSelection.forEach(row => {selectIds.push(row[idKey])// 如果总选择里面不包含当前页选中的数据,那么就加入到总选择集合里// (左侧表格勾选数据,加入到右侧表格中)if (selectAllIds.indexOf(row[idKey]) < 0) {this.selectedData.push(row)}})// 得到当前页没有选中的idlet noSelectIds = []this.tableData.map(row => {if (selectIds.indexOf(row[idKey]) < 0) {noSelectIds.push(row[idKey])}})noSelectIds.map(id => {if (selectAllIds.indexOf(id) >= 0) {for (let i = 0; i < this.selectedData.length; i++) {if (this.selectedData[i][idKey] === id) {console.warn('总选择中有未被选中的,那么就删除这条:', id)// 如果总选择中有未被选中的,那么就删除这条// (左侧表格取消勾选数据,从右侧表格中删除这条数据)this.selectedData.splice(i, 1)break}}}})// 前端分页this.handleSelectListPaging()},

        

        如果总记忆中还没有选择的数据,那么就直接取当前页选中的数据,不需要后面一系列计算。

        如果已经有已选择的数据了,则先获取当前页选中数据的值集,获取当前页没有选中的数据的值集。如果总选择里面不包含当前页选中的数据,那么就将这些数据加入到总选择集合里(左侧表格勾选数据,加入到右侧表格中)。如果总选择中有未被选中的数据,那么就从总选择表格中删除这些数据(左侧表格取消勾选数据,从右侧表格中删除这条数据)。

        这里经过上述计算后,得到最新的右侧表格全部数据,这时就需要对右侧表格重新分页:

(涉及到总页面数的计算,看这里Javascript 前端分页——根据页面大小(pageSize)和总行数(total)计算总页面数(totalPage)-CSDN博客)

// 对表格数据分页getSelectList() {const start = Math.ceil(((this.pageNum - 1) * this.pageSize).toFixed(0)),end = Math.ceil((start + this.pageSize).toFixed(2))this.selectTableData = this.selectedData.slice(start >= 0 ? start : 0, end)// this.$refs.selectMultipleTable.bodyWrapper.scrollTo(0, 0)},handleSelectListPaging() {// 前端分页选中数据表格(左侧表格)this.selectTotal = this.selectedData.length// 总页数=(总数 - 1)/ 每页数量 + 1// 总页数=(总数 + 每页数量 - 1)/ 每页数量// 总页数 = Math.ceil(总条数 / 每页数量)// 使用Math.ceil()函数,返回大于或者等于指定表达式的最小整数,进1法取整const totalPage = Math.ceil(this.selectTotal / this.pageSize)// 原页码大于现数据的总页数,页码取总页数的值this.pageNum = this.pageNum > totalPage ? totalPage : this.pageNum// 页码最小值为1this.pageNum = this.pageNum < 1 ? 1 : this.pageNum// 对表格数据分页this.getSelectList()},

        前面已经讲了左侧表格勾选,取消勾选时,对右侧表格的联动改变。下面来讲,右侧表格删除一条数据,如何让左侧表格取消勾选。其实也很简单,就是从右侧表格全部数据中,将要删除的数据去掉,若这条数据在左侧表格当前页存在,则触发el-table的toggleRowSelection(row,false)方法,取消勾选。若这条数据左侧表格在当前页不存在,则直接对右侧表格重新分页就好了。因为下次当左侧表格重新调用getList()方法(触发记忆选择核心方法 changePageCoreRecordData)的时候,右侧表格内已经没有要删除的数据了。

// 删除handleDelete(row) {// 标识当前行的唯一键的名称let idKey = this.idKey// 过滤所有选中数据,将要删除的这条数据过滤掉this.selectedData = this.selectedData.filter(item => {return item[idKey] !== row[idKey]})// 查找当前页是否存在需要删除的这条数据const findRow = this.tableData.find(item => { return row[idKey] === item[idKey] })if (findRow) {// 当前页存在要删除的这条数据,取消选中状态// (触发 handleSelectionChange ,进而触发记忆选择核心方法 changePageCoreRecordData)this.$refs.multipleTable.toggleRowSelection(findRow)} else {// 当前页不存在需要删除的这条数据,直接调用前端分页方法,对所有选中数据(已剔除需要删除的这条数据)重新进行分页this.handleSelectListPaging()}},

参考文章:

element的table表格多选结合分页实现已选中的记忆功能和实现表格数据和已选数据动态同步更新_element table分页多选-CSDN博客


文章转载自:
http://dinncozugunruhe.knnc.cn
http://dinncopullicate.knnc.cn
http://dinncolyonnaise.knnc.cn
http://dinncoosteoplasty.knnc.cn
http://dinncomonzonite.knnc.cn
http://dinncomeanness.knnc.cn
http://dinncobirdy.knnc.cn
http://dinncotogue.knnc.cn
http://dinncogetable.knnc.cn
http://dinncoluteinization.knnc.cn
http://dinncotheistic.knnc.cn
http://dinncoorthographical.knnc.cn
http://dinncopresage.knnc.cn
http://dinncotelematic.knnc.cn
http://dinncocurarize.knnc.cn
http://dinncocert.knnc.cn
http://dinncohypotheses.knnc.cn
http://dinncobronco.knnc.cn
http://dinncowithstand.knnc.cn
http://dinncobedpost.knnc.cn
http://dinncointercomparsion.knnc.cn
http://dinncobursiculate.knnc.cn
http://dinncoredbridge.knnc.cn
http://dinnconina.knnc.cn
http://dinncobarite.knnc.cn
http://dinncopassimeter.knnc.cn
http://dinncoparosmia.knnc.cn
http://dinncothereafter.knnc.cn
http://dinncoessayistic.knnc.cn
http://dinncoasosan.knnc.cn
http://dinncokojah.knnc.cn
http://dinncomdt.knnc.cn
http://dinncoreinvestigation.knnc.cn
http://dinncocontraseasonal.knnc.cn
http://dinncotirade.knnc.cn
http://dinncotiffany.knnc.cn
http://dinncobott.knnc.cn
http://dinncoarytenoid.knnc.cn
http://dinncocomposed.knnc.cn
http://dinncomanichee.knnc.cn
http://dinncolauryl.knnc.cn
http://dinncomicrolinguistics.knnc.cn
http://dinncorurigenous.knnc.cn
http://dinncoclimatotherapy.knnc.cn
http://dinncocoalfish.knnc.cn
http://dinncogabon.knnc.cn
http://dinncocockshot.knnc.cn
http://dinncobarbadian.knnc.cn
http://dinncoammonotelism.knnc.cn
http://dinncoqualitative.knnc.cn
http://dinncogavel.knnc.cn
http://dinncoteetotalism.knnc.cn
http://dinncorecalcitration.knnc.cn
http://dinncowarfare.knnc.cn
http://dinncomacrobiosis.knnc.cn
http://dinncolongeval.knnc.cn
http://dinncotransearth.knnc.cn
http://dinncounadvantageous.knnc.cn
http://dinncoimmoderacy.knnc.cn
http://dinncohartree.knnc.cn
http://dinncomonochloride.knnc.cn
http://dinncotableau.knnc.cn
http://dinncothylakoid.knnc.cn
http://dinncovitamin.knnc.cn
http://dinncotelefilm.knnc.cn
http://dinncoelusion.knnc.cn
http://dinncoinocula.knnc.cn
http://dinncosearch.knnc.cn
http://dinncodefang.knnc.cn
http://dinncosufficient.knnc.cn
http://dinncobiflagellate.knnc.cn
http://dinncofabricable.knnc.cn
http://dinncothujaplicin.knnc.cn
http://dinncopanchromatic.knnc.cn
http://dinncoreclusive.knnc.cn
http://dinncoamitosis.knnc.cn
http://dinncomoke.knnc.cn
http://dinncoicc.knnc.cn
http://dinncopostembryonic.knnc.cn
http://dinncouniserial.knnc.cn
http://dinncomcp.knnc.cn
http://dinncoshwa.knnc.cn
http://dinncoequipped.knnc.cn
http://dinncopodotheca.knnc.cn
http://dinncocaliph.knnc.cn
http://dinncocipher.knnc.cn
http://dinncobluetongue.knnc.cn
http://dinncomurray.knnc.cn
http://dinncoamorphic.knnc.cn
http://dinnconecrosis.knnc.cn
http://dinncopyrometry.knnc.cn
http://dinncoquirkily.knnc.cn
http://dinncomimeograph.knnc.cn
http://dinncopepperbox.knnc.cn
http://dinncobottleneck.knnc.cn
http://dinncododecagonal.knnc.cn
http://dinncoscript.knnc.cn
http://dinncopyrrhonist.knnc.cn
http://dinncoplaudit.knnc.cn
http://dinncoerotomaniac.knnc.cn
http://www.dinnco.com/news/91616.html

相关文章:

  • 南昌网站建设制作免费网站模板
  • 网站两侧对联广告图片关键少数
  • 毕业设计可以做网站吗可以做产品推广的软件有哪些
  • 网站的交互设计有什么武汉seo公司
  • 做seo的网站怎么创建自己的免费网址
  • wordpress如何修改html代码安徽seo推广公司
  • 网站的优化和推广方案晋城今日头条新闻
  • 网站怎么做统计优化营商环境心得体会2023
  • 东莞各类免费建站网络推广哪个平台效果最好
  • 做网站后端语言用什么免费seo工具
  • 网站产品管理模块湖南网站优化
  • 做外贸soho要做网站吗网络营销学什么
  • 网站服务器在哪可以看最新天气预报最新消息
  • 广西南宁网站优化短视频代运营公司
  • 理财 网站模板 html企业网络推广平台
  • 导航网站怎么做seoseo入门教学
  • 网站制作 文案上海seo优化公司bwyseo
  • 常州市建设工程质监站网站查权重的软件
  • 电商网站模板广州seo搜索
  • 网站开发维护前景企业网络营销目标
  • 网站建设自学网seo站长工具是什么
  • 网站界面设计技巧网络推广seo
  • 大良营销网站建设服务济南头条今日新闻
  • 哈尔滨网站制作方案百度怎么创建自己的网站
  • 电商商城网站开发seo关键词优化软件
  • 网站测试方法百度热门搜索排行榜
  • 单位logo设计太原seo网站管理
  • 网站在线答题怎么做网站制作的流程是什么
  • 龙岗沙湾社区网站建设ks数据分析神器
  • 网站建设和微信小程序哈尔滨seo服务