From eb43a3de6a83f30a6537f4f4d8e90af4e99495bd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=BD=97=E6=B5=AE?= <513711440@qq.com>
Date: Thu, 27 Jul 2023 17:37:04 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=90=88=E4=BD=9C=E4=BC=99?=
 =?UTF-8?q?=E4=BC=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/api/api.js                                |   7 +
 .../settled/partners/PartnersDetails.vue      | 504 ++++++++++++++++++
 src/views/settled/partners/PartnersList.vue   | 271 ++++++++++
 .../partners/modules/RoleDataruleModal.vue    | 120 +++++
 .../partners/modules/SelectRulesModal.vue     | 220 ++++++++
 .../partners/modules/UserRoleModal.vue        | 200 +++++++
 6 files changed, 1322 insertions(+)
 create mode 100644 src/views/settled/partners/PartnersDetails.vue
 create mode 100644 src/views/settled/partners/PartnersList.vue
 create mode 100644 src/views/settled/partners/modules/RoleDataruleModal.vue
 create mode 100644 src/views/settled/partners/modules/SelectRulesModal.vue
 create mode 100644 src/views/settled/partners/modules/UserRoleModal.vue

diff --git a/src/api/api.js b/src/api/api.js
index 30bdfd7..9086c35 100644
--- a/src/api/api.js
+++ b/src/api/api.js
@@ -114,6 +114,10 @@ const getCouncilsDetailApi = (params)=>getAction("/property-central/councils/pro
 const auditCouncilsApi = (params)=>postAction("/property-central/councils/propertyCouncils/audit",params);
 const freezeOrCouncilsApi = (params)=>getAction(`/property-central/councils/propertyCouncils/freezeOrThaw/${params.id}/${params.status}`,{});
 
+const getPartnersDetailApi = (params)=>getAction("/property-central/partners/partnersInfo/queryById",params);
+const auditPartnersApi = (params)=>postAction("/property-central/partners/partnersInfo/audit",params);
+const operatePartnersApi = (params)=>getAction(`/property-central/partners/partnersInfo/operate/${params.id}/${params.status}`,{});
+
 //费用管理
 const getCostListApi = (params)=>getAction("/property-central/property/propertyChargrule/list",params);
 const getCostDetailApi = (params)=>getAction("/property-central/property/propertyChargrule/queryById",params);
@@ -196,6 +200,9 @@ export {
   getCouncilsDetailApi,
   auditCouncilsApi,
   freezeOrCouncilsApi,
+  getPartnersDetailApi,
+  auditPartnersApi,
+  operatePartnersApi
 }
 
 
diff --git a/src/views/settled/partners/PartnersDetails.vue b/src/views/settled/partners/PartnersDetails.vue
new file mode 100644
index 0000000..f2dac0f
--- /dev/null
+++ b/src/views/settled/partners/PartnersDetails.vue
@@ -0,0 +1,504 @@
+<template>
+  <a-spin :spinning="confirmLoading">
+    <div class="title-top">
+      <h3>{{title}}</h3>
+      <div class="button"><a-button @click="onCancel">返回</a-button>
+        <a-button type="primary" @click="submitForm" v-if="pageType == 'edit' || pageType == 'add' ">保存</a-button>
+        <a-button type="danger" @click="onExamine(2)" v-if="pageType == 'audit'">审核驳回</a-button>
+        <a-button type="primary" @click="onExamine(1)" v-if="pageType == 'audit'">审核通过</a-button>
+      </div>
+    </div>
+
+    <j-form-container :disabled="pageType=='detail' || pageType=='audit'">
+      <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
+        <a-card title="合作伙伴基本信息">
+          <a-row>
+            <a-col :span="12">
+              <a-form-model-item label="合作伙伴名称" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="partnersName">
+                <a-input v-model="model.partnersName" placeholder="请输入合作伙伴名称"></a-input>
+              </a-form-model-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-model-item label="统一信用代码" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="creditCode">
+                <a-input v-model="model.creditCode" placeholder="请输入统一信用代码"></a-input>
+              </a-form-model-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-model-item label="法人姓名" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="legalName">
+                <a-input v-model="model.legalName" placeholder="请输入法人姓名"></a-input>
+              </a-form-model-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-model-item label="注册资本(万元)" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="registCapital">
+                <a-input-number v-model="model.registCapital" :min="1" placeholder="请输入注册资本" style="width: 100%" />
+              </a-form-model-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-model-item label="联系人" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="contactName">
+                <a-input v-model="model.contactName" placeholder="请输入联系人"></a-input>
+              </a-form-model-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-model-item label="联系人电话" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="contactPhone">
+                <a-input @blur="contactPhoneChange" v-model="model.contactPhone" placeholder="请输入联系人电话"></a-input>
+              </a-form-model-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-model-item label="注册地址" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="registAdress">
+                <area-cascader v-model="model.registAdress" :data="pcaa" :level="1" type="all" @change="addressChange"
+                  style="width:100%" />
+              </a-form-model-item>
+            </a-col>
+            <a-col :span="24">
+              <a-form-model-item label="详细地址" :labelCol="{ xs:{ span: 24 }, sm:{ span: 3 } }" :wrapperCol="wrapperCol"
+                prop="addressInfo">
+                <a-input v-model="model.addressInfo" placeholder="请输入详细地址" @blur="addressBlur"></a-input>
+              </a-form-model-item>
+            </a-col>
+            <a-col :span="24">
+              <a-form-model-item label="" :offset="3" :pull="3" :labelCol="{ xs:{ span: 24 }, sm:{ span: 3 } }">
+                <div class="hhh">
+                  <div id="container" style="width:100%;height:200px"></div>
+                </div>
+              </a-form-model-item>
+            </a-col>
+            <a-col :span="24">
+              <a-form-model-item label="介绍" :labelCol="{ xs:{ span: 24 }, sm:{ span: 3 } }" :wrapperCol="wrapperCol"
+                prop="partnersContent">
+                <a-textarea v-model="model.partnersContent" placeholder="请输入介绍" :maxLength="500"
+                  :auto-size="{ minRows: 3, maxRows: 5 }" />
+              </a-form-model-item>
+            </a-col>
+          </a-row>
+        </a-card>
+        <a-card title="授权信息">
+          <a-row>
+            <a-col :span="12">
+              <a-form-model-item label="授权开始日期" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="empowerBeginDate">
+                <j-date placeholder="请选择授权开始日期" v-model="model.empowerBeginDate" style="width: 100%" />
+              </a-form-model-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-model-item label="授权结束日期" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="empowerEndDate">
+                <j-date placeholder="请选择授权结束日期" v-model="model.empowerEndDate" style="width: 100%"
+                  :start="model.empowerBeginDate" />
+              </a-form-model-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-model-item label="分利规则" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="sharingRuleName">
+                <a-input v-model="model.sharingRuleName" placeholder="请选择分利规则" read-only>
+                  
+                  <a-icon slot="addonAfter" type="search" @click="chooseRules()" />
+                </a-input>
+              </a-form-model-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-model-item label="管理员账户" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="adminLoginName">
+                <a-input v-model="model.adminLoginName" placeholder="请输入管理员账户"></a-input>
+              </a-form-model-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-model-item label="管理员密码" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="adminPassword">
+                <a-input v-model="model.adminPassword" placeholder="请输入管理员密码"></a-input>
+              </a-form-model-item>
+            </a-col>
+            <a-col :span="12" style="position:relative">
+              <a-form-model-item label="访问域名前缀" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="accessAddress"
+                v-if="pageType=='add' || pageType=='edit'">
+                <a-input v-model="model.accessAddress" placeholder="请输入访问域名前缀"
+                  addon-after=".property.hjxbc.cn"></a-input>
+              </a-form-model-item>
+              <a-form-model-item label="访问域名" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="accessAddress"
+                :disabled="false" v-else>
+                <p v-if="model.accessAddress">{{ model.accessAddress }}.property.hjxbc.cn</p>
+              </a-form-model-item>
+              <a @click="onCopyLink" v-if="model.accessAddress"
+                style="position:absolute;top:0;right:-10px;line-height:40px;z-index:999;pointer-events:auto;">复制</a>
+            </a-col>
+          </a-row>
+        </a-card>
+        <a-card title="合同附件">
+          <a-row>
+            <a-col :span="24">
+              <a-form-model-item label="合同附件" :labelCol="{ xs:{ span: 24 }, sm:{ span: 3 } }" :wrapperCol="wrapperCol"
+                prop="contractUrl">
+                <j-upload v-model="model.contractUrl"></j-upload>
+              </a-form-model-item>
+            </a-col>
+          </a-row>
+        </a-card>
+      </a-form-model>
+    </j-form-container>
+    <Select-Rules-Modal ref="selectRulesModal" @selectFinished="selectRulesOK"></Select-Rules-Modal>
+  </a-spin>
+</template>
+
+<script>
+const mapZoom = [5, 8, 10, 12]
+let timer = null
+import { getPartnersDetailApi, auditPartnersApi } from '@/api/api'
+import { httpAction, getAction } from '@/api/manage'
+import { isMobile, validateCreditCode, alphanumeric } from '@/utils/validate'
+import SelectRulesModal from './modules/SelectRulesModal'
+
+export default {
+  name: 'PartnersDetails',
+  inject: ['closeCurrent'],
+  components: {
+    SelectRulesModal,
+  },
+  data() {
+    const validateToNextPhone = (rule, value, callback) => {
+      if (value && isMobile(value)) {
+        callback()
+      } else {
+        callback('请输入正确的联系人电话!')
+      }
+    }
+    const validateCode = (rule, value, callback) => {
+      if (value && validateCreditCode(value)) {
+        callback()
+      } else {
+        callback('社会统一信用代码输入错误')
+      }
+    }
+    const isAlphanumeric = (rule, value, callback) => {
+      if (value && alphanumeric(value)) {
+        callback()
+      } else {
+        callback('请输入带字母的域名前缀')
+      }
+    }
+    return {
+      title: '',
+      pageType: '',
+      pcaa: this.$Jpcaa,
+      model: {},
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 6 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      confirmLoading: false,
+      validatorRules: {
+        partnersName: [{ required: true, message: '请输入合作伙伴名称', trigger: 'blur' }],
+        creditCode: [{ required: true, message: '请输入统一信用代码', trigger: 'blur' }, { validator: validateCode }],
+        legalName: [{ required: true, message: '请输入法人代表', trigger: 'blur' }],
+        registCapital: [{ required: true, message: '请输入注册资本', trigger: 'blur' }],
+        contactName: [{ required: true, message: '请输入联系人', trigger: 'blur' }],
+        contactPhone: [
+          { required: true, message: '请输入联系人电话', trigger: 'blur' },
+          { validator: validateToNextPhone },
+        ],
+        registAdress: [{ required: true, message: '请选择注册地址', trigger: 'change' }],
+        addressInfo: [{ required: true, message: '请输入详细地址', trigger: 'blur' }],
+        //logoUrl: [{ required: true, message: '请上传集团LOGO', trigger: 'change' }],
+        empowerBeginDate: [{ required: true, message: '请选择授权开始日期', trigger: 'change' }],
+        empowerEndDate: [{ required: true, message: '请选择权结束日期', trigger: 'change' }],
+        sharingRuleName: [{ required: true, message: '请选择分利规则', trigger: 'change' }],
+        adminLoginName: [{ required: true, message: '请输入管理员账号', trigger: 'blur' }],
+        adminPassword: [{ required: true, message: '请输入管理员密码', trigger: 'blur' }],
+        accessAddress: [
+          { required: true, message: '请输入访问域名前缀', trigger: 'blur' },
+          { validator: isAlphanumeric },
+        ],
+        contractUrl: [{ required: true, message: '请上传合同附件', trigger: 'change' }],
+      },
+      url: {
+        add: '/property-central/partners/partnersInfo/add',
+        edit: '/property-central/partners/partnersInfo/edit',
+      },
+      costList: [],
+      mapRef: null,
+      sharingRuleId:[]
+    }
+  },
+  computed: {
+    formDisabled() {
+      return this.disabled
+    },
+  },
+  watch: {
+    'model.addressInfo': {
+      handler(newV) {
+        if (newV) {
+          clearTimeout(timer)
+          timer = setTimeout(() => {
+            // this.getLongitude(this.model.categoryCodes[0], this.model.categoryCodes.join('') + newV, mapZoom[3])
+          }, 1000)
+        }
+      },
+    },
+  },
+  created() {
+    this.pageType = this.$route.query.type
+    if (this.$route.query.type == 'add') {
+      this.title = '新增'
+    } else if (this.$route.query.type == 'edit') {
+      this.title = '编辑'
+    } else if (this.$route.query.type == 'audit') {
+      this.title = '审核'
+    } else if (this.$route.query.type == 'detail') {
+      this.title = '详情'
+    }
+    if (this.$route.query.id) {
+      this.getPageDetail()
+    }
+  },
+  mounted() {
+    this.mapRef = new BMapGL.Map('container') // 创建地图实例
+    var point = new BMapGL.Point(108.5525, 34.3237) // 创建点坐标
+    this.mapRef.centerAndZoom(point, mapZoom[0])
+    // var zoomCtrl = new BMapGL.ZoomControl();  // 添加缩放控件
+    // this.mapRef.addControl(zoomCtrl);
+    this.mapRef.enableScrollWheelZoom(true) //开启鼠标滚轮缩放
+    this.mapRef.addEventListener('click', (e) => this.getAddress(e))
+  },
+  methods: {
+    async getPageDetail() {
+      let { result } = await getPartnersDetailApi({ id: this.$route.query.id })
+      this.edit(result)
+      if (result.provinceName) {
+        this.getLongitude(
+          result.provinceName,
+          result.provinceName + result.cityName + result.countyName + result.addressInfo,
+          mapZoom[3]
+        )
+      }
+    },
+    onCancel() {
+      this.closeCurrent()
+      this.$router.go(-1)
+    },
+    //选择分利规则
+    chooseRules() {
+      this.sharingRuleId = this.model.sharingRuleId.split(',')
+      console.log(this.sharingRuleId)
+      console.log(11111)
+      this.$refs.selectRulesModal.visible = true
+      this.$refs.selectRulesModal.selectedRowKeys = this.sharingRuleId
+    },
+    selectRulesOK(data) {
+      console.log(data)
+      let sharingRuleId = ''
+      let sharingRuleName = ''
+      for (var a = 0; a < data.length; a++) {
+        sharingRuleId += data[a].id + ',';
+        sharingRuleName += data[a].ruleName + ',';
+      }
+      sharingRuleId = sharingRuleId.substring(0, sharingRuleId.lastIndexOf(','));
+      this.$set(this.model,'sharingRuleId',sharingRuleId);
+      this.$set(this.model,'sharingRuleName',sharingRuleName);
+    },
+    contactPhoneChange(e) {
+      if (!this.model.adminLoginName) {
+        this.model.adminLoginName = e.target.value
+      }
+    },
+    edit(record) {
+      console.log(record)
+      this.model = Object.assign({}, record.partnersInfo)
+      this.model.registAdress = [
+        record.partnersInfo.provinceCode,
+        record.partnersInfo.cityCode,
+        record.partnersInfo.countyCode,
+      ]
+      this.visible = true
+      
+      //
+      let list = record.partnersInfo.shareRuleList;
+      let sharingRuleName = ''
+      for (var a = 0; a < list.length; a++) {
+        sharingRuleName += list[a].ruleName + ',';
+      }
+      this.$set(this.model,'sharingRuleName',sharingRuleName);
+    },
+    onExamine(type) {
+      const that = this
+      if (type == 1) {
+        return auditPartnersApi({
+          id: this.$route.query.id,
+          auditStatus: 'auditPass',
+        }).then((res) => {
+          that.$message.success('审核通过成功')
+          that.$emit('ok')
+          this.onCancel()
+        })
+      } else if (type == 2) {
+        return auditPartnersApi({
+          id: this.$route.query.id,
+          auditStatus: 'refuse',
+        }).then((res) => {
+          that.$message.success('审核驳回成功')
+          this.onCancel()
+        })
+      }
+    },
+    addressChange(val) {
+      const province = Object.keys(val[0])[0]
+      const city = Object.keys(val[1])[0]
+      const county = Object.keys(val[2])[0]
+      this.model.provinceName = val[0][province]
+      this.model.provinceCode = province
+      this.model.cityName = val[1][city]
+      this.model.cityCode = city
+      this.model.countyName = val[2][county]
+      this.model.countyCode = county
+      if (this.model.addressInfo) {
+        this.getLongitude(
+          this.model.provinceName,
+          this.model.provinceName + this.model.cityName + this.model.countyName + this.model.addressInfo,
+          mapZoom[3]
+        )
+      }
+    },
+    addressBlur(val) {
+      if (this.model.provinceName) {
+        this.getLongitude(
+          this.model.provinceName,
+          this.model.provinceName + this.model.cityName + this.model.countyName + val.target.value,
+          mapZoom[3]
+        )
+      }
+    },
+    getAddress(e) {
+      let _this = this
+      // 创建地理编码实例
+      var myGeo = new BMapGL.Geocoder()
+      // 根据坐标得到地址描述
+      myGeo.getLocation(new BMapGL.Point(e.latlng.lng, e.latlng.lat), function (result) {
+        if (result) {
+          _this.mapRef.clearOverlays()
+          _this.model.registAdress = [
+            result.addressComponents.province,
+            result.addressComponents.city,
+            result.addressComponents.district,
+          ]
+          _this.model.addressInfo = result.addressComponents.street + result.addressComponents.streetNumber
+          _this.model.longitude = result.point.lng
+          _this.model.latitude = result.point.lat
+          _this.positionMap(e.latlng.lng, e.latlng.lat, mapZoom[3], result.address)
+          console.log(result)
+        }
+      })
+    },
+    positionMap(mapCenterLng, mapCenterLat, mapzoom, address) {
+      var point = new BMapGL.Point(mapCenterLng, mapCenterLat) // 创建点坐标
+      this.mapRef.centerAndZoom(point, mapzoom)
+      var marker = new BMapGL.Marker(point, { title: address }) // 创建标注
+      this.mapRef.addOverlay(marker) // 将标注添加到地图中
+      let _this = this
+      // marker.addEventListener("click", function(){
+      var label = new BMapGL.Label(address, {
+        // 创建文本标注
+        position: point, // 设置标注的地理位置
+        offset: new BMapGL.Size(0, -55), // 设置标注的偏移量
+      })
+      _this.mapRef.addOverlay(label) // 将标注添加到地图中
+      label.setStyle({
+        // 设置label的样式
+        color: '#333',
+        fontSize: '14px',
+        padding: '4px 10px',
+        border: '1px solid #1E90FF',
+        borderRadius: '4px',
+        transform: 'translateX(-40%)',
+      })
+      // });
+    },
+    getLongitude(city, address, zoom) {
+      let _this = this
+      var myGeo = new BMapGL.Geocoder()
+      myGeo.getPoint(
+        address,
+        function (point) {
+          if (point) {
+            _this.mapRef.clearOverlays()
+            _this.model.longitude = point.lng
+            _this.model.latitude = point.lat
+            _this.positionMap(point.lng, point.lat, zoom, address)
+          } else {
+            console.log('您选择的地址没有解析到结果!')
+          }
+        },
+        city
+      )
+    },
+    onCopyLink() {
+      let txa = document.createElement('textarea')
+      txa.value = this.model.accessAddress + '.partner.hjxbc.cn'
+      document.body.appendChild(txa)
+      txa.select()
+      document.execCommand('copy')
+      document.body.removeChild(txa)
+      this.$message.success('复制成功!')
+    },
+    submitForm() {
+      const that = this
+      // 触发表单验证
+      this.$refs.form.validate((valid) => {
+        if (valid) {
+          that.confirmLoading = true
+          let httpurl = ''
+          let method = ''
+          if (!this.model.id) {
+            httpurl += this.url.add
+            method = 'post'
+          } else {
+            httpurl += this.url.edit
+            method = 'put'
+          }
+          this.model.registAdress = undefined
+          httpAction(httpurl, this.model, method)
+            .then((res) => {
+              if (res.success) {
+                that.$message.success(res.message)
+                that.$emit('ok')
+                this.onCancel()
+              } else {
+                that.$message.warning(res.message)
+              }
+            })
+            .finally(() => {
+              that.confirmLoading = false
+            })
+        }
+      })
+    },
+  },
+  beforeDestroy() {
+    clearTimeout(timer)
+    this.mapRef.removeEventListener('click', (e) => this.getAddress(e))
+  },
+}
+</script>
+<style lang="less" scoped>
+.title-top {
+  background: #fff;
+  padding: 0 25px;
+  line-height: 50px;
+  height: 50px;
+  margin-bottom: 5px;
+  h3 {
+    font-weight: bold;
+    display: inline-block;
+  }
+  .button {
+    float: right;
+    .ant-btn {
+      margin-left: 15px;
+    }
+  }
+}
+</style>
+<style>
+.area-select {
+  width: 100% !important;
+}
+.anchorBL {
+  visibility: hidden;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/settled/partners/PartnersList.vue b/src/views/settled/partners/PartnersList.vue
new file mode 100644
index 0000000..c2bfc11
--- /dev/null
+++ b/src/views/settled/partners/PartnersList.vue
@@ -0,0 +1,271 @@
+<template>
+  <a-card :bordered="false">
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+          <a-col :md="6" :sm="8">
+            <a-form-item label="合作伙伴名称">
+              <j-input placeholder="请输入合作伙伴名称" v-model="queryParam.partnersName"></j-input>
+            </a-form-item>
+          </a-col>
+          <a-col :md="6" :sm="8">
+            <a-form-item label="入驻开始时间">
+              <a-date-picker placeholder="入驻开始时间" valueFormat="YYYY-MM-DD"
+                v-model="queryParam.createTime_begin"></a-date-picker>
+            </a-form-item>
+          </a-col>
+          <a-col :md="6" :sm="8">
+            <a-form-item label="入驻结束时间">
+              <a-date-picker placeholder="入驻结束时间" valueFormat="YYYY-MM-DD"
+                v-model="queryParam.createTime_end"></a-date-picker>
+            </a-form-item>
+          </a-col>
+          <!-- <a-col :md="8" :sm="10">
+            <a-form-item label="入驻时间">
+              <a-range-picker v-model="queryParam.propertyTime" />
+            </a-form-item>
+          </a-col> -->
+          <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+            <a-col :md="6" :sm="24">
+              <a-button type="primary" @click="searchQuery">查询</a-button>
+              <a-button style="margin-left: 8px" @click="searchReset">重置</a-button>
+            </a-col>
+          </span>
+        </a-row>
+      </a-form>
+    </div>
+
+    <!-- 操作按钮区域 -->
+    <div class="table-operator">
+      <a-button @click="propertyDetails(1)" type="primary" icon="plus">新增</a-button>
+      <!-- <a-button type="primary" icon="download" @click="handleExportXls('t_property_settled')">导出</a-button> -->
+      <a-dropdown v-if="selectedRowKeys.length > 0">
+        <a-menu slot="overlay">
+          <a-menu-item key="1" @click="batchDel"><a-icon type="delete" />删除</a-menu-item>
+        </a-menu>
+        <a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
+      </a-dropdown>
+    </div>
+
+    <!-- table区域-begin -->
+    <div>
+      <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+        <i class="anticon anticon-info-circle ant-alert-icon"></i>已选择&nbsp;<a style="font-weight: 600">{{
+        selectedRowKeys.length }}</a>项&nbsp;&nbsp;
+        <a style="margin-left: 24px" v-if="selectedRowKeys.length > 0" @click="onClearSelected">清空</a>
+      </div>
+
+      <a-table ref="table" size="middle" :scroll="{x:true}" bordered rowKey="id" :columns="columns"
+        :dataSource="dataSource" :pagination="pagination" :loading="loading" class="j-table-force-nowrap"
+        @change="handleTableChange">
+        <span slot="empowerEndDate" slot-scope="text, record">
+          <span v-if="record.empowerEndDate">{{record.empowerBeginDate}} 至 {{record.empowerEndDate}} </span>
+        </span>
+        <span slot="partnersStatus" slot-scope="text, record">
+          <span>{{record.partnersStatus === 'normal' ? '正常' : '冻结'}}</span>
+        </span>
+        <span slot="expirationStatus" slot-scope="text, record">
+          <a-tag>{{record.expirationStatus === 'notStarted' ? '未开始' :record.expirationStatus === 'normal' ? '正常' :record.expirationStatus === 'soonExpired' ? '即将到期' :record.expirationStatus === 'expire' ? '已过期' : ''}}</a-tag>
+        </span>
+        <span slot="action" slot-scope="text, record">
+
+          <a href="javascript:;" @click="propertyDetails(4, record.id)">详情</a>
+
+          <a-divider type="vertical" />
+          <a-dropdown>
+            <a class="ant-dropdown-link">
+              更多 <a-icon type="down" />
+            </a>
+            <a-menu slot="overlay">
+              <a-menu-item v-if="record.auditStatus === 'auditPass'">
+                <a @click="handlePerssion(record.roleId)">授权</a>
+              </a-menu-item>
+              <a-menu-item>
+                <a href="javascript:;" @click="propertyDetails(2, record.id)"
+                  v-if="record.auditStatus != 'waitAudit'">编辑</a>
+              </a-menu-item>
+              <a-menu-item v-if="record.auditStatus === 'waitAudit'">
+                <a href="javascript:;" @click="propertyDetails(3, record.id)">审核</a>
+              </a-menu-item>
+              <a-menu-item v-if="record.auditStatus === 'auditPass'">
+                <a href="javascript:;"
+                  @click="onStatus(record)">{{record.partnersStatus === 'normal' ? '冻结' : '解冻'}}</a>
+              </a-menu-item>
+              <a-menu-item>
+                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)" placement="topLeft">
+                  <a style="color: #f00;">删除</a>
+                </a-popconfirm>
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown>
+        </span>
+      </a-table>
+
+    </div>
+    <!-- table区域-end -->
+    <!-- 右侧的角色权限配置 -->
+    <user-role-modal ref="modalUserRole"></user-role-modal>
+  </a-card>
+</template>
+
+<script>
+import { operatePartnersApi } from '@/api/api'
+import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+import { filterDictTextByCache } from '@/components/dict/JDictSelectUtil'
+import UserRoleModal from './modules/UserRoleModal'
+
+const columns = [
+  {
+    title: '合作伙伴名称',
+    dataIndex: 'partnersName',
+    key: 'partnersName',
+    align: 'center',
+  },
+  {
+    title: '统一社会信用代码',
+    dataIndex: 'creditCode',
+    key: 'creditCode',
+    align: 'center',
+  },
+  {
+    title: '联系人',
+    dataIndex: 'contactName',
+    key: 'contactName',
+    align: 'center',
+  },
+  {
+    title: '电话',
+    dataIndex: 'contactPhone',
+    key: 'contactPhone',
+    align: 'center',
+  },
+  {
+    title: '授权时间',
+    dataIndex: 'empowerEndDate',
+    scopedSlots: { customRender: 'empowerEndDate' },
+    align: 'center',
+  },
+  {
+    title: '推广商铺数量',
+    dataIndex: 'empowerCommunityNum',
+    key: 'empowerCommunityNum',
+    align: 'center',
+  },
+  {
+    title: '推广费用合计',
+    dataIndex: 'empowerCommunityNum1',
+    key: 'empowerCommunityNum1',
+    align: 'center',
+  },
+  {
+    title: '审核状态',
+    dataIndex: 'auditStatus',
+    key: 'auditStatus',
+    customRender: function (text) {
+      return filterDictTextByCache('auditStatus', text)
+    },
+  },
+  {
+    title: '到期提示',
+    dataIndex: 'expirationStatus',
+    scopedSlots: { customRender: 'expirationStatus' },
+    key: 'expirationStatus',
+    align: 'center',
+  },
+  {
+    title: '冻结状态',
+    dataIndex: 'partnersStatus',
+    scopedSlots: { customRender: 'partnersStatus' },
+    key: 'partnersStatus',
+    align: 'center',
+  },
+  {
+    title: '操作',
+    dataIndex: 'action',
+    scopedSlots: { customRender: 'action' },
+    align: 'center',
+    fixed: 'right',
+    width: 150,
+  },
+]
+
+export default {
+  name: 'PartnersList',
+  mixins: [JeecgListMixin],
+  components: { UserRoleModal },
+  data() {
+    return {
+      columns: columns,
+      loading: false,
+      pagination: {},
+      url: {
+        list: '/property-central/partners/partnersInfo/list',
+        delete: '/property-central/partners/partnersInfo/delete',
+        deleteBatch: '/property-central/partners/partnersInfo/deleteBatch',
+      },
+    }
+  },
+  methods: {
+    propertyDetails(type, id) {
+      if (type == 1) {
+        this.$router.push({
+          path: '/settled/partners/PartnersDetails?type=add',
+        })
+      } else if (type == 2) {
+        this.$router.push({
+          path: '/settled/partners/PartnersDetails?type=edit&id=' + id,
+        })
+      } else if (type == 3) {
+        this.$router.push({
+          path: '/settled/partners/PartnersDetails?type=audit&id=' + id,
+        })
+      } else if (type == 4) {
+        this.$router.push({
+          path: '/settled/partners/PartnersDetails?type=detail&id=' + id,
+        })
+      }
+    },
+    // onLoadDetail(record, type) {
+    //   record['registAdress'] = [record.provinceCode, record.cityCode, record.countyCode]
+    //   if (type === 'edit') {
+    //     this.handleEdit(record)
+    //   } else {
+    //     this.handleDetail(record)
+    //   }
+    // },
+    // onChange(date, dateString) {
+    //   if (dateString.length > 0) {
+    //     this.queryParam.createTime_begin = dateString[0]
+    //     this.queryParam.createTime_end = dateString[1]
+    //   } else {
+    //     this.queryParam.createTime_begin = ''
+    //     this.queryParam.createTime_end = ''
+    //   }
+    // },
+    onStatus(record) {
+      let that = this
+      this.$confirm({
+        title: `确认${record.partnersStatus === 'normal' ? '冻结' : '解冻'}此合作伙伴?`,
+        closable: true,
+        okText: `${record.partnersStatus === 'normal' ? '冻结' : '解冻'}`,
+        onOk() {
+          return operatePartnersApi({
+            id: record.id,
+            status: `${record.partnersStatus === 'normal' ? 'freeze' : 'normal'}`,
+          }).then((res) => {
+            that.searchQuery()
+          })
+        },
+        onCancel() {},
+      })
+    },
+    handlePerssion(roleId) {
+      this.$refs.modalUserRole.show(roleId)
+    },
+  },
+}
+</script>
+<style scoped>
+@import '~@assets/less/common.less';
+</style>
\ No newline at end of file
diff --git a/src/views/settled/partners/modules/RoleDataruleModal.vue b/src/views/settled/partners/modules/RoleDataruleModal.vue
new file mode 100644
index 0000000..bb5b75b
--- /dev/null
+++ b/src/views/settled/partners/modules/RoleDataruleModal.vue
@@ -0,0 +1,120 @@
+<template>
+  <a-drawer
+    title="数据规则/按钮权限配置"
+    width="365"
+    :closable="false"
+    @close="onClose"
+    :visible="visible"
+  >
+
+    <a-tabs defaultActiveKey="1">
+      <a-tab-pane tab="数据规则" key="1">
+
+        <a-checkbox-group v-model="dataruleChecked" v-if="dataruleList.length>0">
+          <a-row>
+            <a-col :span="24" v-for="(item,index) in dataruleList" :key=" 'dr'+index ">
+              <a-checkbox :value="item.id">{{ item.ruleName }}</a-checkbox>
+            </a-col>
+
+            <a-col :span="24">
+              <div style="width: 100%;margin-top: 15px">
+                <a-button @click="saveDataruleForRole" type="primary" size="small" icon="save">点击保存</a-button>
+              </div>
+            </a-col>
+          </a-row>
+        </a-checkbox-group>
+        <div v-else><h3>无配置信息!</h3></div>
+
+      </a-tab-pane>
+      <!--<a-tab-pane tab="按钮权限" key="2">敬请期待!!!</a-tab-pane>-->
+    </a-tabs>
+
+  </a-drawer>
+</template>
+
+<script>
+  import ARow from 'ant-design-vue/es/grid/Row'
+  import ACol from 'ant-design-vue/es/grid/Col'
+  import { getAction,postAction } from '@/api/manage'
+
+  export default {
+    name: 'RoleDataruleModal',
+    components: { ACol, ARow },
+    data(){
+      return {
+        functionId:'',
+        roleId:'',
+        visible:false,
+        tabList: [{
+          key: '1',
+          tab: '数据规则',
+        }, {
+          key: '2',
+          tab: '按钮权限',
+        }],
+        activeTabKey: '1',
+        url:{
+          datarule:"/sys/role/datarule",
+        },
+        dataruleList:[],
+        dataruleChecked:[]
+      }
+    },
+    methods:{
+      loadData(){
+        getAction(`${this.url.datarule}/${this.functionId}/${this.roleId}`).then(res=>{
+          console.log(res)
+          if(res.success){
+            this.dataruleList = res.result.datarule
+            let drChecked = res.result.drChecked
+            if(drChecked){
+              this.dataruleChecked = drChecked.split(",")
+            }
+          }
+        })
+      },
+      saveDataruleForRole(){
+        if(!this.dataruleChecked || this.dataruleChecked.length==0){
+          this.$message.warning("请注意,现未勾选任何数据权限!")
+        }
+        let params = {
+          permissionId:this.functionId,
+          roleId:this.roleId,
+          dataRuleIds:this.dataruleChecked.join(",")
+        }
+        console.log("保存数据权限",params)
+        postAction(this.url.datarule,params).then(res=>{
+          if(res.success){
+            this.$message.success(res.message)
+          }else{
+            this.$message.error(res.message)
+          }
+        })
+      },
+      show(functionId,roleId){
+        this.onReset()
+        this.functionId = functionId
+        this.roleId = roleId
+        this.visible=true
+        this.loadData()
+      },
+      onClose(){
+        this.visible=false
+        this.onReset()
+      },
+      onTabChange (key) {
+        this.activeTabKey = key
+      },
+      onReset(){
+        this.functionId=''
+        this.roleId=''
+        this.dataruleList=[]
+        this.dataruleChecked=[]
+      }
+    }
+  }
+</script>
+
+<style scoped>
+
+</style>
\ No newline at end of file
diff --git a/src/views/settled/partners/modules/SelectRulesModal.vue b/src/views/settled/partners/modules/SelectRulesModal.vue
new file mode 100644
index 0000000..285c644
--- /dev/null
+++ b/src/views/settled/partners/modules/SelectRulesModal.vue
@@ -0,0 +1,220 @@
+<template>
+  <div>
+    <a-modal
+      centered
+      :title="title"
+      :width="1000"
+      :visible="visible"
+      @ok="selectRulesOK"
+      @cancel="handleCancel"
+      cancelText="关闭">
+      <!-- 查询区域 -->
+      <div class="table-page-search-wrapper">
+        <a-form layout="inline"  @keyup.enter.native="searchQuery">
+          <a-row :gutter="24">
+            <a-col :span="10">
+              <a-form-item label="分利规则名称">
+                <a-input placeholder="请输入分利规则名称" v-model="queryParam.ruleName"></a-input>
+              </a-form-item>
+            </a-col>
+            <a-col :span="8">
+                    <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+                      <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+                      <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
+                    </span>
+            </a-col>
+          </a-row>
+        </a-form>
+      </div>
+      <!-- table区域-begin -->
+      <div>
+        <a-table
+          size="small"
+          bordered
+          rowKey="id"
+          :columns="columns"
+          :dataSource="dataSource1"
+          :pagination="ipagination"
+          :loading="loading"
+          :scroll="{ y: 240 }"
+          :rowSelection="{selectedRowKeys: selectedRowKeys,onSelect:onSelect,onChange: onSelectChange}"
+          @change="handleTableChange">
+
+        </a-table>
+      </div>
+      <!-- table区域-end -->
+
+
+    </a-modal>
+  </div>
+</template>
+
+<script>
+  import {filterObj} from '@/utils/util'
+  import {getAction} from '@/api/manage'
+
+  export default {
+    name: "selectRulesModal",
+    data() {
+      return {
+        title: "选择小区",
+        names: [],
+        visible: false,
+        // 查询条件
+        queryParam: {},
+        // 表头
+        columns: [
+          {
+            title: '分利规则名称',
+            align: "center",
+            width: 100,
+            dataIndex: 'ruleName'
+          },
+          {
+            title: '判断条件',
+            align: "center",
+            width: 100,
+            dataIndex: 'judgingCondition'
+          },
+          {
+            title: 'sass总平台分利',
+            align: "center",
+            width: 150,
+            dataIndex: 'saasBenefits'
+          },
+          {
+            title: '合作伙伴分利',
+            align: "center",
+            width: 100,
+            dataIndex: 'partnerBenefits'
+          },
+          {
+            title: '小区分利',
+            align: "center",
+            width: 100,
+            dataIndex: 'communityBenefits'
+          },
+        ],
+
+        //数据集
+        dataSource1: [],
+        // 分页参数
+        ipagination: {
+          current: 1,
+          pageSize: 10,
+          pageSizeOptions: ['10', '20', '30'],
+          showTotal: (total, range) => {
+            return range[0] + "-" + range[1] + " 共" + total + "条"
+          },
+          showQuickJumper: true,
+          showSizeChanger: true,
+          total: 0
+        },
+        isorter: {
+          column: 'createTime',
+          order: 'desc',
+        },
+        loading: false,
+        selectedRowKeys: [],
+        selectedRows: [],
+        selectedCurrently:[],
+        // selectedRowKeys:[],
+        url: {
+          list: "/property-central/sharerule/shareRule/list",
+        }
+      }
+    },
+    created() {
+      this.loadData();
+    },
+    methods: {
+      searchQuery() {
+        this.loadData(1);
+      },
+      searchReset() {
+        this.queryParam = {};
+        this.loadData(1);
+      },
+      handleCancel() {
+        this.visible = false;
+      },
+      selectRulesOK() {
+        this.$emit("selectFinished", this.selectedCurrently);
+        this.visible = false;
+      },
+      loadData(arg) {
+        //加载数据 若传入参数1则加载第一页的内容
+        if (arg === 1) {
+          this.ipagination.current = 1;
+        }
+        var params = this.getQueryParams();//查询条件
+        getAction(this.url.list, params).then((res) => {
+          if (res.success) {
+            this.dataSource1 = res.result.records;
+            this.ipagination.total = res.result.total;
+          }
+        })
+      },
+      getQueryParams() {
+        var param = Object.assign({}, this.queryParam, this.isorter);
+        param.pageNo = this.ipagination.current;
+        param.pageSize = this.ipagination.pageSize;
+        return filterObj(param);
+      },
+      onSelect(record, selected) {
+        // if (selected === true) {
+        //   this.selectedCurrently = record;
+        // }
+      },
+      onSelectChange(selectedRowKeys, selectedRows) {
+        this.selectedRowKeys = selectedRowKeys;
+        this.selectionRows = selectedRows;
+        this.selectedCurrently = selectedRows;
+        
+      },
+      handleTableChange(pagination, filters, sorter) {
+        //分页、排序、筛选变化时触发
+        console.log(sorter);
+        //TODO 筛选
+        if (Object.keys(sorter).length > 0) {
+          this.isorter.column = sorter.field;
+          this.isorter.order = "ascend" == sorter.order ? "asc" : "desc"
+        }
+        this.ipagination = pagination;
+        this.loadData();
+      }
+    }
+  }
+</script>
+<style lang="less" scoped>
+  .ant-card-body .table-operator {
+    margin-bottom: 18px;
+  }
+
+  .ant-table-tbody .ant-table-row td {
+    padding-top: 15px;
+    padding-bottom: 15px;
+  }
+
+  .anty-row-operator button {
+    margin: 0 5px
+  }
+
+  .ant-btn-danger {
+    background-color: #ffffff
+  }
+
+  .ant-modal-cust-warp {
+    height: 100%
+  }
+
+  .ant-modal-cust-warp .ant-modal-body {
+    height: calc(100% - 110px) !important;
+    overflow-y: auto
+  }
+
+  .ant-modal-cust-warp .ant-modal-content {
+    height: 90% !important;
+    overflow-y: hidden
+  }
+</style>
\ No newline at end of file
diff --git a/src/views/settled/partners/modules/UserRoleModal.vue b/src/views/settled/partners/modules/UserRoleModal.vue
new file mode 100644
index 0000000..8dd5c28
--- /dev/null
+++ b/src/views/settled/partners/modules/UserRoleModal.vue
@@ -0,0 +1,200 @@
+<template>
+  <a-drawer
+    :title="title"
+    :maskClosable="true"
+    width=650
+    placement="right"
+    :closable="true"
+    @close="close"
+    :visible="visible"
+    style="overflow: auto;padding-bottom: 53px;">
+
+    <a-form>
+      <a-form-item label='所拥有的权限'>
+        <a-tree
+          checkable
+          @check="onCheck"
+          :checkedKeys="checkedKeys"
+          :treeData="treeData"
+          @expand="onExpand"
+          @select="onTreeNodeSelect"
+          :selectedKeys="selectedKeys"
+          :expandedKeys="expandedKeysss"
+          :checkStrictly="checkStrictly">
+          <span slot="hasDatarule" slot-scope="{slotTitle,ruleFlag}">
+            {{ slotTitle }}<a-icon v-if="ruleFlag" type="align-left" style="margin-left:5px;color: red;"></a-icon>
+          </span>
+        </a-tree>
+      </a-form-item>
+    </a-form>
+
+    <div class="drawer-bootom-button">
+      <a-dropdown style="float: left" :trigger="['click']" placement="topCenter">
+        <a-menu slot="overlay">
+          <a-menu-item key="1" @click="switchCheckStrictly(1)">父子关联</a-menu-item>
+          <a-menu-item key="2" @click="switchCheckStrictly(2)">取消关联</a-menu-item>
+          <a-menu-item key="3" @click="checkALL">全部勾选</a-menu-item>
+          <a-menu-item key="4" @click="cancelCheckALL">取消全选</a-menu-item>
+          <a-menu-item key="5" @click="expandAll">展开所有</a-menu-item>
+          <a-menu-item key="6" @click="closeAll">合并所有</a-menu-item>
+        </a-menu>
+        <a-button>
+          树操作 <a-icon type="up" />
+        </a-button>
+      </a-dropdown>
+      <a-popconfirm title="确定放弃编辑?" @confirm="close" okText="确定" cancelText="取消">
+        <a-button style="margin-right: .8rem">取消</a-button>
+      </a-popconfirm>
+      <a-button @click="handleSubmit(false)" type="primary" :loading="loading" ghost style="margin-right: 0.8rem">仅保存</a-button>
+      <a-button @click="handleSubmit(true)" type="primary" :loading="loading">保存并关闭</a-button>
+    </div>
+
+    <role-datarule-modal ref="datarule"></role-datarule-modal>
+
+  </a-drawer>
+
+</template>
+<script>
+  import {queryTreeListByTypeForRole,queryRolePermission,saveRolePermission} from '@/api/api'
+  import RoleDataruleModal from './RoleDataruleModal.vue'
+
+  export default {
+    name: "RoleModal",
+    components:{
+      RoleDataruleModal
+    },
+    data(){
+      return {
+        roleId:"",
+        treeData: [],
+        defaultCheckedKeys:[],
+        checkedKeys:[],
+        expandedKeysss:[],
+        allTreeKeys:[],
+        autoExpandParent: true,
+        checkStrictly: false,
+        title:"物业权限配置",
+        visible: false,
+        loading: false,
+        selectedKeys:[]
+      }
+    },
+    methods: {
+      onTreeNodeSelect(id){
+        if(id && id.length>0){
+          this.selectedKeys = id
+        }
+        this.$refs.datarule.show(this.selectedKeys[0],this.roleId)
+      },
+      onCheck (o) {
+        if(this.checkStrictly){
+          this.checkedKeys = o.checked;
+        }else{
+          this.checkedKeys = o
+        }
+      },
+      show(roleId){
+        this.roleId=roleId
+        this.visible = true;
+      },
+      close () {
+        this.reset()
+        this.$emit('close');
+        this.visible = false;
+      },
+      onExpand(expandedKeys){
+        this.expandedKeysss = expandedKeys;
+        this.autoExpandParent = false
+      },
+      reset () {
+        this.expandedKeysss = []
+        this.checkedKeys = []
+        this.defaultCheckedKeys = []
+        this.loading = false
+      },
+      expandAll () {
+        this.expandedKeysss = this.allTreeKeys
+      },
+      closeAll () {
+        this.expandedKeysss = []
+      },
+      checkALL () {
+        this.checkedKeys = this.allTreeKeys
+      },
+      cancelCheckALL () {
+        //this.checkedKeys = this.defaultCheckedKeys
+        this.checkedKeys = []
+      },
+      switchCheckStrictly (v) {
+        if(v==1){
+          this.checkStrictly = false
+        }else if(v==2){
+          this.checkStrictly = true
+        }
+      },
+      handleCancel () {
+        this.close()
+      },
+      handleSubmit(exit) {
+        let that = this;
+        let params =  {
+          roleId:that.roleId,
+          permissionIds:that.checkedKeys.join(","),
+          lastpermissionIds:that.defaultCheckedKeys.join(","),
+        };
+        that.loading = true;
+        console.log("请求参数:",params);
+        saveRolePermission(params).then((res)=>{
+          if(res.success){
+            that.$message.success(res.message);
+            that.loading = false;
+            if (exit) {
+              that.close()
+            }
+          }else {
+            that.$message.error(res.message);
+            that.loading = false;
+            if (exit) {
+              that.close()
+            }
+          }
+          this.loadData();
+        })
+      },
+      loadData(){
+        queryTreeListByTypeForRole({platformType: 'partner'}).then((res) => {
+          this.treeData = res.result.treeList
+          this.allTreeKeys = res.result.ids
+          queryRolePermission({roleId:this.roleId}).then((res)=>{
+              this.checkedKeys = [...res.result];
+              this.defaultCheckedKeys = [...res.result];
+              this.expandedKeysss = this.allTreeKeys;
+              console.log(this.defaultCheckedKeys)
+          })
+        })
+      }
+    },
+  watch: {
+    visible () {
+      if (this.visible) {
+        this.loadData();
+      }
+    }
+  }
+  }
+
+</script>
+<style lang="less" scoped>
+  .drawer-bootom-button {
+    position: absolute;
+    bottom: 0;
+    width: 100%;
+    border-top: 1px solid #e8e8e8;
+    padding: 10px 16px;
+    text-align: right;
+    left: 0;
+    background: #fff;
+    border-radius: 0 0 2px 2px;
+  }
+
+</style>
\ No newline at end of file
-- 
2.17.1