guhongwei 3 лет назад
Родитель
Сommit
65db1bdc1c

+ 285 - 0
src/layout/chatCommon/chat.vue

@@ -0,0 +1,285 @@
+<template>
+  <div id="chat">
+    <van-row>
+      <van-col span="24" class="main">
+        <van-col span="24" class="one" :style="{ height: client.height - 87 + 'px' }">
+          <template v-for="(i, index) in list">
+            <template v-if="isSender(i, index)">
+              <van-col span="24" class="senderTime" :key="`div${i.id}${index}`">
+                <span :key="`senderTime${i.id}${index}`">[{{ i.send_time }}] {{ i.sender_name }}</span>
+                <span v-if="i.type == '1'" v-html="i.content" :key="`senderContent${i.id}${index}`"></span>
+                <span v-else-if="i.type == '2'">
+                  {{ getFile(i.file) }}<van-button type="info" size="mini" class="downBtn" @click="downFile(i.file)">下载</van-button>
+                </span>
+              </van-col>
+            </template>
+            <template v-else>
+              <van-col span="24" class="receverTime" :key="`div${i.id}${index}`">
+                <span :key="`receverTime${i.id}${index}`"> {{ i.sender_name }} [{{ i.send_time }}]</span>
+                <span v-if="i.type == '1'" v-html="i.content" :key="`receverContent${i.id}${index}`"></span>
+                <span v-else-if="i.type == '2'">
+                  {{ getFile(i.file) }}<van-button type="info" size="mini" class="downBtn" @click="downFile(i.file)">下载</van-button>
+                </span>
+              </van-col>
+            </template>
+          </template>
+        </van-col>
+        <van-col span="24" class="two">
+          <van-col span="17" class="cont">
+            <van-field v-model="content" placeholder="请输入内容" />
+          </van-col>
+          <van-col span="7" class="btn">
+            <van-button type="info" size="small" @click="send">发送</van-button>
+            <van-button type="info" size="small" @click="other">其它</van-button>
+          </van-col>
+        </van-col>
+      </van-col>
+    </van-row>
+    <van-dialog v-model="show" class="dialog" title="文件" :showConfirmButton="false" :showCancelButton="false" :closeOnClickOverlay="false">
+      <van-form>
+        <van-field name="file" label="文件">
+          <template #input>
+            <van-uploader
+              :fileList="fileForm.file"
+              :max-count="1"
+              :after-read="(file) => toUpload(file, 'file')"
+              @delete="(file) => toDelete(file, 'file')"
+              accept="file"
+            />
+          </template>
+        </van-field>
+        <div class="btn">
+          <van-button type="danger" size="small" @click="twoClose">取消发送</van-button>
+          <van-button type="info" size="small" @click="twoSend">提交发送</van-button>
+        </div>
+      </van-form>
+    </van-dialog>
+  </div>
+</template>
+
+<script>
+import { Toast } from 'vant';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: upload } = createNamespacedHelpers('upload');
+const { mapActions: adminLogin } = createNamespacedHelpers('adminLogin');
+const { mapActions: patentchat } = createNamespacedHelpers('patentchat');
+const _ = require('lodash');
+export default {
+  name: 'chat',
+  props: {},
+  components: {},
+  data: function () {
+    return {
+      adminInfo: {},
+      content: '',
+      // 消息列表
+      list: [],
+      // 浏览器高度
+      client: {},
+      // 发送其他内容
+      show: false,
+      fileForm: {},
+    };
+  },
+  created() {
+    this.searchAdmin();
+    this.search();
+  },
+  methods: {
+    ...upload(['upload']),
+    ...adminLogin({ adminQuery: 'query' }),
+    ...patentchat(['create', 'query']),
+    // 查询
+    async search() {
+      let res = await this.query({ id: this.user._id });
+      if (this.$checkRes(res)) {
+        this.$set(this, `list`, res.data);
+      }
+    },
+    // 发言,正常内容
+    async send() {
+      if (this.content) {
+        let arr = {
+          type: '1',
+          content: this.content,
+          sender_id: this.user._id,
+          sender_name: this.user.name,
+          receiver_id: this.adminInfo._id,
+          receiver_name: this.adminInfo.name,
+        };
+        let res = await this.create(arr);
+        if (this.$checkRes(res)) {
+          this.$toast({ type: `success`, message: `发言成功` });
+          this.content = '';
+          this.search();
+        }
+      } else {
+        this.$toast({ type: `fail`, message: `缺少必要信息` });
+      }
+    },
+    // 发言,发送文件
+    other() {
+      this.show = true;
+    },
+    // 提交发送
+    async twoSend() {
+      let data = this.fileForm;
+      if (data.file) {
+        let data = {
+          type: '2',
+          file: data.file,
+          sender_id: this.user._id,
+          sender_name: this.user.name,
+          receiver_id: this.adminInfo._id,
+          receiver_name: this.adminInfo.name,
+        };
+        let res = await this.create(data);
+        if (this.$checkRes(res)) {
+          this.$toast({ type: `success`, message: `发言成功` });
+          this.fileForm = { file: [] };
+          this.twoClose();
+          this.search();
+        }
+      } else {
+        this.$toast({ type: `fail`, message: `缺少必要信息` });
+      }
+    },
+    // 取消发送
+    twoClose() {
+      this.show = false;
+    },
+
+    async toUpload({ file }, model) {
+      // 上传,赋值
+      const res = await this.upload({ file, dir: 'chat' });
+      if (this.$checkRes(res)) {
+        this.$set(this.fileForm, model, [{ name: res.name, url: res.uri }]);
+      }
+    },
+    toDelete(file, model) {
+      const index = this.fileForm[model].findIndex((f) => _.isEqual(f, file));
+      this.fileForm[model].splice(index, 1);
+    },
+    // 处理文件
+    getFile(data) {
+      if (data.length > 0) {
+        return data[0].name;
+      }
+    },
+    // 下载文件
+    downFile(data) {
+      if (data.length > 0) {
+        let url = data.map((i) => i.url);
+        window.location.href = `${process.env.VUE_APP_HOST}/${url[0]}`;
+      } else {
+        this.$toast({ type: `fail`, message: `非正常文件,无法下载` });
+      }
+    },
+    // 判断发言人
+    isSender(data) {
+      return this.user.id !== data.sender_id;
+    },
+    // 查询管理员
+    async searchAdmin() {
+      let res = await this.adminQuery({ code: 'JLKJQY' });
+      if (this.$checkRes(res)) {
+        this.$set(this, `adminInfo`, res.data[0]);
+      }
+    },
+  },
+  mounted() {
+    let client = {
+      height: document.documentElement.clientHeight || document.body.clientHeight,
+      width: document.documentElement.clientWidth || document.body.clientWidth,
+    };
+    this.$set(this, `client`, client);
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.main {
+  .one {
+    overflow-x: hidden;
+    overflow-y: auto;
+    padding: 10px 5px;
+    .senderTime {
+      float: left;
+      width: 100%;
+      text-align: left;
+      color: #666;
+      font-size: 14px;
+      margin: 0 0 5px 0;
+    }
+    .senderTime span:last-child {
+      float: left;
+      width: 100%;
+      text-align: left;
+      color: #000;
+    }
+    .receverTime {
+      float: right;
+      width: 100%;
+      color: #666;
+      font-size: 14px;
+      margin: 0 0 5px 0;
+    }
+    .receverTime span:first-child {
+      float: right;
+      width: 100%;
+      text-align: right;
+    }
+    .receverTime span:last-child {
+      float: right;
+      width: 100%;
+      text-align: right;
+      color: #000;
+    }
+  }
+  .two {
+    height: 40px;
+    border-top: 1px solid #ccc;
+    .cont {
+      /deep/.van-cell {
+        line-height: 20px;
+        padding: 10px;
+      }
+    }
+    .btn {
+      text-align: center;
+      /deep/.van-button--small {
+        width: 54px;
+        height: 40px;
+        padding: 0;
+      }
+    }
+  }
+}
+.dialog {
+  .btn {
+    text-align: center;
+    .van-button {
+      margin: 8px;
+    }
+  }
+}
+.downBtn {
+  margin: 0 0 0 8px;
+  /deep/.van-button__text {
+    color: #ffffff !important;
+  }
+}
+</style>

+ 148 - 0
src/layout/list/cashing/model-1.vue

@@ -0,0 +1,148 @@
+<template>
+  <div id="model-6">
+    <el-row class="list">
+      <el-col :span="24" class="is_cashing">
+        <el-col :span="4" class="cashing">
+          {{ getCash(data.is_cashing) }}
+        </el-col>
+      </el-col>
+      <el-col :span="24" class="other">
+        <el-col :span="24" class="other_info textOver">
+          申请企业:<span>{{ data.company || '暂无' }}</span>
+        </el-col>
+        <el-col :span="24" class="other_info textOver">
+          联系电话:<span>{{ data.phone || '暂无' }}</span>
+        </el-col>
+        <el-col :span="24" class="other_info textOver">
+          中介机构:<span>{{ data.medium.name || '暂无' }}</span>
+        </el-col>
+        <el-col :span="24" class="other_info textOver">
+          审核状态:<span>{{ getStu(data.status) || '暂无' }}</span>
+        </el-col>
+      </el-col>
+      <el-col :span="24" class="btn">
+        <el-button type="primary" size="mini" @click="view">查看详情</el-button>
+        <el-button type="primary" size="mini" @click="edit" v-if="data.status == '-1'">重申</el-button>
+        <el-button type="primary" size="mini" @click="edit" v-if="data.status == '1' || data.status == '2'">上传合同</el-button>
+        <el-button type="primary" size="mini" @click="cash" v-if="data.status == '3' && data.is_cashing == '0'">我要兑付</el-button>
+        <el-button type="primary" size="mini" @click="cashview" v-if="data.is_cashing == '1'">兑付详情</el-button>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+const { iscashing, declareStatus } = require('@/plugins/couindex');
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'model-6',
+  props: {
+    data: { type: Object, default: () => {} },
+    router: { type: String },
+  },
+  components: {},
+  data: function () {
+    return {
+      kjpx: require('@a/kjpx.jpg'),
+    };
+  },
+  created() {},
+  methods: {
+    // 详情
+    view() {
+      this.$router.push({ path: '/adminCompany/cashing/declare/info', query: { id: this.data._id, status: this.data.status } });
+    },
+    // 重申
+    edit() {
+      this.$router.push({ path: '/adminCompany/cashing/declare/detail', query: { id: this.data._id, status: this.data.status } });
+    },
+    // 兑付
+    cash() {
+      this.$router.push({ path: '/adminCompany/cashing/declare/cashing', query: { id: this.data._id } });
+    },
+    // 兑付详情
+    cashview() {
+      this.$router.push({ path: '/adminCompany/cashing/declare/cashingInfo', query: { id: this.data._id } });
+    },
+    getCash(i) {
+      const r = iscashing.find((f) => f.value === i);
+      if (r) return r.label;
+      else return '';
+    },
+    getStu(i) {
+      const r = declareStatus.find((f) => f.value === i);
+      if (r) return r.label;
+      else return '';
+    },
+  },
+  computed: {
+    ...mapState(['user', 'menuParams']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.list {
+  background-color: #fff;
+  border-radius: 5px;
+  margin: 0 0 10px 0;
+  padding: 0 0 8px 0;
+  .is_cashing {
+    margin: 0 0 5px 0;
+    .cashing {
+      text-align: center;
+      background-color: #409eff;
+      color: #fff;
+      font-size: 12px;
+      padding: 5px 0;
+      border-radius: 5px;
+    }
+  }
+  .other {
+    padding: 0 10px;
+    .other_info {
+      font-size: 14px;
+      color: #666;
+      margin: 0 0 10px 0;
+      span {
+        color: #000;
+      }
+    }
+  }
+  .btn {
+    text-align: center;
+    margin: 10px 0 0 0;
+  }
+}
+// .list {
+//   background-color: #fff;
+//   border-radius: 5px;
+//   margin: 0 0 10px 0;
+//   padding: 8px;
+//   .name {
+//     font-size: 16px;
+//     margin: 0 0 5px 0;
+//     font-weight: bold;
+//   }
+//   .other {
+//     .other_info {
+//       font-size: 14px;
+//       color: #666;
+//       margin: 0 0 5px 0;
+//       span {
+//         color: #000;
+//       }
+//     }
+//   }
+//   .btn {
+//     text-align: center;
+//     margin: 10px 0 0 0;
+//   }
+// }
+</style>

+ 145 - 0
src/layout/list/cashing/model-2.vue

@@ -0,0 +1,145 @@
+<template>
+  <div id="model-2">
+    <el-row class="list">
+      <el-col :span="24" class="is_cashing">
+        <el-col :span="4" class="cashing">
+          {{ getCash(data.is_cashing) }}
+        </el-col>
+      </el-col>
+      <el-col :span="24" class="other">
+        <el-col :span="24" class="other_info textOver">
+          申领类型:<span>{{ data.type || '暂无' }}</span>
+        </el-col>
+        <el-col :span="24" class="other_info textOver">
+          申请企业:<span>{{ data.company || '暂无' }}</span>
+        </el-col>
+        <el-col :span="24" class="other_info textOver">
+          申请人:<span>{{ data.apply_person || '暂无' }}</span>
+        </el-col>
+        <el-col :span="24" class="other_info textOver">
+          联系电话:<span>{{ data.phone || '暂无' }}</span>
+        </el-col>
+        <el-col :span="24" class="other_info textOver">
+          审核状态:<span>{{ getStu(data.status) || '暂无' }}</span>
+        </el-col>
+      </el-col>
+      <el-col :span="24" class="btn">
+        <el-button type="primary" size="mini" @click="view">查看详情</el-button>
+        <el-button type="primary" size="mini" @click="cash" v-if="data.status == '1' && data.is_cashing == '0'">我要兑付</el-button>
+        <el-button type="primary" size="mini" @click="cashview" v-if="data.is_cashing == '1'">兑付详情</el-button>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+const { iscashing, rewardStatus } = require('@/plugins/couindex');
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'model-2',
+  props: {
+    data: { type: Object, default: () => {} },
+    router: { type: String },
+  },
+  components: {},
+  data: function () {
+    return {
+      kjpx: require('@a/kjpx.jpg'),
+    };
+  },
+  created() {},
+  methods: {
+    // 详情
+    view() {
+      this.$router.push({ path: '/adminCompany/cashing/invention/info', query: { id: this.data._id } });
+    },
+    // 兑付
+    cash() {
+      this.$router.push({ path: '/adminCompany/cashing/invention/cashing', query: { id: this.data._id } });
+    },
+    // 兑付详情
+    cashview() {
+      this.$router.push({ path: '/adminCompany/cashing/invention/cashingInfo', query: { id: this.data._id } });
+    },
+    getCash(i) {
+      const r = iscashing.find((f) => f.value === i);
+      if (r) return r.label;
+      else return '';
+    },
+    getStu(i) {
+      const r = rewardStatus.find((f) => f.value === i);
+      if (r) return r.label;
+      else return '';
+    },
+  },
+  computed: {
+    ...mapState(['user', 'menuParams']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.list {
+  background-color: #fff;
+  border-radius: 5px;
+  margin: 0 0 10px 0;
+  padding: 0 0 8px 0;
+  .is_cashing {
+    margin: 0 0 5px 0;
+    .cashing {
+      text-align: center;
+      background-color: #409eff;
+      color: #fff;
+      font-size: 12px;
+      padding: 5px 0;
+      border-radius: 5px;
+    }
+  }
+  .other {
+    padding: 0 10px;
+    .other_info {
+      font-size: 14px;
+      color: #666;
+      margin: 0 0 10px 0;
+      span {
+        color: #000;
+      }
+    }
+  }
+  .btn {
+    text-align: center;
+    margin: 10px 0 0 0;
+  }
+}
+// .list {
+//   background-color: #fff;
+//   border-radius: 5px;
+//   margin: 0 0 10px 0;
+//   padding: 8px;
+//   .name {
+//     font-size: 16px;
+//     margin: 0 0 5px 0;
+//     font-weight: bold;
+//   }
+//   .other {
+//     .other_info {
+//       font-size: 14px;
+//       color: #666;
+//       margin: 0 0 5px 0;
+//       span {
+//         color: #000;
+//       }
+//     }
+//   }
+//   .btn {
+//     text-align: center;
+//     margin: 10px 0 0 0;
+//   }
+// }
+</style>

+ 145 - 0
src/layout/list/cashing/model-3.vue

@@ -0,0 +1,145 @@
+<template>
+  <div id="model-2">
+    <el-row class="list">
+      <el-col :span="24" class="is_cashing">
+        <el-col :span="4" class="cashing">
+          {{ getCash(data.is_cashing) }}
+        </el-col>
+      </el-col>
+      <el-col :span="24" class="other">
+        <el-col :span="24" class="other_info textOver">
+          申领类型:<span>{{ data.type || '暂无' }}</span>
+        </el-col>
+        <el-col :span="24" class="other_info textOver">
+          申请企业:<span>{{ data.company || '暂无' }}</span>
+        </el-col>
+        <el-col :span="24" class="other_info textOver">
+          申请人:<span>{{ data.apply_person || '暂无' }}</span>
+        </el-col>
+        <el-col :span="24" class="other_info textOver">
+          联系电话:<span>{{ data.phone || '暂无' }}</span>
+        </el-col>
+        <el-col :span="24" class="other_info textOver">
+          审核状态:<span>{{ getStu(data.status) || '暂无' }}</span>
+        </el-col>
+      </el-col>
+      <el-col :span="24" class="btn">
+        <el-button type="primary" size="mini" @click="view">查看详情</el-button>
+        <el-button type="primary" size="mini" @click="cash" v-if="data.status == '1' && data.is_cashing == '0'">我要兑付</el-button>
+        <el-button type="primary" size="mini" @click="cashview" v-if="data.is_cashing == '1'">兑付详情</el-button>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+const { iscashing, rewardStatus } = require('@/plugins/couindex');
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'model-2',
+  props: {
+    data: { type: Object, default: () => {} },
+    router: { type: String },
+  },
+  components: {},
+  data: function () {
+    return {
+      kjpx: require('@a/kjpx.jpg'),
+    };
+  },
+  created() {},
+  methods: {
+    // 详情
+    view() {
+      this.$router.push({ path: '/adminCompany/cashing/reward/info', query: { id: this.data._id } });
+    },
+    // 兑付
+    cash() {
+      this.$router.push({ path: '/adminCompany/cashing/reward/cashing', query: { id: this.data._id } });
+    },
+    // 兑付详情
+    cashview() {
+      this.$router.push({ path: '/adminCompany/cashing/reward/cashingInfo', query: { id: this.data._id } });
+    },
+    getCash(i) {
+      const r = iscashing.find((f) => f.value === i);
+      if (r) return r.label;
+      else return '';
+    },
+    getStu(i) {
+      const r = rewardStatus.find((f) => f.value === i);
+      if (r) return r.label;
+      else return '';
+    },
+  },
+  computed: {
+    ...mapState(['user', 'menuParams']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.list {
+  background-color: #fff;
+  border-radius: 5px;
+  margin: 0 0 10px 0;
+  padding: 0 0 8px 0;
+  .is_cashing {
+    margin: 0 0 5px 0;
+    .cashing {
+      text-align: center;
+      background-color: #409eff;
+      color: #fff;
+      font-size: 12px;
+      padding: 5px 0;
+      border-radius: 5px;
+    }
+  }
+  .other {
+    padding: 0 10px;
+    .other_info {
+      font-size: 14px;
+      color: #666;
+      margin: 0 0 10px 0;
+      span {
+        color: #000;
+      }
+    }
+  }
+  .btn {
+    text-align: center;
+    margin: 10px 0 0 0;
+  }
+}
+// .list {
+//   background-color: #fff;
+//   border-radius: 5px;
+//   margin: 0 0 10px 0;
+//   padding: 8px;
+//   .name {
+//     font-size: 16px;
+//     margin: 0 0 5px 0;
+//     font-weight: bold;
+//   }
+//   .other {
+//     .other_info {
+//       font-size: 14px;
+//       color: #666;
+//       margin: 0 0 5px 0;
+//       span {
+//         color: #000;
+//       }
+//     }
+//   }
+//   .btn {
+//     text-align: center;
+//     margin: 10px 0 0 0;
+//   }
+// }
+</style>

+ 72 - 0
src/layout/list/model-1.vue

@@ -0,0 +1,72 @@
+<template>
+  <div id="model-1">
+    <el-row class="list" @click.native="toDetail">
+      <el-col :span="24" class="title">
+        {{ data.title }}
+      </el-col>
+      <el-col :span="24" class="other">
+        <p>
+          更新时间:<span>{{ data.publish_time || '暂无' }}</span>
+        </p>
+        <p>
+          信息来源:<span>{{ data.origin || '暂无' }}</span>
+        </p>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'model-1',
+  props: { data: { type: Object, default: () => {} } },
+  components: {},
+  data: function () {
+    return {};
+  },
+  created() {},
+  methods: {
+    toDetail() {
+      this.$router.push({ path: this.detailRouter, query: { id: this.data._id } });
+    },
+  },
+  computed: {
+    ...mapState(['user', 'menuParams']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+    detailRouter() {
+      const key = this.$route.meta.key;
+      return `/${key}/detail`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.list {
+  padding: 10px 5px;
+  background: #fff;
+  margin: 0 0 5px 0;
+  border-radius: 5px;
+  .title {
+    font-size: 15px;
+    font-weight: bold;
+    margin: 0 0 5px 0;
+  }
+  .other {
+    p {
+      padding: 0 0 5px 0;
+      color: #666;
+      font-size: 14px;
+      span {
+        color: #000;
+      }
+    }
+  }
+}
+</style>

+ 70 - 0
src/layout/list/model-2.vue

@@ -0,0 +1,70 @@
+<template>
+  <div id="model-2">
+    <el-row class="list" @click.native="toDetail">
+      <el-col :span="24" class="title">
+        {{ data.title }}
+      </el-col>
+      <el-col :span="24" class="other">
+        <p>
+          <span>{{ data.origin || '暂无' }}</span>
+          <span>{{ data.publish_time || '暂无' }}</span>
+        </p>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'model-2',
+  props: { data: { type: Object, default: () => {} } },
+  components: {},
+  data: function () {
+    return {};
+  },
+  created() {},
+  methods: {
+    toDetail() {
+      this.$router.push({ path: this.detailRouter, query: { id: this.data._id } });
+    },
+  },
+  computed: {
+    ...mapState(['user', 'menuParams']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+    detailRouter() {
+      const key = this.$route.meta.key;
+      return `/${key}/detail`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.list {
+  padding: 10px 5px;
+  background: #fff;
+  margin: 0 0 5px 0;
+  border-radius: 5px;
+  .title {
+    font-size: 15px;
+    font-weight: bold;
+    margin: 0 0 5px 0;
+  }
+  .other {
+    p {
+      span {
+        display: inline-block;
+        width: 50%;
+        font-size: 14px;
+        color: #666;
+      }
+    }
+  }
+}
+</style>

+ 99 - 0
src/layout/list/model-3.vue

@@ -0,0 +1,99 @@
+<template>
+  <div id="model-3">
+    <el-row class="list" @click.native="toDetail">
+      <el-col :span="8" class="image">
+        <el-image :src="kjpx" fit="fit"></el-image>
+      </el-col>
+      <el-col :span="16" class="info">
+        <el-col :span="24" class="title">
+          {{ data.title }}
+        </el-col>
+        <el-col :span="24" class="other">
+          <p>
+            更新时间:<span>{{ data.publish_time || '暂无' }}</span>
+          </p>
+          <p>
+            信息来源:<span>{{ data.origin || '暂无' }}</span>
+          </p>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'model-3',
+  props: {
+    data: { type: Object, default: () => {} },
+    router: { type: String },
+  },
+  components: {},
+  data: function () {
+    return {
+      kjpx: require('@a/kjpx.jpg'),
+    };
+  },
+  created() {},
+  methods: {
+    toDetail() {
+      this.$router.push({ path: this.router ? this.router : this.detailRouter, query: { id: this.data._id } });
+    },
+  },
+  computed: {
+    ...mapState(['user', 'menuParams']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+    detailRouter() {
+      const key = this.$route.meta.key;
+      return `/${key}/detail`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.list {
+  padding: 10px 5px;
+  background: #fff;
+  margin: 0 0 5px 0;
+  border-radius: 5px;
+  .image {
+    text-align: center;
+    .el-image {
+      border: 1px solid #f9f9f9;
+      border-radius: 5px;
+    }
+  }
+  .info {
+    padding: 0 5px;
+    .title {
+      font-size: 15px;
+      font-weight: bold;
+      margin: 0 0 5px 0;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      -webkit-line-clamp: 2;
+      word-break: break-all;
+      display: -webkit-box;
+      -webkit-box-orient: vertical;
+      max-height: 40px;
+    }
+    .other {
+      p {
+        padding: 0 0 5px 0;
+        color: #666;
+        font-size: 14px;
+        span {
+          color: #000;
+        }
+      }
+    }
+  }
+}
+</style>

+ 123 - 0
src/layout/list/model-4.vue

@@ -0,0 +1,123 @@
+<template>
+  <div id="model-4">
+    <el-row class="list" @click.native="toDetail">
+      <el-col :span="24" class="title">
+        {{ data.title }}
+      </el-col>
+      <el-col :span="24" class="other">
+        <el-col :span="24" class="other_info">
+          更新时间:<span>{{ data.create_time || '暂无' }}</span>
+        </el-col>
+        <el-col :span="24" class="other_info brief">
+          信息简介:<span>{{ data.brief || '暂无' }}</span>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'model-4',
+  props: {
+    data: { type: Object, default: () => {} },
+    router: { type: String },
+  },
+  components: {},
+  data: function () {
+    return {
+      kjpx: require('@a/kjpx.jpg'),
+    };
+  },
+  created() {},
+  methods: {
+    toDetail() {
+      this.$router.push({ path: this.router ? this.router : this.detailRouter, query: { id: this.data._id } });
+    },
+  },
+  computed: {
+    ...mapState(['user', 'menuParams']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+    detailRouter() {
+      const key = this.$route.meta.key;
+      return `/${key}/detail`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.list {
+  background-color: #fff;
+  border-radius: 5px;
+  margin: 0 0 10px 0;
+  padding: 8px;
+  .title {
+    font-size: 16px;
+    margin: 0 0 5px 0;
+    font-weight: bold;
+  }
+  .other {
+    .other_info {
+      font-size: 14px;
+      color: #666;
+      margin: 0 0 5px 0;
+      span {
+        color: #000;
+      }
+    }
+    .brief {
+      overflow: hidden;
+      text-overflow: ellipsis;
+      -webkit-line-clamp: 2;
+      word-break: break-all;
+      display: -webkit-box;
+      -webkit-box-orient: vertical;
+    }
+  }
+}
+// .list {
+//   padding: 10px 5px;
+//   background: #fff;
+//   margin: 0 0 5px 0;
+//   border-radius: 5px;
+//   .image {
+//     text-align: center;
+//     .el-image {
+//       border: 1px solid #f9f9f9;
+//       border-radius: 5px;
+//     }
+//   }
+//   .info {
+//     padding: 0 5px;
+//     .title {
+//       font-size: 15px;
+//       font-weight: bold;
+//       margin: 0 0 5px 0;
+//       overflow: hidden;
+//       text-overflow: ellipsis;
+//       -webkit-line-clamp: 2;
+//       word-break: break-all;
+//       display: -webkit-box;
+//       -webkit-box-orient: vertical;
+//       max-height: 40px;
+//     }
+//     .other {
+//       p {
+//         padding: 0 0 5px 0;
+//         color: #666;
+//         font-size: 14px;
+//         span {
+//           color: #000;
+//         }
+//       }
+//     }
+//   }
+// }
+</style>

+ 98 - 0
src/layout/list/model-5.vue

@@ -0,0 +1,98 @@
+<template>
+  <div id="model-5">
+    <el-row class="list">
+      <el-col :span="24" class="name">
+        {{ data.name }}
+      </el-col>
+      <el-col :span="24" class="other">
+        <el-col :span="12" class="other_info textOver">
+          创新券类型:<span>{{ data.coupons_type || '暂无' }}</span>
+        </el-col>
+        <el-col :span="12" class="other_info textOver">
+          所属分类:<span>{{ data.classify || '暂无' }}</span>
+        </el-col>
+        <el-col :span="12" class="other_info textOver">
+          折扣类型:<span>{{ data.discount_type || '暂无' }}</span>
+        </el-col>
+        <el-col :span="12" class="other_info textOver">
+          适用服务类型:<span>{{ data.use_type || '暂无' }}</span>
+        </el-col>
+      </el-col>
+      <el-col :span="24" class="btn">
+        <el-button type="primary" size="mini" @click.native="toDetail">详情</el-button>
+        <el-button type="success" size="mini" @click.native="toApply">申领</el-button>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'model-5',
+  props: {
+    data: { type: Object, default: () => {} },
+    router: { type: String },
+  },
+  components: {},
+  data: function () {
+    return {
+      kjpx: require('@a/kjpx.jpg'),
+    };
+  },
+  created() {},
+  methods: {
+    toDetail() {
+      this.$router.push({ path: this.router ? this.router : this.detailRouter, query: { id: this.data._id } });
+    },
+    toApply() {
+      this.$router.push({ path: this.router ? this.router : this.applyRouter, query: { id: this.data._id } });
+    },
+  },
+  computed: {
+    ...mapState(['user', 'menuParams']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+    detailRouter() {
+      const key = this.$route.meta.key;
+      return `/adminCompany/${key}/detail`;
+    },
+    applyRouter() {
+      const key = this.$route.meta.key;
+      return `/adminCompany/${key}/apply`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.list {
+  background-color: #fff;
+  border-radius: 5px;
+  margin: 0 0 10px 0;
+  padding: 8px;
+  .name {
+    font-size: 16px;
+    margin: 0 0 5px 0;
+    font-weight: bold;
+  }
+  .other {
+    .other_info {
+      font-size: 14px;
+      color: #666;
+      margin: 0 0 5px 0;
+      span {
+        color: #000;
+      }
+    }
+  }
+  .btn {
+    text-align: center;
+    margin: 10px 0 0 0;
+  }
+}
+</style>

+ 101 - 0
src/layout/list/model-6.vue

@@ -0,0 +1,101 @@
+<template>
+  <div id="model-6">
+    <el-row class="list">
+      <el-col :span="24" class="name">
+        {{ data.coupons ? data.coupons.name : '暂无' }}
+      </el-col>
+      <el-col :span="24" class="other">
+        <el-col :span="12" class="other_info textOver">
+          申请人:<span>{{ data.apply_person || '暂无' }}</span>
+        </el-col>
+        <el-col :span="12" class="other_info textOver">
+          联系电话:<span>{{ data.phone || '暂无' }}</span>
+        </el-col>
+        <el-col :span="12" class="other_info textOver">
+          是否使用:<span>{{ getUse(data.is_use) || '暂无' }}</span>
+        </el-col>
+        <el-col :span="12" class="other_info textOver">
+          审核状态:<span>{{ getStu(data.status) || '暂无' }}</span>
+        </el-col>
+      </el-col>
+      <el-col :span="24" class="btn">
+        <el-button type="primary" size="mini" @click.native="toDetail">详情</el-button>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+const { isuse, couponsapplyStatus } = require('@/plugins/couindex');
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'model-6',
+  props: {
+    data: { type: Object, default: () => {} },
+    router: { type: String },
+  },
+  components: {},
+  data: function () {
+    return {
+      kjpx: require('@a/kjpx.jpg'),
+    };
+  },
+  created() {},
+  methods: {
+    toDetail() {
+      this.$router.push({ path: this.router ? this.router : this.detailRouter, query: { id: this.data._id } });
+    },
+    getUse(i) {
+      const r = isuse.find((f) => f.value === i);
+      if (r) return r.label;
+      else return '';
+    },
+    getStu(i) {
+      const r = couponsapplyStatus.find((f) => f.value === i);
+      if (r) return r.label;
+      else return '';
+    },
+  },
+  computed: {
+    ...mapState(['user', 'menuParams']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+    detailRouter() {
+      const key = this.$route.meta.key;
+      return `/adminCompany/${key}/resultInfo`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.list {
+  background-color: #fff;
+  border-radius: 5px;
+  margin: 0 0 10px 0;
+  padding: 8px;
+  .name {
+    font-size: 16px;
+    margin: 0 0 5px 0;
+    font-weight: bold;
+  }
+  .other {
+    .other_info {
+      font-size: 14px;
+      color: #666;
+      margin: 0 0 5px 0;
+      span {
+        color: #000;
+      }
+    }
+  }
+  .btn {
+    text-align: center;
+    margin: 10px 0 0 0;
+  }
+}
+</style>

+ 7 - 8
src/router/index.js

@@ -144,14 +144,13 @@ router.beforeEach((to, from, next) => {
   document.title = `${to.meta.title} `;
   const token = localStorage.getItem('token');
   if (to.path == '/account/index') {
-    // if (!token) {
-    //   next(`/login?path=${to.path}`);
-    // } else {
-    //   let user = jwt.decode(token);
-    //   store.commit('setUser', user, { root: true });
-    //   next();
-    // }
-    next();
+    if (!token) {
+      next(`/login?path=${to.path}`);
+    } else {
+      let user = jwt.decode(token);
+      store.commit('setUser', user, { root: true });
+      next();
+    }
   } else {
     let user = jwt.decode(token);
     store.commit('setUser', user, { root: true });

+ 87 - 0
src/views/patent/admin/adminBtn.vue

@@ -0,0 +1,87 @@
+<template>
+  <div id="adminBtn">
+    <van-row>
+      <van-col span="24" class="main">
+        <van-col span="24" class="one">
+          <van-divider content-position="left" :style="{ color: '#1989fa', borderColor: '#1989fa' }">我的消息</van-divider>
+          <van-col span="24" class="one_1">
+            <van-cell title="咨询服务" @click="pathBtn('admin/message', 'service')" is-link />
+            <van-cell title="通知管理" @click="pathBtn('admin/message', 'notice')" is-link />
+            <van-cell title="审核通知" @click="pathBtn('admin/message', 'examine')" is-link />
+            <van-cell title="专利预警" @click="pathBtn('admin/message', 'warning')" is-link />
+          </van-col>
+        </van-col>
+        <van-col span="24" class="one">
+          <van-divider content-position="left" :style="{ color: '#1989fa', borderColor: '#1989fa' }">专利审核</van-divider>
+          <van-col span="24" class="one_1">
+            <van-cell title="专利申请" @click="pathBtn('admin/examine', 'patent')" is-link />
+            <van-cell title="国知局反馈消息" @click="pathBtn('admin/examine', 'hairmess')" is-link />
+            <van-cell title="查新检索" @click="pathBtn('admin/examine', 'analysis')" is-link />
+          </van-col>
+        </van-col>
+        <van-col span="24" class="one">
+          <van-divider content-position="left" :style="{ color: '#1989fa', borderColor: '#1989fa' }">专利管理</van-divider>
+          <van-col span="24" class="one_1">
+            <van-cell title="专利信息" @click="pathBtn('admin/patent', 'info')" is-link />
+            <van-cell title="价值评估" @click="pathBtn('admin/patent', 'assessment')" is-link />
+            <van-cell title="专利交易" @click="pathBtn('admin/patent', 'trans')" is-link />
+          </van-col>
+        </van-col>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'adminBtn',
+  props: {},
+  components: {},
+  data: function () {
+    return {};
+  },
+  created() {},
+  methods: {
+    pathBtn(type, path) {
+      this.$router.push({ path: `/service/patent/${type}/${path}` });
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.main {
+  .one {
+    .one_1 {
+      .one_1action {
+        /deep/.van-info {
+          background-color: #409eff;
+        }
+        /deep/.van-goods-action-icon {
+          padding: 8px 0;
+        }
+        i {
+          font-size: 20px;
+        }
+      }
+    }
+    /deep/.van-divider {
+      margin: 10px;
+    }
+  }
+}
+</style>

+ 39 - 9
src/views/patent/index.vue

@@ -1,22 +1,52 @@
 <template>
-  <div id="index">
-    <van-row>
-      <van-col span="24" class="main"> 阿萨德 </van-col>
-    </van-row>
+  <div id="login">
+    <admin-frame :useTop="false" :usePage="false" :useNav="false">
+      <template v-slot:info>
+        <user-1 v-if="role == '1'"></user-1>
+        <user-2 v-else-if="role == '2'"></user-2>
+        <user-3 v-else-if="role == '3'"></user-3>
+      </template>
+    </admin-frame>
   </div>
 </template>
 
 <script>
+import user1 from './user-role/user-1.vue';
+import user2 from './user-role/user-2.vue';
+import user3 from './user-role/user-3.vue';
+import adminFrame from '@frame/src/components/mobile-frame/mobile-main.vue';
 import { mapState, createNamespacedHelpers } from 'vuex';
 export default {
-  name: 'index',
+  name: 'login',
   props: {},
-  components: {},
+  components: {
+    adminFrame,
+    user1,
+    user2,
+    user3,
+  },
   data: function () {
-    return {};
+    return {
+      role: '3',
+    };
+  },
+  async created() {
+    this.searchUser();
+  },
+  methods: {
+    // 查询用户身份
+    searchUser() {
+      if (this.user) {
+        if (this.user.role == '1') {
+          this.$set(this, `role`, '1');
+        } else if (this.user.role == '2') {
+          this.$set(this, `role`, '2');
+        } else {
+          this.$set(this, `role`, '3');
+        }
+      }
+    },
   },
-  created() {},
-  methods: {},
   computed: {
     ...mapState(['user']),
   },

+ 63 - 0
src/views/patent/market/detail.vue

@@ -0,0 +1,63 @@
+<template>
+  <div id="detail">
+    <admin-frame topType="2" @back="back" :rightArrow="false" :usePage="false" :useNav="false">
+      <template v-slot:info>
+        <detail-1 :form="form"></detail-1>
+      </template>
+    </admin-frame>
+  </div>
+</template>
+
+<script>
+import detail1 from './parts/detail-1.vue';
+import adminFrame from '@frame/src/components/mobile-frame/mobile-main.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: patent } = createNamespacedHelpers('patent');
+export default {
+  name: 'detail',
+  props: {},
+  components: {
+    adminFrame,
+    detail1,
+  },
+  data: function () {
+    return {
+      form: {},
+    };
+  },
+  async created() {
+    if (this.id) await this.search();
+  },
+  methods: {
+    ...patent(['fetch']),
+    async search() {
+      let res = await this.fetch(this.id);
+      if (this.$checkRes(res)) {
+        this.$set(this, `form`, res.data);
+      }
+    },
+    // 返回
+    back() {
+      window.history.go(-1);
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    id() {
+      return this.$route.query.id;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 108 - 0
src/views/patent/market/index.vue

@@ -0,0 +1,108 @@
+<template>
+  <div id="index">
+    <admin-frame @search="search" :limit="limit" :total="total" topType="2" @back="back" :rightArrow="false" :useNav="false">
+      <template v-slot:info>
+        <van-tabs v-model="active" @change="change">
+          <van-tab :title="`授权专利【${oneTotal}】`" name="1">
+            <list-1 :list="oneList" @detail="detail"></list-1>
+          </van-tab>
+          <van-tab :title="`专利转让【${twoTotal}】`" name="2">
+            <list-2 :list="twoList" @detail="twoDetail"></list-2>
+          </van-tab>
+        </van-tabs>
+      </template>
+    </admin-frame>
+  </div>
+</template>
+
+<script>
+import list1 from './parts/list-1.vue';
+import list2 from './parts/list-2.vue';
+import adminFrame from '@frame/src/components/mobile-frame/mobile-main.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: patent } = createNamespacedHelpers('patent');
+const { mapActions: patenttrans } = createNamespacedHelpers('patenttrans');
+export default {
+  name: 'index',
+  props: {},
+  components: {
+    adminFrame,
+    list1,
+    list2,
+  },
+  data: function () {
+    return {
+      active: '1',
+      limit: 5,
+      total: 0,
+      // 授权专利
+      oneList: [],
+      // 专利转让
+      twoList: [],
+      oneTotal: 0,
+      twoTotal: 0,
+    };
+  },
+  async created() {
+    await this.search();
+    await this.searchTotal();
+  },
+  methods: {
+    ...patent(['query']),
+    ...patenttrans({ transQuery: 'query' }),
+    async search({ skip = 0, limit = this.limit, ...info } = {}) {
+      if (this.active == '1') {
+        let res = await this.query({ skip, limit, ...info });
+        if (this.$checkRes(res)) {
+          this.$set(this, `oneList`, res.data);
+          this.$set(this, `total`, res.total);
+        }
+      } else if (this.active == '2') {
+        let res = await this.transQuery({ skip, limit, ...info });
+        if (this.$checkRes(res)) {
+          this.$set(this, `twoList`, res.data);
+          this.$set(this, `total`, res.total);
+        }
+      }
+    },
+    // 查询总数
+    async searchTotal({ skip = 0, limit = this.limit, ...info } = {}) {
+      let res = await this.query({ skip, limit, ...info });
+      if (this.$checkRes(res)) this.$set(this, `oneTotal`, res.total);
+      res = await this.transQuery({ skip, limit, ...info });
+      if (this.$checkRes(res)) this.$set(this, `twoTotal`, res.total);
+    },
+    // 专利详情
+    detail(data) {
+      this.$router.push({ path: '/service/patent/market/detail', query: { id: data._id } });
+    },
+    // 交易详情
+    twoDetail(data) {
+      this.$router.push({ path: '/service/patent/market/transDetail', query: { id: data._id } });
+    },
+    change(name) {
+      this.$set(this, `active`, name);
+      this.search();
+    },
+    // 返回
+    back() {
+      this.$router.push({ path: '/service/patent/index' });
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 122 - 0
src/views/patent/market/parts/detail-1.vue

@@ -0,0 +1,122 @@
+<template>
+  <div id="detail-1">
+    <el-row>
+      <el-col :span="24" class="main">
+        <el-col :span="24" class="one">
+          <el-image v-if="form.img_url != undefined || null" :src="form.img_url"></el-image>
+          <el-image v-else :src="noimage"></el-image>
+        </el-col>
+        <el-col :span="24" class="two">
+          <p>
+            <span>专利有效性:</span>
+            <span>{{ form.term || '暂无' }}</span>
+          </p>
+          <p>
+            <span>名称:</span>
+            <span>{{ form.name || '暂无' }}</span>
+          </p>
+          <p>
+            <span>申请号:</span>
+            <span> {{ form.create_number || '暂无' }}</span>
+          </p>
+          <p>
+            <span>申请日:</span>
+            <span>{{ form.create_date || '暂无' }}</span>
+          </p>
+          <p>
+            <span>公开(公告)号:</span>
+            <span>{{ form.success_number || '暂无' }}</span>
+          </p>
+          <p>
+            <span>公开(公告)日:</span>
+            <span>{{ form.success_date || '暂无' }}</span>
+          </p>
+          <p>
+            <span>专利类型:</span>
+            <span>{{ form.type || '暂无' }}</span>
+          </p>
+          <p>
+            <span>发明人:</span>
+            <span>{{ form.inventor || '暂无' }}</span>
+          </p>
+          <p>
+            <span>发明人地址:</span>
+            <span>{{ form.address || '暂无' }}</span>
+          </p>
+          <p>
+            <span>申请人:</span>
+            <span>{{ form.apply_personal || '暂无' }}</span>
+          </p>
+          <p>
+            <span>代理人:</span>
+            <span>{{ form.agent_personal || '暂无' }}</span>
+          </p>
+          <p>
+            <span>代理机构:</span>
+            <span>{{ form.agent || '暂无' }}</span>
+          </p>
+
+          <p>
+            <span>摘要:</span>
+            <span>{{ form.abstract || '暂无' }}</span>
+          </p>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'detail-1',
+  props: {
+    form: { type: Object },
+  },
+  components: {},
+  data: function () {
+    return {
+      noimage: require('@/assets/noimage.jpg'),
+    };
+  },
+  created() {},
+  methods: {},
+  computed: {
+    ...mapState(['user']),
+  },
+  metaform() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.main {
+  .one {
+    height: 220px;
+    border-bottom: 1px solid #f1f1f1;
+    .el-image {
+      width: 100%;
+      height: 219px;
+    }
+  }
+  .two {
+    p {
+      font-size: 16px;
+      color: #666;
+      padding: 10px;
+      border-bottom: 1px solid #ccc;
+      span:nth-child(2) {
+        color: #000;
+      }
+    }
+  }
+}
+</style>

+ 88 - 0
src/views/patent/market/parts/detail-2.vue

@@ -0,0 +1,88 @@
+<template>
+  <div id="detail-2">
+    <van-row>
+      <van-col span="24" class="main">
+        <van-col span="24" class="one">
+          <van-form label-width="5em">
+            <van-field v-model="form.create_number" name="create_number" label="申请号" readonly />
+            <van-field v-model="form.patent_name" name="patent_name" label="专利名称" readonly />
+            <van-field v-model="form.contact" name="contact" label="联系人" readonly />
+            <van-field v-model="form.phone" name="phone" label="联系电话" readonly />
+            <van-field v-model="form.email" name="email" label="电子邮箱" readonly />
+            <van-field v-model="form.budget" name="budget" type="digit" label="投资预算" readonly />
+            <van-field v-model="form.type" name="type" label="交易类型" readonly />
+            <van-field name="is_report" label="评估报告">
+              <template #input>
+                <van-radio-group v-model="form.is_report" direction="horizontal" disabled>
+                  <van-radio :name="true">有</van-radio>
+                  <van-radio :name="false">无</van-radio>
+                </van-radio-group>
+                <van-button type="info" size="small" v-if="form.is_report == true" @click="download(form.report)">下载报告</van-button>
+              </template>
+            </van-field>
+            <van-field v-model="form.requirementdesc" name="requirementdesc" label="技术说明" rows="2" autosize type="textarea" readonly />
+            <van-field v-model="form.expect" name="expect" label="商业预期" rows="2" autosize type="textarea" readonly />
+            <van-field v-model="form.condition" name="condition" label="条件及要求" rows="2" autosize type="textarea" readonly />
+          </van-form>
+        </van-col>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'detail-2',
+  props: {
+    form: { type: Object },
+  },
+  components: {},
+  data: function () {
+    return {};
+  },
+  created() {},
+  methods: {
+    // 填写合同
+    addContract() {
+      this.$emit('addContract');
+    },
+    // 撤回交易
+    revoke() {
+      this.$emit('revoke');
+    },
+    // 用户确认
+    confirm() {
+      this.$emit('confirm');
+    },
+    download(data) {
+      window.location.href = `${process.env.VUE_APP_HOST}/${data[0].url}`;
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.main {
+  .two {
+    text-align: center;
+    margin: 10px 0;
+    .van-button {
+      margin: 0 10px;
+    }
+  }
+}
+</style>

+ 81 - 0
src/views/patent/market/parts/list-1.vue

@@ -0,0 +1,81 @@
+<template>
+  <div id="list-1">
+    <van-row>
+      <van-col span="24" class="main">
+        <van-col span="24" class="list" v-for="(item, index) in list" :key="index" @click.native="detail(item)">
+          <van-col span="24" class="title textOver">
+            {{ item.name }}
+          </van-col>
+          <van-col span="24" class="other">
+            <van-col span="24" class="otherInfo">
+              专利有效性:<span>{{ item.term || '暂无' }}</span>
+            </van-col>
+            <van-col span="24" class="otherInfo">
+              颁发时间:<span>{{ item.success_date || '暂无' }}</span>
+            </van-col>
+          </van-col>
+        </van-col>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'list-1',
+  props: {
+    list: { type: Array },
+  },
+  components: {},
+  data: function () {
+    return {};
+  },
+  created() {},
+  methods: {
+    detail(data) {
+      this.$emit('detail', data);
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.main {
+  margin: 8px 0 0 0;
+  .list {
+    background-color: #fff;
+    margin: 0 0 10px 0;
+    box-shadow: 0 0 5px #f1f1f1;
+    padding: 8px;
+    .title {
+      font-size: 16px;
+      font-weight: bold;
+      margin: 0 0 5px 0;
+    }
+    .other {
+      .otherInfo {
+        font-size: 14px;
+        color: #666;
+        margin: 0 0 5px 0;
+        span {
+          color: #000;
+        }
+      }
+    }
+  }
+}
+</style>

+ 85 - 0
src/views/patent/market/parts/list-2.vue

@@ -0,0 +1,85 @@
+<template>
+  <div id="list-3">
+    <van-row>
+      <van-col span="24" class="main">
+        <van-col span="24" class="list" v-for="(item, index) in list" :key="index" @click.native="detail(item)">
+          <van-col span="24" class="title textOver">
+            {{ item.patent_name }}
+          </van-col>
+          <van-col span="24" class="other">
+            <van-col span="24" class="otherInfo">
+              申请号:<span>{{ item.create_number || '暂无' }}</span>
+            </van-col>
+            <van-col span="12" class="otherInfo">
+              交易类型:<span>{{ item.type || '暂无' }}</span>
+            </van-col>
+            <van-col span="12" class="otherInfo">
+              投资预算:<span>{{ item.budget || '暂无' }}万元</span>
+            </van-col>
+          </van-col>
+        </van-col>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'list-3',
+  props: {
+    list: { type: Array },
+  },
+  components: {},
+  data: function () {
+    return {};
+  },
+  created() {},
+  methods: {
+    detail(data) {
+      this.$emit('detail', data);
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.main {
+  padding: 8px 8px 0 8px;
+  .list {
+    background-color: #fff;
+    margin: 0 0 8px 0;
+    padding: 8px;
+    border-radius: 5px;
+    .title {
+      font-size: 16px;
+      font-weight: bold;
+      margin: 0 0 5px 0;
+    }
+    .other {
+      margin: 0 0 5px 0;
+      .otherInfo {
+        font-size: 14px;
+        color: #666;
+        margin: 0 0 5px 0;
+        span {
+          color: #000;
+        }
+      }
+    }
+  }
+}
+</style>

+ 63 - 0
src/views/patent/market/transDetail.vue

@@ -0,0 +1,63 @@
+<template>
+  <div id="transDetail">
+    <admin-frame topType="2" @back="back" :rightArrow="false" :usePage="false" :useNav="false">
+      <template v-slot:info>
+        <info-1 :form="form"></info-1>
+      </template>
+    </admin-frame>
+  </div>
+</template>
+
+<script>
+import info1 from './parts/detail-2.vue';
+import adminFrame from '@frame/src/components/mobile-frame/mobile-main.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: patenttrans } = createNamespacedHelpers('patenttrans');
+export default {
+  name: 'transDetail',
+  props: {},
+  components: {
+    adminFrame,
+    info1,
+  },
+  data: function () {
+    return {
+      form: {},
+    };
+  },
+  created() {
+    if (this.id) this.search();
+  },
+  methods: {
+    ...patenttrans(['fetch']),
+    async search() {
+      let res = await this.fetch(this.id);
+      if (this.$checkRes(res)) {
+        this.$set(this, `form`, res.data);
+      }
+    },
+    // 返回
+    back() {
+      window.history.go(-1);
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    id() {
+      return this.$route.query.id;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 142 - 0
src/views/patent/mech/mechBtn.vue

@@ -0,0 +1,142 @@
+<template>
+  <div id="mechBtn">
+    <van-row>
+      <van-col span="24" class="main">
+        <van-col span="24" class="one">
+          <van-divider content-position="left" :style="{ color: '#1989fa', borderColor: '#1989fa' }">我的消息</van-divider>
+          <van-col span="24" class="one_1">
+            <van-col span="8" class="one_1action" @click.native="pathBtn('mech/message', 'unRead')">
+              <van-goods-action-icon text="未读">
+                <template #icon><i class="iconfont icon-xiaoxi"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+            <van-col span="8" class="one_1action" @click.native="pathBtn('mech/message', 'read')">
+              <van-goods-action-icon text="已读">
+                <template #icon><i class="iconfont icon-xiaoxi"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+            <van-col span="8" class="one_1action" @click.native="pathBtn('mech/message', 'notice')">
+              <van-goods-action-icon text="通知">
+                <template #icon><i class="iconfont icon-tongzhi"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+          </van-col>
+        </van-col>
+        <van-col span="24" class="one">
+          <van-divider content-position="left" :style="{ color: '#1989fa', borderColor: '#1989fa' }">我的审核</van-divider>
+          <van-col span="24" class="one_1">
+            <van-col span="8" class="one_1action" @click.native="pathBtn('mech/examine', 'patent')">
+              <van-goods-action-icon text="专利审核">
+                <template #icon><i class="iconfont icon-jiaodi"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+            <van-col span="8" class="one_1action" @click.native="pathBtn('mech/examine', 'contract')">
+              <van-goods-action-icon text="合同审核">
+                <template #icon><i class="iconfont icon-pinggu"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+            <van-col span="8" class="one_1action" @click.native="pathBtn('mech/examine', 'trans')">
+              <van-goods-action-icon text="交易审核">
+                <template #icon><i class="iconfont icon-pinggu"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+          </van-col>
+        </van-col>
+        <van-col span="24" class="one">
+          <van-divider content-position="left" :style="{ color: '#1989fa', borderColor: '#1989fa' }">我的专利</van-divider>
+          <van-col span="24" class="one_1">
+            <van-col span="8" class="one_1action" @click.native="pathBtn('mech/patent', 'information')">
+              <van-goods-action-icon text="专利信息">
+                <template #icon><i class="iconfont icon-jiaodi"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+            <van-col span="8" class="one_1action" @click.native="pathBtn('mech/patent', 'navigation')">
+              <van-goods-action-icon text="查新检索">
+                <template #icon><i class="iconfont icon-pinggu"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+            <van-col span="8" class="one_1action" @click.native="pathBtn('mech/patent', 'early')">
+              <van-goods-action-icon text="专利预警">
+                <template #icon><i class="iconfont icon-pinggu"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+          </van-col>
+        </van-col>
+        <van-col span="24" class="one">
+          <van-divider content-position="left" :style="{ color: '#1989fa', borderColor: '#1989fa' }">我的交易</van-divider>
+          <van-col span="24" class="one_1">
+            <van-col span="8" class="one_1action" @click.native="pathBtn('mech/transaction', 'index', 'type=转让')">
+              <van-goods-action-icon text="专利转让">
+                <template #icon><i class="iconfont icon-jiaodi"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+            <van-col span="8" class="one_1action" @click.native="pathBtn('mech/transaction', 'index', 'type=合作')">
+              <van-goods-action-icon text="专利合作">
+                <template #icon><i class="iconfont icon-pinggu"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+            <van-col span="8" class="one_1action" @click.native="pathBtn('mech/transaction', 'index', 'type=招商')">
+              <van-goods-action-icon text="专利招商">
+                <template #icon><i class="iconfont icon-pinggu"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+          </van-col>
+        </van-col>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'mechBtn',
+  props: {},
+  components: {},
+  data: function () {
+    return {};
+  },
+  created() {},
+  methods: {
+    pathBtn(type, path, query) {
+      this.$router.push({ path: `/service/patent/${type}/${path}?${query}` });
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.main {
+  .one {
+    .one_1 {
+      .one_1action {
+        /deep/.van-info {
+          background-color: #409eff;
+        }
+        /deep/.van-goods-action-icon {
+          padding: 8px 0;
+        }
+        i {
+          font-size: 20px;
+        }
+      }
+    }
+    /deep/.van-divider {
+      margin: 10px;
+    }
+  }
+}
+</style>

+ 61 - 0
src/views/patent/parts/banner-1.vue

@@ -0,0 +1,61 @@
+<template>
+  <div id="banner-1">
+    <van-row>
+      <van-col span="24" class="main">
+        <van-col span="24" class="one">
+          <van-swipe :autoplay="3000">
+            <van-swipe-item class="images" v-for="(item, index) in images" :key="index">
+              <img :src="item.url" />
+            </van-swipe-item>
+          </van-swipe>
+        </van-col>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'banner-1',
+  props: {},
+  components: {},
+  data: function () {
+    return {
+      // 广告位
+      images: [{ url: require('@a/userbj.jpg') }, { url: require('@a/userbj.jpg') }],
+    };
+  },
+  created() {},
+  methods: {},
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.main {
+  .one {
+    .images {
+      height: 100px;
+      overflow: hidden;
+      img {
+        width: 100%;
+        height: 100px;
+        overflow: hidden;
+      }
+    }
+  }
+}
+</style>

+ 62 - 0
src/views/patent/parts/patent-1.vue

@@ -0,0 +1,62 @@
+<template>
+  <div id="patent-1">
+    <el-row>
+      <el-col :span="24" class="main">
+        <list-1 :list="list" @detail="detail"></list-1>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import list1 from '../market/parts/list-1.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: patent } = createNamespacedHelpers('patent');
+export default {
+  name: 'patent-1',
+  props: {},
+  components: {
+    list1,
+  },
+  data: function () {
+    return {
+      list: [],
+    };
+  },
+  async created() {
+    await this.search();
+  },
+  methods: {
+    ...patent(['query']),
+    async search({ skip = 0, limit = 4, searchName, ...info } = {}) {
+      let res = await this.query({ skip, limit, ...info });
+      if (this.$checkRes(res)) {
+        this.$set(this, `list`, res.data);
+      }
+    },
+    // 查看详情
+    detail(data) {
+      this.$router.push({ path: '/service/patent/market/detail', query: { id: data._id } });
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.main {
+  padding: 0 8px;
+}
+</style>

+ 58 - 0
src/views/patent/parts/trans-1.vue

@@ -0,0 +1,58 @@
+<template>
+  <div id="trans-1">
+    <van-row>
+      <van-col span="24" class="main">
+        <list-1 :list="list" @detail="detail"></list-1>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script>
+import list1 from '../market/parts/list-2.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: patenttrans } = createNamespacedHelpers('patenttrans');
+export default {
+  name: 'trans-1',
+  props: {},
+  components: {
+    list1,
+  },
+  data: function () {
+    return {
+      list: [],
+      limit: 4,
+    };
+  },
+  async created() {
+    await this.search();
+  },
+  methods: {
+    ...patenttrans(['query']),
+    async search({ skip = 0, limit = this.limit, ...info } = {}) {
+      let res = await this.query({ skip, limit, ...info });
+      if (this.$checkRes(res)) {
+        this.$set(this, `list`, res.data);
+      }
+    },
+    detail(data) {
+      this.$router.push({ path: '/service/patent/market/transDetail', query: { id: data._id } });
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 101 - 0
src/views/patent/parts/userTop.vue

@@ -0,0 +1,101 @@
+<template>
+  <div id="userTop">
+    <van-row>
+      <van-col span="24" class="main">
+        <van-col span="24" class="one" @click.native="back">
+          <van-col span="24" class="image">
+            <van-image :src="icon"></van-image>
+          </van-col>
+          <van-col span="24" class="other">
+            <van-col span="24" class="otherInfo">
+              {{ userInfo.name || '游客' }}
+            </van-col>
+            <van-col span="24" class="otherInfo">
+              {{ userInfo.phone || '游客123456' }}
+            </van-col>
+          </van-col>
+        </van-col>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+var moment = require('moment');
+export default {
+  name: 'userTop',
+  props: {},
+  components: {},
+  data: function () {
+    return {
+      icon: require('@a/icon.jpg'),
+      userInfo: {},
+    };
+  },
+  created() {
+    this.searchUser();
+  },
+  methods: {
+    // 查询用户
+    searchUser() {
+      if (this.user) {
+        this.$set(this, `userInfo`, this.user);
+      } else {
+        let data = {
+          name: '游客',
+          phone: moment(new Date()).valueOf(),
+        };
+        this.$set(this, `userInfo`, data);
+      }
+    },
+    // 返回个人中心
+    back() {
+      this.$router.push({ path: '/account/index' });
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.main {
+  .one {
+    background: url('~@/assets/userbj.jpg');
+    background-repeat: no-repeat;
+    background-size: 100% 100%;
+    .image {
+      text-align: center;
+      padding: 10px 0 10px 0;
+      .van-image {
+        width: 66px;
+        height: 66px;
+        /deep/.van-image__img {
+          border-radius: 90px;
+        }
+      }
+    }
+    .other {
+      text-align: center;
+      .otherInfo {
+        font-size: 16px;
+        color: #000;
+        font-weight: bold;
+        margin: 0 0 5px 0;
+      }
+    }
+  }
+}
+</style>

+ 63 - 0
src/views/patent/user-role/user-1.vue

@@ -0,0 +1,63 @@
+<template>
+  <div id="user-1">
+    <admin-frame :useTop="false" :usePage="false" :useNav="false">
+      <template v-slot:info>
+        <van-col span="24" class="one">
+          <user-top></user-top>
+        </van-col>
+        <van-col span="24" class="two" :style="{ height: client.height - 140 + 'px' }">
+          <admin-btn></admin-btn>
+        </van-col>
+      </template>
+    </admin-frame>
+  </div>
+</template>
+
+<script>
+import adminBtn from '../admin/adminBtn.vue';
+import userTop from '../parts/userTop.vue';
+import adminFrame from '@frame/src/components/mobile-frame/mobile-main.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'user-1',
+  props: {},
+  components: {
+    adminFrame,
+    userTop,
+    adminBtn,
+  },
+  data: function () {
+    return {
+      client: {},
+    };
+  },
+  created() {},
+  methods: {},
+  mounted() {
+    let client = {
+      height: document.documentElement.clientHeight || document.body.clientHeight,
+      width: document.documentElement.clientWidth || document.body.clientWidth,
+    };
+    this.$set(this, `client`, client);
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.two {
+  overflow-y: auto;
+}
+</style>

+ 46 - 0
src/views/patent/user-role/user-2.vue

@@ -0,0 +1,46 @@
+<template>
+  <div id="user-2">
+    <admin-frame :useTop="false" :usePage="false" :useNav="false">
+      <template v-slot:info>
+        <user-top></user-top>
+        <mech-btn></mech-btn>
+      </template>
+    </admin-frame>
+  </div>
+</template>
+
+<script>
+import mechBtn from '../mech/mechBtn.vue';
+import userTop from '../parts/userTop.vue';
+import adminFrame from '@frame/src/components/mobile-frame/mobile-main.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'user-2',
+  props: {},
+  components: {
+    adminFrame,
+    userTop,
+    mechBtn,
+  },
+  data: function () {
+    return {};
+  },
+  created() {},
+  methods: {},
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 44 - 0
src/views/patent/user-role/user-3.vue

@@ -0,0 +1,44 @@
+<template>
+  <div id="user-3">
+    <van-row>
+      <van-col span="24" class="main">
+        <user-top></user-top>
+        <user-btn></user-btn>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script>
+import userTop from '../parts/userTop.vue';
+import userBtn from '../user/userBtn.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'user-3',
+  props: {},
+  components: {
+    userTop,
+    userBtn,
+  },
+  data: function () {
+    return {};
+  },
+  created() {},
+  methods: {},
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 232 - 0
src/views/patent/user/userBtn.vue

@@ -0,0 +1,232 @@
+<template>
+  <div id="userBtn">
+    <van-row>
+      <van-col span="24" class="main">
+        <van-col span="24" class="one">
+          <van-divider content-position="left" :style="{ color: '#1989fa', borderColor: '#1989fa' }">我的消息</van-divider>
+          <van-col span="24" class="one_1">
+            <van-col span="8" class="one_1action onlyColor" @click.native="pathBtn('user/message', 'unRead')">
+              <van-goods-action-icon text="未读" :badge="numData.message ? numData.message.unread : ''">
+                <template #icon><i class="iconfont icon-xiaoxi"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+            <van-col span="8" class="one_1action" @click.native="pathBtn('user/message', 'read')">
+              <van-goods-action-icon text="已读" badge="">
+                <template #icon><i class="iconfont icon-xiaoxi"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+            <van-col span="8" class="one_1action" @click.native="pathBtn('user/message', 'notice')">
+              <van-goods-action-icon text="通知" badge="">
+                <template #icon><i class="iconfont icon-tongzhi"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+          </van-col>
+        </van-col>
+        <van-col span="24" class="one">
+          <van-divider content-position="left" :style="{ color: '#1989fa', borderColor: '#1989fa' }">我的申请</van-divider>
+          <van-col span="24" class="one_1">
+            <van-col span="8" class="one_1action" @click.native="pathBtn('user/apply', 'apply')">
+              <van-goods-action-icon text="专利申请" :badge="numData.apply ? numData.apply.apply : '0'">
+                <template #icon><i class="iconfont icon-jiaodi"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+            <van-col span="8" class="one_1action" @click.native="pathBtn('user/apply', 'analysis')">
+              <van-goods-action-icon text="查新检索" :badge="numData.apply ? numData.apply.analysis : '0'">
+                <template #icon><i class="iconfont icon-pinggu"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+            <van-col span="8" class="one_1action" @click.native="pathBtn('user/apply', 'assessment')">
+              <van-goods-action-icon text="价值评估" :badge="numData.apply ? numData.apply.access : '0'">
+                <template #icon><i class="iconfont icon-pinggu"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+          </van-col>
+        </van-col>
+        <van-col span="24" class="one">
+          <van-divider content-position="left" :style="{ color: '#1989fa', borderColor: '#1989fa' }">我的专利</van-divider>
+          <van-col span="24" class="one_1">
+            <van-col span="8" class="one_1action" @click.native="pathBtn('user/patent', 'information')">
+              <van-goods-action-icon text="专利信息" :badge="numData.patent ? numData.patent.information : '0'">
+                <template #icon><i class="iconfont icon-jiaodi"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+            <van-col span="8" class="one_1action" @click.native="pathBtn('user/patent', 'navigation')">
+              <van-goods-action-icon text="专利导航" badge="">
+                <template #icon><i class="iconfont icon-pinggu"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+            <van-col span="8" class="one_1action" @click.native="pathBtn('user/patent', 'early')">
+              <van-goods-action-icon text="专利预警" :badge="numData.patent ? numData.patent.early : '0'">
+                <template #icon><i class="iconfont icon-pinggu"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+          </van-col>
+        </van-col>
+        <van-col span="24" class="one">
+          <van-divider content-position="left" :style="{ color: '#1989fa', borderColor: '#1989fa' }">我的交易</van-divider>
+          <van-col span="24" class="one_1">
+            <van-col span="8" class="one_1action" @click.native="pathBtn('user/transaction', 'index', 'type=转让')">
+              <van-goods-action-icon text="专利转让" :badge="numData.transaction ? numData.transaction.trans1 : '0'">
+                <template #icon><i class="iconfont icon-jiaodi"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+            <van-col span="8" class="one_1action" @click.native="pathBtn('user/transaction', 'index', 'type=合作')">
+              <van-goods-action-icon text="专利合作" :badge="numData.transaction ? numData.transaction.trans2 : '0'">
+                <template #icon><i class="iconfont icon-pinggu"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+            <van-col span="8" class="one_1action" @click.native="pathBtn('user/transaction', 'index', 'type=招商')">
+              <van-goods-action-icon text="专利招商" :badge="numData.transaction ? numData.transaction.trans3 : '0'">
+                <template #icon><i class="iconfont icon-pinggu"></i></template>
+              </van-goods-action-icon>
+            </van-col>
+          </van-col>
+        </van-col>
+        <van-col span="24" class="two">
+          <van-col span="24" class="two_1">
+            <banner-1></banner-1>
+          </van-col>
+          <van-col span="24" class="two_2">
+            <van-divider :style="{ color: '#1989fa', borderColor: '#1989fa' }" @click="more()"> <span>专利超市</span><span>More</span> </van-divider>
+            <van-tabs v-model="active" color="#409eff">
+              <van-tab title="授权专利" name="1">
+                <patent-1></patent-1>
+              </van-tab>
+              <van-tab title="专利转让" name="2">
+                <trans-1></trans-1>
+              </van-tab>
+            </van-tabs>
+          </van-col>
+        </van-col>
+      </van-col>
+    </van-row>
+    <van-col span="24" class="sticky">
+      <span @click="chat">咨询<br />服务</span>
+    </van-col>
+    <van-dialog v-model="chatShow" class="dialog" title="咨询服务" :showConfirmButton="false" :showCancelButton="false" :closeOnClickOverlay="true">
+      <frame-chat></frame-chat>
+    </van-dialog>
+  </div>
+</template>
+
+<script>
+import banner1 from '../parts/banner-1.vue';
+import patent1 from '../parts/patent-1.vue';
+import trans1 from '../parts/trans-1.vue';
+import frameChat from '@/layout/chatCommon/chat.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: statistics } = createNamespacedHelpers('statistics');
+export default {
+  name: 'userBtn',
+  props: {},
+  components: {
+    frameChat,
+    banner1,
+    patent1,
+    trans1,
+  },
+  data: function () {
+    return {
+      chatShow: false,
+      active: '1',
+      numData: {},
+    };
+  },
+  created() {
+    if (this.user.id) this.search();
+  },
+  methods: {
+    ...statistics(['patentUserIndex']),
+    async search({ skip = 0, limit = 10, ...info } = {}) {
+      let res = await this.patentUserIndex({ id: this.user.id });
+      if (this.$checkRes(res)) {
+        this.$set(this, `numData`, res.data);
+      }
+    },
+    pathBtn(type, path, query) {
+      if (this.user) {
+        this.$router.push({ path: `/service/patent/${type}/${path}?${query}` });
+      } else {
+        this.$router.push({ path: '/login', query: { path: '/service/patent/index', type: '1' } });
+      }
+    },
+    chat() {
+      // this.chatShow = true;
+      this.$router.push({ path: '/service/patent/user/chat/index' });
+    },
+    // 更多
+    more() {
+      this.$router.push({ path: '/service/patent/market/index' });
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.main {
+  .one {
+    .one_1 {
+      .one_1action {
+        /deep/.van-info {
+          background-color: #409eff;
+        }
+        /deep/.van-goods-action-icon {
+          padding: 8px 0;
+        }
+        i {
+          font-size: 20px;
+        }
+      }
+    }
+    /deep/.van-divider {
+      margin: 10px;
+    }
+  }
+  .two {
+    .two_1 {
+      margin: 5px 0 0 0;
+    }
+    .two_2 {
+      span:nth-child(2) {
+        margin: 0 10px;
+      }
+    }
+  }
+}
+.sticky {
+  position: fixed;
+  width: 15%;
+  bottom: 30px;
+  z-index: 999;
+  text-align: right;
+  right: 15px;
+  span {
+    display: inline-block;
+    width: 50px;
+    padding: 6px 0;
+    background-color: #409eff;
+    color: #ffffff;
+    border-radius: 90px;
+    font-size: 14px;
+    text-align: center;
+  }
+}
+.onlyColor {
+  /deep/.van-info {
+    background-color: #ff0000 !important;
+  }
+}
+</style>