123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420 |
- <template>
- <view>
- <view class="uni-header">
- <uni-stat-breadcrumb class="uni-stat-breadcrumb-on-phone" />
- <view class="uni-group">
- <input class="uni-search" type="text" v-model="query" @confirm="search" placeholder="请输入搜索内容" />
- <button class="uni-button" type="default" size="mini" @click="search">搜索</button>
- </view>
- </view>
- <view class="uni-container">
- <view class="uni-stat--x flex p-1015">
- <view class="uni-stat--app-select" style="width: 500px;">
- <uni-data-select ref="appListRef" collection="opendb-app-list" field="appid as value, name as text" orderby="text asc" label="应用选择" v-model="appid" @change="search" />
- </view>
- </view>
- <unicloud-db ref="udb" :collection="collectionList" field="title,path,page_rules,appid" :where="where" page-data="replace" :orderby="orderby" :getcount="true"
- :page-size="options.pageSize" :page-current="options.pageCurrent" v-slot:default="{data,pagination,loading,error,options}" :options="options" loadtime="manual"
- @load="onqueryload">
- <uni-table ref="table" :loading="loading" :emptyText="errorMessage || error.message || '没有更多数据'" border stripe>
- <uni-tr>
- <uni-th align="center">序号</uni-th>
- <uni-th align="center" filter-type="search" @filter-change="filterChange($event, 'title')">页面标题</uni-th>
- <uni-th align="left" filter-type="search" @filter-change="filterChange($event, 'path')">页面URL</uni-th>
- <uni-th align="center" filter-type="search" @filter-change="filterChange($event, 'appid')">appid</uni-th>
- <uni-th align="center">操作</uni-th>
- </uni-tr>
- <uni-tr v-for="(item,index) in data" :key="index">
- <uni-td align="center">{{ (pagination.current - 1) * pagination.size + (index+1) }}</uni-td>
- <uni-td align="center">{{ item.title }}</uni-td>
- <uni-td align="left">{{ item.path }}</uni-td>
- <uni-td align="center">{{ item.appid }}</uni-td>
- <uni-td align="center">
- <view class="uni-group">
- <button @click="editRule(item)" class="uni-button" size="mini" type="primary">编辑规则</button>
- </view>
- </uni-td>
- </uni-tr>
- </uni-table>
- <view class="uni-pagination-box">
- <uni-pagination show-icon :page-size="pagination.size" v-model="pagination.current" :total="pagination.count" @change="onPageChanged" />
- </view>
- </unicloud-db>
- </view>
- <uni-popup ref="editRulePopup" type="center">
- <view class="edit-rule-popup">
- <view class="uni-title">页面规则</view>
- <view class="edit-rule-popup-tips">
- <uni-notice-bar :font-size="12" :text="editRulePopup.tips" />
- </view>
- <view class="edit-rule-popup-list">
- <view class="edit-rule-popup-item" v-for="(item1,index1) in pageInfo.page_rules" :key="index1">
- <view class="name">
- 规则 {{ pageInfo.page_rules.length - index1 }}
- </view>
- <view class="tags">
- <view class="tags-item tags-item-text" v-for="(item2, index2) in item1" :key="index2">
- <text class="text">{{ item2 }}</text> <uni-icons class="pointer" type="closeempty" size="12" color="#42b983" @click="deleteParamItem(index1,index2)"></uni-icons>
- </view>
- <view class="tags-item tags-item-add">
- <input class="tags-item-add-input" type="text" v-model.trim="editRulePopup.addParamInfo.value"
- :focus="editRulePopup.addParamInfo.index1 === index1 && editRulePopup.isAddParam" @blur="confirmAddParamItem(index1)"
- v-if="editRulePopup.addParamInfo.index1 === index1 && editRulePopup.isAddParam" placeholder="输入参数名" />
- <button size="mini" class="tags-item-add-btn" @click="addParamItem(index1)" v-else> + 添加参数 </button>
- </view>
- </view>
- <view class="btn">
- <uni-icons type="plus" size="28" class="pointer" color="#606266" @click="addRulesItem" v-if="index1 === 0 && pageInfo.page_rules.length < 5"></uni-icons>
- <uni-icons type="minus" size="28" class="pointer" color="#606266" @click="deleteRulesItem(index1)" v-else></uni-icons>
- </view>
- </view>
- </view>
- <view class="edit-rule-popup-btn">
- <button class="uni-button btn" type="primary" size="default" :loading="editRulePopup.loading" :disabled="editRulePopup.loading" @click="saveRule">保存</button>
- <button class="uni-button btn" type="default" size="default" @click="closeEditRulePopup">取消</button>
- </view>
- </view>
- </uni-popup>
- </view>
- </template>
- <script>
- import { enumConverter, filterToWhere } from '../../../js_sdk/validator/uni-stat-pages.js';
- const db = uniCloud.database()
- // 表查询配置
- const dbOrderBy = '' // 排序字段
- const dbSearchFields = ['title', 'path'] // 模糊搜索字段,支持模糊搜索的字段列表。联表查询格式: 主表字段名.副表字段名,例如用户表关联角色表 role.role_name
- // 分页配置
- const pageSize = 20
- const pageCurrent = 1
- const orderByMapping = {
- "ascending": "asc",
- "descending": "desc"
- }
- export default {
- data() {
- return {
- collectionList: "uni-stat-pages",
- appid: '',
- query: '',
- where: '',
- orderby: dbOrderBy,
- orderByFieldName: "",
- selectedIndexs: [],
- errorMessage: '',
- options: {
- pageSize,
- pageCurrent,
- filterData: {},
- ...enumConverter
- },
- imageStyles: {
- width: 64,
- height: 64
- },
- exportExcel: {
- "filename": "uni-stat-pages.xls",
- "type": "xls",
- "fields": {
- "title": "title",
- "path": "path"
- }
- },
- exportExcelData: [],
- pageInfo: {
- _id: "",
- page_rules: []
- },
- editRulePopup: {
- loading: false,
- tips: `页面规则说明:
- 1. 用于生成内容统计 url 的规则。通过设置页面有效参数,通过带参数的 url 对内容进行标识。例如有一个详情页面的请求有三个参数 page/detail/detail?id=1&type=1&t=1565943419,其中 t 为时间戳或随机数,则 id 和 type 为有效参数,需要在页面规则 page/detail/detail 中添加 id,type 这两个参数。
- 2. 每条规则可以添加多个参数,进行匹配时,每条规则单独生效。
- 3. 每个页面可以添加多个规则(最多 5 个规则),进行匹配时,后添加的规则优先级较高
- 4. 目前的匹配规则只能处理通过 url 显式传递参数,且参数形式为上述示例中的键值对格式。`,
- isAddParam: false,
- addParamInfo: {
- index1: "",
- value: ""
- },
- },
- }
- },
- onLoad() {
- this._filter = {}
- },
- onReady() {
- if (this.$refs.appListRef) {
- this.appid = this.$refs.appListRef.getCache();
- this.search()
- }
- },
- methods: {
- onqueryload(data) {
- this.exportExcelData = data
- },
- getWhere() {
- const query = this.query.trim()
- let queryStr = ''
- if (query) {
- const queryRe = new RegExp(query, 'i')
- queryStr = dbSearchFields.map(name => queryRe + '.test(' + name + ')').join(' || ')
- }
- if (this.appid) {
- if (query) {
- queryStr = `appid=='${this.appid}' && (${queryStr})`;
- } else {
- queryStr = `appid=='${this.appid}'`;
- }
- }
- return queryStr
- },
- search() {
- this.errorMessage = "";
- const newWhere = this.getWhere()
- this.where = newWhere
- this.$nextTick(() => {
- this.loadData()
- })
- },
- loadData(clear = true) {
- this.$refs.udb.loadData({
- clear
- })
- },
- onPageChanged(e) {
- this.selectedIndexs.length = 0
- this.$refs.table.clearSelection()
- this.$refs.udb.loadData({
- current: e.current
- })
- },
- navigateTo(url, clear) {
- // clear 表示刷新列表时是否清除页码,true 表示刷新并回到列表第 1 页,默认为 true
- uni.navigateTo({
- url,
- events: {
- refreshData: () => {
- this.loadData(clear)
- }
- }
- })
- },
- sortChange(e, name) {
- this.orderByFieldName = name;
- if (e.order) {
- this.orderby = name + ' ' + orderByMapping[e.order]
- } else {
- this.orderby = ''
- }
- this.$refs.table.clearSelection()
- this.$nextTick(() => {
- this.$refs.udb.loadData()
- })
- },
- filterChange(e, name) {
- this._filter[name] = {
- type: e.filterType,
- value: e.filter
- }
- let newWhere = filterToWhere(this._filter, db.command)
- if (Object.keys(newWhere).length) {
- this.where = newWhere
- } else {
- this.where = ''
- }
- this.$nextTick(() => {
- this.$refs.udb.loadData()
- })
- },
- // 编辑规则
- editRule(item) {
- // 显示弹窗
- this.$refs.editRulePopup.open();
- // 如果没有规则,则初始化一个空规则
- if (!item.page_rules || !item.page_rules.length) {
- item.page_rules = [
- []
- ];
- }
- this.pageInfo = {
- _id: item._id,
- page_rules: JSON.parse(JSON.stringify(item.page_rules)), // 深拷贝,解除引用关系
- };
- },
- // 添加一个规则
- addRulesItem() {
- this.pageInfo.page_rules.unshift([]);
- },
- // 删除一个规则
- deleteRulesItem(index1) {
- this.pageInfo.page_rules.splice(index1, 1);
- },
- // 添加一个参数
- addParamItem(index1) {
- this.editRulePopup.isAddParam = true;
- this.editRulePopup.addParamInfo.value = "";
- this.editRulePopup.addParamInfo.index1 = index1;
- },
- // 确认添加参数
- confirmAddParamItem(index1) {
- if (this.editRulePopup.addParamInfo.value) {
- this.pageInfo.page_rules[index1].push(this.editRulePopup.addParamInfo.value);
- }
- this.editRulePopup.isAddParam = false;
- },
- // 删除某一个参数
- deleteParamItem(index1, index2) {
- this.pageInfo.page_rules[index1].splice(index2, 1);
- },
- // 关闭编辑规则弹窗
- closeEditRulePopup() {
- this.$refs.editRulePopup.close();
- },
- // 保存规则
- saveRule() {
- this.editRulePopup.loading = true;
- // 过滤下空的规则
- let page_rules = JSON.parse(JSON.stringify(this.pageInfo.page_rules));
- page_rules = page_rules.filter(item => item.length > 0);
- // 保存到数据库
- this.$refs.udb.update(this.pageInfo._id, {
- page_rules
- }, {
- showToast: false,
- needLoading: false,
- success: () => {
- // 修改本地列表中的数据
- this.$refs.udb.dataList.forEach(item => {
- if (item._id === this.pageInfo._id) {
- item.page_rules = page_rules;
- }
- });
- // 关闭弹窗
- this.closeEditRulePopup();
- },
- complete: () => {
- this.editRulePopup.loading = false;
- }
- });
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .edit-rule-popup {
- padding: 20px;
- background-color: #fff;
- width: 900px;
- max-width: 90vw;
- .edit-rule-popup-tips {
- margin-top: 20px;
- }
- .edit-rule-popup-list {
- margin-top: 20px;
- .edit-rule-popup-item {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-top: 20px;
- color: #606266;
- font-size: 14px;
- word-break: break-all;
- &:first-child {
- margin-top: 0;
- }
- .name {
- width: 80px;
- }
- .tags {
- flex: 1;
- border: 1px solid #eee;
- padding: 5px 10px;
- display: flex;
- flex-wrap: wrap;
- .tags-item {
- display: inline-block;
- height: 32px;
- line-height: 30px;
- font-size: 12px;
- box-sizing: border-box;
- white-space: nowrap;
- margin: 5px;
- .text {
- margin-right: 8px;
- }
- &.tags-item-text {
- background-color: #ecf8f3;
- border-color: #d9f1e6;
- padding: 0 10px;
- color: #42b983;
- border-width: 1px;
- border-style: solid;
- border-radius: 4px;
- }
- &.tags-item-add {
- .tags-item-add-input {
- width: 100px;
- height: 32px;
- line-height: 32px;
- padding: 0 10px;
- box-sizing: border-box;
- border-radius: 4px;
- border: 1px solid #dcdfe6;
- font-size: 12px;
- color: #606266;
- outline: none;
- &:focus {
- border-color: #409eff;
- }
- }
- .tags-item-add-btn {
- height: 32px;
- line-height: 32px;
- }
- }
- }
- }
- .btn {
- width: 80px;
- text-align: center;
- }
- }
- }
- .edit-rule-popup-btn {
- /* 按钮显示在右边 */
- display: flex;
- justify-content: flex-end;
- margin-top: 20px;
- .btn {
- margin-left: 10px;
- }
- }
- .pointer {
- cursor: pointer;
- }
- }
- </style>
|