guhongwei 3 tahun lalu
induk
melakukan
46c859930d
33 mengubah file dengan 2888 tambahan dan 1 penghapusan
  1. 80 0
      src/router/index.js
  2. 89 0
      src/views/patent/mech/examine/contract.vue
  3. 142 0
      src/views/patent/mech/examine/contract/check-1.vue
  4. 64 0
      src/views/patent/mech/examine/contract/info-1.vue
  5. 115 0
      src/views/patent/mech/examine/contract/list-1.vue
  6. 76 0
      src/views/patent/mech/examine/contract_check.vue
  7. 114 0
      src/views/patent/mech/examine/patent.vue
  8. 82 0
      src/views/patent/mech/examine/patent/checkForm.vue
  9. 97 0
      src/views/patent/mech/examine/patent/info-1.vue
  10. 119 0
      src/views/patent/mech/examine/patent/list-1.vue
  11. 101 0
      src/views/patent/mech/examine/trans.vue
  12. 1 1
      src/views/patent/mech/mechBtn.vue
  13. 68 0
      src/views/patent/mech/message/notice.vue
  14. 79 0
      src/views/patent/mech/message/notice_create.vue
  15. 58 0
      src/views/patent/mech/message/parts/form-1.vue
  16. 95 0
      src/views/patent/mech/message/parts/list-1.vue
  17. 92 0
      src/views/patent/mech/message/parts/list-2.vue
  18. 65 0
      src/views/patent/mech/message/read.vue
  19. 73 0
      src/views/patent/mech/message/unRead.vue
  20. 65 0
      src/views/patent/mech/patent/early/index.vue
  21. 73 0
      src/views/patent/mech/patent/information/detail.vue
  22. 116 0
      src/views/patent/mech/patent/information/index.vue
  23. 112 0
      src/views/patent/mech/patent/navigation/index.vue
  24. 64 0
      src/views/patent/mech/patent/navigation/info.vue
  25. 90 0
      src/views/patent/mech/patent/navigation/parts/detail-1.vue
  26. 185 0
      src/views/patent/mech/patent/navigation/parts/search-1.vue
  27. 84 0
      src/views/patent/mech/patent/parts/detail-1.vue
  28. 94 0
      src/views/patent/mech/patent/parts/list-1.vue
  29. 83 0
      src/views/patent/mech/patent/parts/list-4.vue
  30. 72 0
      src/views/patent/mech/transaction/index.vue
  31. 66 0
      src/views/patent/mech/transaction/info.vue
  32. 76 0
      src/views/patent/mech/transaction/parts/info-1.vue
  33. 98 0
      src/views/patent/mech/transaction/parts/list-1.vue

+ 80 - 0
src/router/index.js

@@ -245,6 +245,86 @@ const patent = [
     meta: { title: '专利交易-填写合同' },
     component: () => import('../views/patent/user/transaction/contract.vue'),
   },
+  // 机构用户
+  // 我的消息
+  {
+    path: '/patent/mech/message/unRead',
+    meta: { title: '未读信息' },
+    component: () => import('../views/patent/mech/message/unRead.vue'),
+  },
+  {
+    path: '/patent/mech/message/read',
+    meta: { title: '已读信息' },
+    component: () => import('../views/patent/mech/message/read.vue'),
+  },
+  {
+    path: '/patent/mech/message/notice',
+    meta: { title: '通知信息' },
+    component: () => import('../views/patent/mech/message/notice.vue'),
+  },
+  {
+    path: '/patent/mech/message/notice_create',
+    meta: { title: '通知信息-编辑通知' },
+    component: () => import('../views/patent/mech/message/notice_create.vue'),
+  },
+  // 我的审核
+  {
+    path: '/patent/mech/examine/patent',
+    meta: { title: '专利审核' },
+    component: () => import('../views/patent/mech/examine/patent.vue'),
+  },
+  {
+    path: '/patent/mech/examine/contract',
+    meta: { title: '合同审核' },
+    component: () => import('../views/patent/mech/examine/contract.vue'),
+  },
+  {
+    path: '/patent/mech/examine/contract_check',
+    meta: { title: '合同审核-详细信息' },
+    component: () => import('../views/patent/mech/examine/contract_check.vue'),
+  },
+  {
+    path: '/patent/mech/examine/trans',
+    meta: { title: '交易审核' },
+    component: () => import('../views/patent/mech/examine/trans.vue'),
+  },
+  // 我的专利
+  {
+    path: '/patent/mech/patent/information',
+    meta: { title: '专利信息' },
+    component: () => import('../views/patent/mech/patent/information/index.vue'),
+  },
+  {
+    path: '/patent/mech/patent/information/detail',
+    meta: { title: '专利信息-详细信息' },
+    component: () => import('../views/patent/mech/patent/information/detail.vue'),
+  },
+  {
+    path: '/patent/mech/patent/navigation',
+    meta: { title: '查新检索' },
+    component: () => import('../views/patent/mech/patent/navigation/index.vue'),
+  },
+  {
+    path: '/patent/mech/patent/navigation/info',
+    meta: { title: '查新检索-详细信息' },
+    component: () => import('../views/patent/mech/patent/navigation/info.vue'),
+  },
+  {
+    path: '/patent/mech/patent/early',
+    meta: { title: '专利预警' },
+    component: () => import('../views/patent/mech/patent/early/index.vue'),
+  },
+  // 我的交易
+  {
+    path: '/patent/mech/transaction/index',
+    meta: { title: '专利交易' },
+    component: () => import('../views/patent/mech/transaction/index.vue'),
+  },
+  {
+    path: '/patent/mech/transaction/info',
+    meta: { title: '专利交易-详细信息' },
+    component: () => import('../views/patent/mech/transaction/info.vue'),
+  },
 ];
 const web = [
   {

+ 89 - 0
src/views/patent/mech/examine/contract.vue

@@ -0,0 +1,89 @@
+<template>
+  <div id="contract">
+    <admin-frame @search="search" :limit="limit" :total="total" topType="2" @back="back" :rightArrow="false" :useNav="false">
+      <template v-slot:info>
+        <list-1 :list="list" @view="toView" @detail="detail"></list-1>
+      </template>
+    </admin-frame>
+    <van-dialog class="dialog" v-model="show" title="详细信息" :show-confirm-button="false" show-cancel-button>
+      <info-1 :info="info"></info-1>
+    </van-dialog>
+  </div>
+</template>
+
+<script>
+import list1 from './contract/list-1.vue';
+import info1 from './contract/info-1.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: 'contract',
+  props: {},
+  components: {
+    adminFrame,
+    list1,
+    info1,
+  },
+  data: function () {
+    return {
+      list: [],
+      limit: 5,
+      total: 0,
+      // 详细信息
+      show: false,
+      info: {},
+    };
+  },
+  async created() {
+    await this.search();
+  },
+  methods: {
+    ...patenttrans(['query']),
+    async search({ skip = 0, limit = this.limit, ...info } = {}) {
+      info.admin_id = this.user._id;
+      info.status = '1';
+      let res = await this.query({ skip, limit, ...info });
+      if (this.$checkRes(res)) {
+        this.$set(this, `list`, res.data);
+        this.$set(this, `total`, res.total);
+      }
+    },
+    // 合同审核
+    detail(data) {
+      this.$router.push({ path: '/patent/mech/examine/contract_check', query: { id: data.id } });
+    },
+    // 查看信息
+    toView(data) {
+      this.$set(this, `info`, data);
+      this.show = true;
+    },
+    // 返回
+    back() {
+      this.$router.push({ path: '/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>
+.dialog {
+  /deep/.van-dialog__content {
+    height: 350px;
+    overflow-y: auto;
+  }
+}
+</style>

+ 142 - 0
src/views/patent/mech/examine/contract/check-1.vue

@@ -0,0 +1,142 @@
+<template>
+  <div id="check-1">
+    <van-row>
+      <van-col span="24" class="main">
+        <van-col span="24" class="one">
+          <van-form>
+            <van-col span="24" class="one_1"> 专利转让合同 </van-col>
+            <van-col span="24" class="one_2">
+              <span>甲方(转让方):</span>
+              <span>{{ form.contract.transfer }}</span>
+            </van-col>
+            <van-col span="24" class="one_2">
+              <span>乙方(受让方):</span>
+              <span>{{ form.contract.transferee }}</span>
+            </van-col>
+            <van-col span="24" class="one_3">
+              <span>甲、乙方经过平等协商,自愿订立专利权转让合同,并共同遵照执行: </span>
+            </van-col>
+            <van-col span="24" class="one_4">
+              <span>第一条 甲方将其享有的</span>
+              <span>{{ form.contract.patent_name }}</span>
+              <span>专利权有偿转让给乙方,专利号为:</span>
+              <span>{{ form.contract.create_number }}</span>
+            </van-col>
+            <van-col span="24" class="one_4">
+              <span>第二条 甲方向乙方转让</span>
+              <span>{{ form.contract.patent_right }}</span>
+              <span>专利权;</span>
+            </van-col>
+            <van-col span="24" class="one_4">
+              <span>第三条 乙方为此向甲方支付专利权转让费用</span>
+              <span>{{ form.contract.money }}</span>
+              <span>元,于本合同生效后</span>
+              <span>{{ form.contract.days }}</span>
+              <span>天内一次付清。</span>
+            </van-col>
+            <van-col span="24" class="one_3">
+              <span>第四条 如任何一方违反本合同约定给对方造成损失,守约方可以要求对方承担违约责任;</span>
+            </van-col>
+            <van-col span="24" class="one_3">
+              <span>第五条 甲方保证此转让行为不侵犯任何第三方的合法权益;</span>
+            </van-col>
+            <van-col span="24" class="one_3">
+              <span>第六条 本合同于各方签字盖章后生效,未经各方同意,任何一方均无权修改或变更本合同约定;</span>
+            </van-col>
+            <van-col span="24" class="one_8">
+              <span>第七条 任何因本合同的履行而产生的争议,均应当友好协商解决,如无法协商解决,各方同意交由</span>
+              <span>{{ form.contract.arbirate }}</span>
+              <span>仲裁委员会按照该会现时有效的仲裁规则予以仲裁;</span>
+            </van-col>
+            <van-col span="24" class="one_3">
+              <span>第八条 本合同一式三份,双方各执一份,备案一份。</span>
+            </van-col>
+            <van-col span="24" class="btn">
+              <van-button type="info" size="small" @click="onSubmit('2')">合同通过</van-button>
+              <van-button type="danger" size="small" @click="onSubmit('-1')">合同拒绝</van-button>
+            </van-col>
+          </van-form>
+        </van-col>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'check-1',
+  props: {
+    form: { type: Object },
+  },
+  components: {},
+  data: function () {
+    return {};
+  },
+  created() {},
+  methods: {
+    onSubmit(status) {
+      this.$emit('onSubmit', status);
+    },
+  },
+
+  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 {
+    padding: 0 5px;
+    font-size: 16px;
+    span {
+      line-height: 30px;
+    }
+    .one_1 {
+      text-align: center;
+      font-weight: bold;
+      margin: 8px 0 8px 0;
+    }
+    .one_2 {
+      margin: 0 0 8px 0;
+      span:last-child {
+        display: inline-block;
+        width: 65%;
+        border-bottom: 1px solid #000;
+        font-weight: bold;
+      }
+    }
+    .one_3 {
+      margin: 0 0 8px 0;
+    }
+    .one_4 {
+      margin: 0 0 8px 0;
+      span:nth-child(2n) {
+        padding: 0 15px;
+        margin: 0 5px;
+        border-bottom: 1px solid #000;
+        font-weight: bold;
+      }
+    }
+    .btn {
+      margin: 8px 0;
+      text-align: center;
+      .van-button {
+        margin: 0 10px;
+      }
+    }
+  }
+}
+</style>

+ 64 - 0
src/views/patent/mech/examine/contract/info-1.vue

@@ -0,0 +1,64 @@
+<template>
+  <div id="info-1">
+    <van-row>
+      <van-col span="24" class="main">
+        <van-form label-width="5em">
+          <van-field v-model="info.create_number" name="create_number" label="申请号" readonly />
+          <van-field v-model="info.patent_name" name="patent_name" label="专利名称" readonly />
+          <van-field v-model="info.contact" name="contact" label="联系人" readonly />
+          <van-field v-model="info.phone" name="phone" label="联系电话" readonly />
+          <van-field v-model="info.email" name="email" label="电子邮箱" readonly />
+          <van-field v-model="info.budget" name="budget" type="digit" label="投资预算" readonly />
+          <van-field v-model="info.type" name="type" label="交易类型" readonly />
+          <van-field name="is_report" label="评估报告">
+            <template #input>
+              <van-radio-group v-model="info.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="info.is_report == true" @click="download(info.report)">下载报告</van-button>
+            </template>
+          </van-field>
+          <van-field v-model="info.requirementdesc" name="requirementdesc" label="技术说明" rows="2" autosize type="textarea" readonly />
+          <van-field v-model="info.expect" name="expect" label="商业预期" rows="2" autosize type="textarea" readonly />
+          <van-field v-model="info.condition" name="condition" label="条件及要求" rows="2" autosize type="textarea" readonly />
+        </van-form>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'info-1',
+  props: {
+    info: { type: Object },
+  },
+  components: {},
+  data: function () {
+    return {};
+  },
+  created() {},
+  methods: {
+    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></style>

+ 115 - 0
src/views/patent/mech/examine/contract/list-1.vue

@@ -0,0 +1,115 @@
+<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">
+          <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 span="24" class="btn">
+            <van-button type="info" size="small" @click="view(item)">查看信息</van-button>
+            <van-button type="info" size="small" @click="detail(item)" v-if="item.status == '1'">合同审核</van-button>
+            <van-button type="info" size="small" @click="confirm(item)" v-if="item.status == '3'">归档确认</van-button>
+          </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: {
+    // 查看信息
+    view(data) {
+      this.$emit('view', data);
+    },
+    // 合同审核
+    detail(data) {
+      this.$emit('detail', data);
+    },
+    // 归档确认
+    confirm(data) {
+      this.$emit('confirm', data);
+    },
+    // 整理状态
+    getStu(data) {
+      if (data == '0') return '待交易';
+      else if (data == '1') return '填写完合同,等待机构审核';
+      else if (data == '-1') return '填写合同审核失败,重填';
+      else if (data == '2') return '合同审核通过,待用户确认';
+      else if (data == '3') return '用户确认成功,机构归档';
+      else if (data == '-3') return '归档失败';
+      else if (data == '4') return '归档成功';
+    },
+  },
+  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;
+        }
+      }
+    }
+    .btn {
+      text-align: center;
+      .van-button {
+        margin: 0 10px;
+      }
+    }
+  }
+}
+</style>

+ 76 - 0
src/views/patent/mech/examine/contract_check.vue

@@ -0,0 +1,76 @@
+<template>
+  <div id="contract_check">
+    <admin-frame topType="2" @back="back" :rightArrow="false" :usePage="false" :useNav="false">
+      <template v-slot:info>
+        <trans-check :form="form" @onSubmit="onSubmit"></trans-check>
+      </template>
+    </admin-frame>
+  </div>
+</template>
+
+<script>
+import transCheck from './contract/check-1.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: 'contract_check',
+  props: {},
+  components: {
+    adminFrame,
+    transCheck,
+  },
+  data: function () {
+    return {
+      form: {
+        contract: {},
+      },
+    };
+  },
+  created() {
+    if (this.id) this.search();
+  },
+  methods: {
+    ...patenttrans(['fetch', 'check']),
+    async search() {
+      let res = await this.fetch(this.id);
+      if (this.$checkRes(res)) {
+        this.$set(this, `form`, res.data);
+      }
+    },
+    // 审核合同提交
+    async onSubmit(status) {
+      let data = this.form;
+      data.status = status;
+      let res = await this.check(data);
+      if (this.$checkRes(res)) {
+        this.$toast({ type: `success`, message: `审核成功` });
+        this.back();
+      } else {
+        this.$toast({ type: `success`, message: `${res.errmsg}` });
+      }
+    },
+    back() {
+      this.$router.push({ path: '/patent/mech/examine/contract' });
+    },
+  },
+  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>

+ 114 - 0
src/views/patent/mech/examine/patent.vue

@@ -0,0 +1,114 @@
+<template>
+  <div id="patent">
+    <admin-frame @search="search" :limit="limit" :total="total" topType="2" @back="back" :rightArrow="false" :useNav="false">
+      <template v-slot:info>
+        <list-1 :list="list" @view="view" @examine="toExamine"></list-1>
+      </template>
+    </admin-frame>
+    <van-dialog class="dialog" v-model="show" title="详细信息" :show-confirm-button="false" show-cancel-button>
+      <info-1 :info="info"></info-1>
+    </van-dialog>
+    <van-dialog class="twoDialog" v-model="twoShow" title="审核信息" :show-confirm-button="false" :show-cancel-button="false" :closeOnClickOverlay="true">
+      <check-form :form="form" @onSubmit="onSubmit"></check-form>
+    </van-dialog>
+  </div>
+</template>
+
+<script>
+import list1 from './patent/list-1.vue';
+import info1 from './patent/info-1.vue';
+import checkForm from './patent/checkForm.vue';
+import adminFrame from '@frame/src/components/mobile-frame/mobile-main.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: patentapply } = createNamespacedHelpers('patentapply');
+var moment = require('moment');
+export default {
+  name: 'patent',
+  props: {},
+  components: {
+    adminFrame,
+    list1,
+    info1,
+    checkForm,
+  },
+  data: function () {
+    return {
+      list: [],
+      limit: 5,
+      total: 0,
+      // 专利申请详细信息
+      show: false,
+      info: {},
+      // 专利申请审核信息
+      twoShow: false,
+      form: {},
+    };
+  },
+  async created() {
+    await this.search();
+  },
+  methods: {
+    ...patentapply(['query', 'check']),
+    async search({ skip = 0, limit = this.limit, ...info } = {}) {
+      info.mechanism_id = this.user._id;
+      let res = await this.query({ skip, limit, ...info });
+      if (this.$checkRes(res)) {
+        this.$set(this, `list`, res.data);
+        this.$set(this, `total`, res.total);
+      }
+    },
+    // 查看
+    view(data) {
+      if (!data.questions) data.questions = {};
+      this.$set(this, `info`, data);
+      this.show = true;
+    },
+    // 审核
+    toExamine(data) {
+      this.$set(this, `form`, data);
+      this.twoShow = true;
+    },
+    // 提交审核
+    async onSubmit(data) {
+      // 申请状态修改
+      const { id, remark, status } = this.form;
+      const obj = { id, status, remark };
+      if (obj.status == '1') obj.water_number = moment(new Date()).valueOf();
+      const res = await this.check(obj);
+      if (this.$checkRes(res)) {
+        this.$toast({ type: `success`, message: `审核成功` });
+        this.search();
+        this.twoShow = false;
+      } else {
+        this.$toast({ type: `fail`, message: `${res.errmsg}` });
+      }
+    },
+    // 返回
+    back() {
+      this.$router.push({ path: '/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>
+.dialog {
+  /deep/.van-dialog__content {
+    height: 350px;
+    overflow-y: auto;
+  }
+}
+</style>

+ 82 - 0
src/views/patent/mech/examine/patent/checkForm.vue

@@ -0,0 +1,82 @@
+<template>
+  <div id="checkForm">
+    <van-row>
+      <van-col span="24" class="main">
+        <van-form @submit="onSubmit">
+          <van-field v-model="form.name" name="name" label="发明名称" readonly />
+          <van-field name="status" label="审核状态">
+            <template #input>
+              <van-radio-group v-model="form.status" direction="horizontal">
+                <van-radio name="1">通过</van-radio>
+                <van-radio name="-1">拒绝</van-radio>
+              </van-radio-group>
+            </template>
+          </van-field>
+          <van-field
+            v-model="form.remark"
+            name="remark"
+            rows="8"
+            autosize
+            label="审核意见"
+            type="textarea"
+            maxlength="100"
+            placeholder="审核意见"
+            show-word-limit
+            :rules="[{ required: true, message: '特殊情况说明' }]"
+          />
+          <div style="margin: 16px">
+            <van-button round block type="info" native-type="submit">提交</van-button>
+          </div>
+        </van-form>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: upload } = createNamespacedHelpers('upload');
+export default {
+  name: 'checkForm',
+  props: {
+    form: { type: Object },
+  },
+  components: {},
+  data: function () {
+    return {};
+  },
+  created() {},
+  methods: {
+    ...upload(['upload']),
+    onSubmit(values) {
+      this.$emit('onSubmit', values);
+    },
+    async toUpload({ file }, model) {
+      // 上传,赋值
+      const res = await this.upload({ file, dir: 'file' });
+      if (this.$checkRes(res)) {
+        this.$set(this.form, model, [{ name: res.name, url: res.uri }]);
+      }
+    },
+    toDelete(file, model) {
+      const index = this.form[model].findIndex((f) => _.isEqual(f, file));
+      this.form[model].splice(index, 1);
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 97 - 0
src/views/patent/mech/examine/patent/info-1.vue

@@ -0,0 +1,97 @@
+<template>
+  <div id="info-1">
+    <van-row>
+      <van-col span="24" class="main">
+        <van-form>
+          <van-field v-model="info.name" name="发明名称" label="发明名称" readonly />
+          <van-field v-model="info.apply_name" name="申请人" label="申请人" readonly />
+          <van-field v-model="info.water_number" name="专利用户码" label="专利用户码" readonly />
+          <van-field v-model="info.type" name="专利类型" label="专利类型" readonly />
+          <van-col span="24" class="other">
+            <span>发明人:</span><span v-for="(item, index) in info.inventor" :key="index">{{ item.name }};</span>
+          </van-col>
+          <van-col span="24" class="other">
+            <span>技术联系人:</span><span v-for="(item, index) in info.contact" :key="index">{{ item.name }};</span>
+          </van-col>
+          <van-field v-model="info.phone" name="联系人电话" label="联系人电话" readonly />
+          <van-field v-model="info.email" name="联系人邮箱" label="联系人邮箱" readonly />
+          <van-field v-model="info.questions.q8" type="textarea" rows="1" autosize name="特殊情况说明" label="特殊情况说明" readonly />
+          <van-field v-model="info.questions.q1" type="textarea" rows="1" autosize name="本发明的技术领域" label="本发明的技术领域" readonly />
+          <van-field v-model="info.questions.q2" type="textarea" rows="1" autosize name="与本发明相关的背景技术" label="与本发明相关的背景技术" readonly />
+          <van-field
+            v-model="info.questions.q3"
+            type="textarea"
+            rows="1"
+            autosize
+            name="现有技术的缺点及本发明所要解决的技术问题"
+            label="现有技术的缺点及本发明所要解决的技术问题"
+            readonly
+          />
+          <van-field v-model="info.questions.q4" type="textarea" rows="1" autosize name="本发明技术方案的详细阐述" label="本发明技术方案的详细阐述" readonly />
+          <van-field v-model="info.questions.q5" type="textarea" rows="1" autosize name="本申请的关键点和欲保护点" label="本申请的关键点和欲保护点" readonly />
+          <van-field
+            v-model="info.questions.q6"
+            type="textarea"
+            rows="1"
+            autosize
+            name="与本发明最相似,相近的实现技术,方案相比,本发明有何优点"
+            label="与本发明最相似,相近的实现技术,方案相比,本发明有何优点"
+            readonly
+          />
+          <van-field
+            v-model="info.questions.q7"
+            type="textarea"
+            rows="1"
+            autosize
+            name="针对本发明技术方案,是否还有别的替代方案"
+            label="针对本发明技术方案,是否还有别的替代方案"
+            readonly
+          />
+        </van-form>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'info-1',
+  props: {
+    info: { type: Object },
+  },
+  components: {},
+  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>
+.other {
+  background-color: #ffffff;
+  padding: 8px 18px;
+  span {
+    color: #666;
+    font-size: 15px;
+  }
+  span:last-child {
+    color: #000;
+  }
+}
+</style>

+ 119 - 0
src/views/patent/mech/examine/patent/list-1.vue

@@ -0,0 +1,119 @@
+<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">
+          <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.apply_name || '暂无' }}</span>
+            </van-col>
+            <van-col span="24" class="otherInfo">
+              专利用户码:<span>{{ item.water_number || '暂无' }}</span>
+            </van-col>
+            <van-col span="24" class="otherInfo">
+              申请类型:<span>{{ item.type || '暂无' }}</span>
+            </van-col>
+            <van-col span="24" class="otherInfo">
+              申请状态:<span>{{ getStu(item.status) }}</span>
+            </van-col>
+          </van-col>
+          <van-col span="24" class="btn">
+            <van-button size="small" type="info" @click="view(item)">查看信息</van-button>
+            <van-button size="small" type="info" @click="download(item)">审查文件下载</van-button>
+            <van-button size="small" type="info" @click="examine(item)" v-if="item.status == '0'">审核申请</van-button>
+          </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: {
+    view(data) {
+      this.$emit('view', data);
+    },
+    examine(data) {
+      this.$emit('examine', data);
+    },
+    // 整理状态
+    getStu(status) {
+      if (status == '0') return '已提交给相应机构,请等待审核';
+      else if (status == '1') return '机构审核通过,已提交给管理员,请等待审核';
+      else if (status == '-1') return '机构审核未通过,请查看审核意见,并重新提交申请';
+      else if (status == '2') return '管理员审核通过';
+      else if (status == '-2') return '管理员审核未通过,请查看审核意见,并重新提交申请';
+    },
+    // 审查文件下载
+    download(data) {
+      if (data.check_url.length > 0) {
+        let url = data.check_url.map((i) => i.url);
+        window.location.href = `${process.env.VUE_APP_HOST}/${url[0]}`;
+      } else {
+        this.$toast({ type: `fail`, message: `未上传文件` });
+      }
+    },
+  },
+  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;
+        }
+      }
+    }
+    .btn {
+      text-align: center;
+      .van-button {
+        margin: 0 5px;
+      }
+    }
+  }
+}
+</style>

+ 101 - 0
src/views/patent/mech/examine/trans.vue

@@ -0,0 +1,101 @@
+<template>
+  <div id="trans">
+    <admin-frame @search="search" :limit="limit" :total="total" topType="2" @back="back" :rightArrow="false" :useNav="false">
+      <template v-slot:info>
+        <list-1 :list="list" @view="toView" @confirm="confirm"></list-1>
+      </template>
+    </admin-frame>
+    <van-dialog class="dialog" v-model="show" title="详细信息" :show-confirm-button="false" show-cancel-button>
+      <info-1 :info="info"></info-1>
+    </van-dialog>
+  </div>
+</template>
+
+<script>
+import list1 from './contract/list-1.vue';
+import info1 from './contract/info-1.vue';
+import adminFrame from '@frame/src/components/mobile-frame/mobile-main.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: patenttrans } = createNamespacedHelpers('patenttrans');
+const { mapActions: patentinfo } = createNamespacedHelpers('patentinfo');
+export default {
+  name: 'trans',
+  props: {},
+  components: {
+    adminFrame,
+    list1,
+    info1,
+  },
+  data: function () {
+    return {
+      list: [],
+      limit: 5,
+      total: 0,
+      // 详细信息
+      show: false,
+      info: {},
+    };
+  },
+  async created() {
+    await this.search();
+  },
+  methods: {
+    ...patenttrans(['query', 'check']),
+    ...patentinfo(['update']),
+    async search({ skip = 0, limit = this.limit, ...info } = {}) {
+      info.admin_id = this.user._id;
+      info.status = '3';
+      let res = await this.query({ skip, limit, ...info });
+      if (this.$checkRes(res)) {
+        this.$set(this, `list`, res.data);
+        this.$set(this, `total`, res.total);
+      }
+    },
+    // 查看信息
+    toView(data) {
+      this.$set(this, `info`, data);
+      this.show = true;
+    },
+    // 归档确认
+    async confirm(data) {
+      data.status = '4';
+      let res = await this.check(data);
+      if (this.$checkRes(res)) {
+        let arr = await this.update({ id: data.patent_id, trans_status: '1' });
+        if (this.$checkRes(arr)) {
+          this.$toast({ type: `success`, message: `归档成功,交易结束` });
+          this.search();
+        }
+      } else {
+        this.$toast({ type: `success`, message: `${res.errmsg}` });
+      }
+    },
+    // 返回
+    back() {
+      this.$router.push({ path: '/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>
+.dialog {
+  /deep/.van-dialog__content {
+    height: 350px;
+    overflow-y: auto;
+  }
+}
+</style>

+ 1 - 1
src/views/patent/mech/mechBtn.vue

@@ -99,7 +99,7 @@ export default {
   created() {},
   methods: {
     pathBtn(type, path, query) {
-      this.$router.push({ path: `/service/patent/${type}/${path}?${query}` });
+      this.$router.push({ path: `/patent/${type}/${path}?${query}` });
     },
   },
   computed: {

+ 68 - 0
src/views/patent/mech/message/notice.vue

@@ -0,0 +1,68 @@
+<template>
+  <div id="read">
+    <admin-frame @search="search" :limit="limit" :total="total" topType="2" @back="back" @add="add" :useNav="false">
+      <template v-slot:info>
+        <list-2 :list="list"></list-2>
+      </template>
+    </admin-frame>
+  </div>
+</template>
+
+<script>
+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: patentnotice } = createNamespacedHelpers('patentnotice');
+export default {
+  name: 'read',
+  props: {},
+  components: {
+    adminFrame,
+    list2,
+  },
+  data: function () {
+    return {
+      limit: 5,
+      total: 0,
+      list: [],
+    };
+  },
+  async created() {
+    this.search();
+  },
+  methods: {
+    ...patentnotice(['query']),
+    async search({ skip = 0, limit = this.limit, ...info } = {}) {
+      info.to_id = this.user._id;
+      let res = await this.query({ skip, limit, ...info });
+      if (this.$checkRes(res)) {
+        this.$set(this, `list`, res.data);
+        this.$set(this, `total`, res.total);
+      }
+    },
+    // 添加
+    add() {
+      this.$router.push({ path: '/patent/mech/message/notice_create' });
+    },
+    // 返回
+    back() {
+      this.$router.push({ path: '/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>

+ 79 - 0
src/views/patent/mech/message/notice_create.vue

@@ -0,0 +1,79 @@
+<template>
+  <div id="notice_create">
+    <admin-frame topType="2" @back="back" :rightArrow="false" :usePage="false" :useNav="false">
+      <template v-slot:info>
+        <notice-form :form="form" @onSubmit="onSubmit"></notice-form>
+      </template>
+    </admin-frame>
+  </div>
+</template>
+
+<script>
+import noticeForm from './parts/form-1.vue';
+import adminFrame from '@frame/src/components/mobile-frame/mobile-main.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: patentnotice } = createNamespacedHelpers('patentnotice');
+export default {
+  name: 'detail',
+  props: {},
+  components: {
+    adminFrame,
+    noticeForm,
+  },
+  data: function () {
+    return {
+      form: {},
+    };
+  },
+  async created() {
+    this.search();
+  },
+  methods: {
+    ...patentnotice(['create']),
+    search() {
+      let data = { send_id: this.user.id, send_name: this.user.name, to_type: '3' };
+      this.$set(this, `form`, data);
+    },
+    async onSubmit(data) {
+      let res = await this.create(data);
+      if (this.$checkRes(res)) {
+        this.$toast({ type: `success`, message: `发送通知成功` });
+        this.back();
+      } else {
+        this.$toast({ type: `success`, message: `${res.errmsg}` });
+      }
+    },
+    // 返回
+    back() {
+      this.$router.push({ path: '/patent/mech/message/notice' });
+    },
+  },
+  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>
+.one {
+  .one_1 {
+    text-align: center;
+    .van-button {
+      margin: 0 5px 10px 5px;
+    }
+  }
+}
+</style>

+ 58 - 0
src/views/patent/mech/message/parts/form-1.vue

@@ -0,0 +1,58 @@
+<template>
+  <div id="form-1">
+    <van-row>
+      <van-col span="24" class="main">
+        <van-form @submit="onSubmit" label-width="4em">
+          <van-field v-model="form.send_id" name="send_id" label="发送人id" style="display: none" />
+          <van-field v-model="form.send_name" name="send_name" label="发送人" readonly />
+          <van-field name="to_type" label="接收用户">
+            <template #input>
+              <van-radio-group v-model="form.to_type" direction="horizontal">
+                <van-radio name="3">平台用户</van-radio>
+              </van-radio-group>
+            </template>
+          </van-field>
+          <van-field v-model="form.content" name="content" rows="2" autosize label="发送内容" type="textarea" placeholder="发送内容" />
+          <div style="margin: 16px">
+            <van-button round block type="info" native-type="submit">提交</van-button>
+          </div>
+        </van-form>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'form-1',
+  props: {
+    form: { type: Object },
+  },
+  components: {},
+  data: function () {
+    return {};
+  },
+  created() {},
+  methods: {
+    onSubmit(values) {
+      this.$emit('onSubmit', values);
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 95 - 0
src/views/patent/mech/message/parts/list-1.vue

@@ -0,0 +1,95 @@
+<template>
+  <div id="list-1">
+    <van-col span="24" class="main">
+      <van-col span="24" class="list" v-for="(item, index) in list" :key="index">
+        <van-col span="24" class="other">
+          <van-col span="24" class="otherInfo">
+            <span>{{ item.content || '暂无' }}</span>
+          </van-col>
+          <van-col span="24" class="otherInfo">
+            发送时间:<span>{{ getDate(item.meta) }}</span>
+          </van-col>
+          <van-col span="24" class="otherInfo">
+            是否已读:<span>{{ item.is_read ? '已读' : '未读' }}</span>
+          </van-col>
+        </van-col>
+        <van-col span="24" class="btn" v-if="item.is_read == false">
+          <van-button size="small" type="info" @click="update(item)">消息已读</van-button>
+        </van-col>
+      </van-col>
+    </van-col>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+var moment = require('moment');
+export default {
+  name: 'list-1',
+  props: {
+    list: { type: Array },
+  },
+  components: {},
+  data: function () {
+    return {};
+  },
+  created() {},
+  methods: {
+    update(data) {
+      this.$emit('update', data);
+    },
+    getDate(val) {
+      let newDate = moment(val.createdAt).format('YYYY-MM-DD HH:mm:ss');
+      if (newDate) return newDate;
+    },
+  },
+  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 0 0 0;
+  .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;
+          line-height: 20px;
+        }
+      }
+    }
+    .btn {
+      text-align: center;
+      .van-button {
+        margin: 0 5px;
+      }
+    }
+  }
+}
+</style>

+ 92 - 0
src/views/patent/mech/message/parts/list-2.vue

@@ -0,0 +1,92 @@
+<template>
+  <div id="list-2">
+    <van-col span="24" class="main">
+      <van-col span="24" class="list" v-for="(item, index) in list" :key="index">
+        <van-col span="24" class="other">
+          <van-col span="24" class="otherInfo">
+            <span>{{ item.content || '暂无' }}</span>
+          </van-col>
+          <van-col span="24" class="otherInfo">
+            发送人:<span>{{ item.send_name || '暂无' }}</span>
+          </van-col>
+          <van-col span="24" class="otherInfo">
+            发送时间:<span>{{ getDate(item.meta) }}</span>
+          </van-col>
+        </van-col>
+      </van-col>
+    </van-col>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+var moment = require('moment');
+export default {
+  name: 'list-2',
+  props: {
+    list: { type: Array },
+  },
+  components: {},
+  data: function () {
+    return {};
+  },
+  created() {},
+  methods: {
+    update(data) {
+      this.$emit('update', data);
+    },
+    getDate(val) {
+      let newDate = moment(val.createdAt).format('YYYY-MM-DD HH:mm:ss');
+      if (newDate) return newDate;
+    },
+  },
+  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 0 0 0;
+  .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;
+          line-height: 20px;
+        }
+      }
+    }
+    .btn {
+      text-align: center;
+      .van-button {
+        margin: 0 5px;
+      }
+    }
+  }
+}
+</style>

+ 65 - 0
src/views/patent/mech/message/read.vue

@@ -0,0 +1,65 @@
+<template>
+  <div id="read">
+    <admin-frame @search="search" :limit="limit" :total="total" topType="2" @back="back" :rightArrow="false" :useNav="false">
+      <template v-slot:info>
+        <list-1 :list="list"></list-1>
+      </template>
+    </admin-frame>
+  </div>
+</template>
+
+<script>
+import list1 from './parts/list-1.vue';
+import adminFrame from '@frame/src/components/mobile-frame/mobile-main.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: patentexamine } = createNamespacedHelpers('patentexamine');
+export default {
+  name: 'read',
+  props: {},
+  components: {
+    adminFrame,
+    list1,
+  },
+  data: function () {
+    return {
+      limit: 5,
+      total: 0,
+      list: [],
+    };
+  },
+  async created() {
+    this.search();
+  },
+  methods: {
+    ...patentexamine(['query']),
+    async search({ skip = 0, limit = this.limit, ...info } = {}) {
+      info.to = this.user.id;
+      info.is_read = true;
+      let res = await this.query({ skip, limit, ...info });
+      if (this.$checkRes(res)) {
+        this.$set(this, `list`, res.data);
+        this.$set(this, `total`, res.total);
+      }
+    },
+    // 返回
+    back() {
+      this.$router.push({ path: '/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>

+ 73 - 0
src/views/patent/mech/message/unRead.vue

@@ -0,0 +1,73 @@
+<template>
+  <div id="unRead">
+    <admin-frame @search="search" :limit="limit" :total="total" topType="2" @back="back" :rightArrow="false" :useNav="false">
+      <template v-slot:info>
+        <list-1 :list="list" @update="toUpdate"></list-1>
+      </template>
+    </admin-frame>
+  </div>
+</template>
+
+<script>
+import list1 from './parts/list-1.vue';
+import adminFrame from '@frame/src/components/mobile-frame/mobile-main.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: patentexamine } = createNamespacedHelpers('patentexamine');
+export default {
+  name: 'unRead',
+  props: {},
+  components: {
+    adminFrame,
+    list1,
+  },
+  data: function () {
+    return {
+      limit: 5,
+      total: 0,
+      list: [],
+    };
+  },
+  async created() {
+    this.search();
+  },
+  methods: {
+    ...patentexamine(['query', 'update']),
+    async search({ skip = 0, limit = this.limit, ...info } = {}) {
+      info.to = this.user.id;
+      info.is_read = false;
+      let res = await this.query({ skip, limit, ...info });
+      if (this.$checkRes(res)) {
+        this.$set(this, `list`, res.data);
+        this.$set(this, `total`, res.total);
+      }
+    },
+    async toUpdate(data) {
+      data.is_read = true;
+      let res = await this.update(data);
+      if (this.$checkRes(res)) {
+        this.$toast({ type: 'success', message: '取消提醒成功' });
+        this.search();
+      }
+    },
+    // 返回
+    back() {
+      this.$router.push({ path: '/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>

+ 65 - 0
src/views/patent/mech/patent/early/index.vue

@@ -0,0 +1,65 @@
+<template>
+  <div id="index">
+    <admin-frame @search="search" :limit="limit" :total="total" topType="2" @back="back" :rightArrow="false" :useNav="false">
+      <template v-slot:info>
+        <list-4 :list="list"></list-4>
+      </template>
+    </admin-frame>
+  </div>
+</template>
+
+<script>
+import list4 from '../parts/list-4.vue';
+import adminFrame from '@frame/src/components/mobile-frame/mobile-main.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: patentearly } = createNamespacedHelpers('patentearly');
+export default {
+  name: 'index',
+  props: {},
+  components: {
+    adminFrame,
+    list4,
+  },
+  data: function () {
+    return {
+      limit: 5,
+      total: 0,
+      list: [],
+    };
+  },
+  async created() {
+    this.search();
+  },
+  methods: {
+    ...patentearly(['queryByOrg']),
+    async search({ skip = 0, limit = this.limit, searchName, ...info } = {}) {
+      info.searchName = searchName;
+      info.code = this.user.code;
+      let res = await this.queryByOrg({ skip, limit, ...info });
+      if (this.$checkRes(res)) {
+        this.$set(this, `list`, res.data);
+        this.$set(this, `total`, res.total);
+      }
+    },
+    // 返回
+    back() {
+      this.$router.push({ path: '/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>

+ 73 - 0
src/views/patent/mech/patent/information/detail.vue

@@ -0,0 +1,73 @@
+<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: patentinfo } = createNamespacedHelpers('patentinfo');
+export default {
+  name: 'detail',
+  props: {},
+  components: {
+    adminFrame,
+    detail1,
+  },
+  data: function () {
+    return {
+      form: {},
+    };
+  },
+  async created() {
+    if (this.id) await this.search();
+  },
+  methods: {
+    ...patentinfo(['fetch']),
+    async search() {
+      let res = await this.fetch(this.id);
+      if (this.$checkRes(res)) {
+        res.data.inventor = JSON.stringify(res.data.inventor.map((i) => i.name));
+        this.$set(this, `form`, res.data);
+      }
+    },
+    // 返回
+    back() {
+      this.$router.push({ path: '/patent/mech/patent/information' });
+    },
+  },
+  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>
+.one {
+  .one_1 {
+    text-align: center;
+    .van-button {
+      margin: 0 5px 10px 5px;
+    }
+  }
+}
+</style>

+ 116 - 0
src/views/patent/mech/patent/information/index.vue

@@ -0,0 +1,116 @@
+<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" color="#409eff">
+          <van-tab :title="`已授权【${oneTotal}】`" name="有效">
+            <list-1 :list="list" @detail="detail"></list-1>
+          </van-tab>
+          <van-tab :title="`已受理【${twoTotal}】`" name="审中">
+            <list-1 :list="list" @detail="detail"></list-1>
+          </van-tab>
+          <van-tab :title="`已失效专利【${thrTotal}】`" name="失效">
+            <list-1 :list="list" @detail="detail"></list-1>
+          </van-tab>
+        </van-tabs>
+      </template>
+    </admin-frame>
+  </div>
+</template>
+
+<script>
+import list1 from '../parts/list-1.vue';
+import adminFrame from '@frame/src/components/mobile-frame/mobile-main.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: patentinfo } = createNamespacedHelpers('patentinfo');
+export default {
+  name: 'index',
+  props: {},
+  components: {
+    adminFrame,
+    list1,
+  },
+  data: function () {
+    return {
+      active: '有效',
+      list: [],
+      limit: 10,
+      total: 0,
+      oneTotal: 0,
+      twoTotal: 0,
+      thrTotal: 0,
+    };
+  },
+  async created() {
+    await this.search({ term: '有效' });
+    await this.searchTotal();
+  },
+  methods: {
+    ...patentinfo(['queryByOrg']),
+    async search({ skip = 0, limit = this.limit, ...info } = {}) {
+      if (this.active == '有效') {
+        info.term = this.active;
+        info.code = this.user.code;
+        let res = await this.queryByOrg({ skip, limit, ...info });
+        if (this.$checkRes(res)) {
+          this.$set(this, `list`, res.data);
+          this.$set(this, `total`, res.total);
+        }
+      } else if (this.active == '审中') {
+        info.term = this.active;
+        info.code = this.user.code;
+        let res = await this.queryByOrg({ skip, limit, ...info });
+        if (this.$checkRes(res)) {
+          this.$set(this, `list`, res.data);
+          this.$set(this, `total`, res.total);
+        }
+      } else if (this.active == '失效') {
+        info.term = this.active;
+        info.code = this.user.code;
+        let res = await this.queryByOrg({ skip, limit, ...info });
+        if (this.$checkRes(res)) {
+          this.$set(this, `list`, res.data);
+          this.$set(this, `total`, res.total);
+        }
+      }
+    },
+    // 查询总数
+    async searchTotal({ skip = 0, limit = this.limit, ...info } = {}) {
+      let res = await this.queryByOrg({ skip, limit, term: '有效', code: this.user.code, ...info });
+      if (this.$checkRes(res)) this.$set(this, `oneTotal`, res.total);
+      res = await this.queryByOrg({ skip, limit, term: '审中', code: this.user.code, ...info });
+      if (this.$checkRes(res)) this.$set(this, `twoTotal`, res.total);
+      res = await this.queryByOrg({ skip, limit, term: '失效', code: this.user.code, ...info });
+      if (this.$checkRes(res)) this.$set(this, `thrTotal`, res.total);
+    },
+    // 详情
+    detail(data) {
+      this.$router.push({ path: '/patent/mech/patent/information/detail', query: { id: data.id } });
+    },
+    // 选择类型
+    change(name) {
+      this.$set(this, `active`, name);
+      this.search({ term: name });
+    },
+    // 返回
+    back() {
+      this.$router.push({ path: '/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>

+ 112 - 0
src/views/patent/mech/patent/navigation/index.vue

@@ -0,0 +1,112 @@
+<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-col span="24" class="one">
+          <van-button type="info" size="small" @click="addSearch">添加查询</van-button>
+        </van-col>
+        <van-col span="24"><list-1 :list="list" @detail="detail"></list-1></van-col>
+      </template>
+    </admin-frame>
+    <van-dialog v-model="show" title="查询条件" class="dialog" :showConfirmButton="false">
+      <search-1 :searchForm="searchForm" @reseatBtn="reseatBtn" @search="search" @></search-1>
+    </van-dialog>
+    <van-dialog v-model="twoShow" title="详细信息" class="twodialog" confirmButtonText="取消">
+      <detail-1 :form="info"></detail-1>
+    </van-dialog>
+  </div>
+</template>
+
+<script>
+import search1 from './parts/search-1.vue';
+import list1 from '../parts/list-1.vue';
+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: patentinfo } = createNamespacedHelpers('patentinfo');
+const moment = require('moment');
+export default {
+  name: 'index',
+  props: {},
+  components: {
+    adminFrame,
+    list1,
+    search1,
+    detail1,
+  },
+  data: function () {
+    return {
+      list: [],
+      limit: 5,
+      total: 0,
+      // 查询
+      show: false,
+      searchForm: {},
+      // 详细信息
+      twoShow: false,
+      info: {},
+    };
+  },
+  async created() {
+    await this.search();
+  },
+  methods: {
+    ...patentinfo(['mechQuery']),
+    async search({ skip = 0, limit = this.limit, searchForm, ...info } = {}) {
+      let res = await this.mechQuery({ skip, limit, code: this.user.code, ...searchForm, ...info });
+      if (this.$checkRes(res)) {
+        this.$set(this, `list`, res.data);
+        this.$set(this, `total`, res.total);
+        this.show = false;
+      }
+    },
+    // 返回
+    back() {
+      this.$router.push({ path: '/patent/index' });
+    },
+    // 添加
+    addSearch() {
+      this.show = true;
+    },
+    // 重置
+    reseatBtn() {
+      this.$set(this, `searchForm`, {});
+      this.show = false;
+    },
+    // 查看详情
+    detail(data) {
+      // this.$router.push({ path: '/service/patent/mech/patent/navigation/info', query: { id: data.id } });
+      this.$set(this, `info`, data);
+      this.twoShow = true;
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.one {
+  background-color: #ffffff;
+  text-align: center;
+  padding: 8px 0;
+}
+/deep/.van-dialog {
+  width: 95%;
+}
+/deep/.van-dialog__content {
+  height: 450px;
+  overflow-y: auto;
+}
+</style>

+ 64 - 0
src/views/patent/mech/patent/navigation/info.vue

@@ -0,0 +1,64 @@
+<template>
+  <div id="info_create">
+    <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: patentinfo } = createNamespacedHelpers('patentinfo');
+export default {
+  name: 'info_create',
+  props: {},
+  components: {
+    adminFrame,
+    detail1,
+  },
+  data: function () {
+    return {
+      form: {},
+    };
+  },
+  async created() {
+    if (this.id) await this.search();
+  },
+  methods: {
+    ...patentinfo(['fetch']),
+    async search() {
+      let res = await this.fetch(this.id);
+      if (this.$checkRes(res)) {
+        this.$set(this, `form`, res.data);
+      }
+    },
+
+    // 返回
+    back() {
+      this.$router.push({ path: '/patent/mech/patent/navigation' });
+    },
+  },
+  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>

+ 90 - 0
src/views/patent/mech/patent/navigation/parts/detail-1.vue

@@ -0,0 +1,90 @@
+<template>
+  <div id="detail-1">
+    <van-row>
+      <van-col span="24" class="main">
+        <van-col span="24" class="one">
+          <van-image :src="img_url"></van-image>
+        </van-col>
+        <van-col span="24" class="two">
+          <van-form>
+            <van-field v-model="form.term" name="term" label="专利有效性" />
+            <van-field v-model="form.name" name="name" label="名称" />
+            <van-field v-model="form.create_number" name="create_number" label="申请号" />
+            <van-field v-model="form.create_date" name="create_date" label="申请日" />
+            <van-field v-model="form.success_number" name="success_number" label="公开(公告)号" />
+            <van-field v-model="form.success_date" name="success_date" label="公开(公告)日" />
+            <van-field v-model="form.type" name="type" label="专利类型" />
+            <van-field v-model="form.inventor" name="inventor" label="发明人" />
+            <van-field v-model="form.address" name="address" label="发明人地址" />
+            <van-field v-model="form.apply_personal" name="apply_personal" label="申请人" />
+            <van-field v-model="form.agent_personal" name="agent_personal" label="代理人" />
+            <van-field v-model="form.agent" name="agent" label="代理机构" />
+            <van-field v-model="form.abstract" name="abstract" label="摘要" rows="1" autosize type="textarea" />
+            <van-field name="trans_status" label="是否交易">
+              <template #input>
+                <van-radio-group v-model="form.trans_status" direction="horizontal" disabled>
+                  <van-radio name="0">未交易</van-radio>
+                  <van-radio name="1">已交易</van-radio>
+                </van-radio-group>
+              </template>
+            </van-field>
+          </van-form>
+        </van-col>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'detail-1',
+  props: { form: { type: Object } },
+  components: {},
+  data: function () {
+    return {
+      img_url: '',
+    };
+  },
+  created() {},
+  methods: {
+    searchImg(data) {
+      if (data.img_url) {
+        var url = data.img_url.map((item) => item.url)[0];
+        this.$set(this, `img_url`, url);
+      } else {
+        var url = require('@/assets/fmzl.jpg');
+        this.$set(this, `img_url`, url);
+      }
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    form: {
+      deep: true,
+      immediate: true,
+      handler(val) {
+        this.searchImg(val);
+      },
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.main {
+  .one {
+    height: 220px;
+    border-bottom: 1px solid #f1f1f1;
+    .van-image {
+      width: 100%;
+      height: 219px;
+    }
+  }
+}
+</style>

+ 185 - 0
src/views/patent/mech/patent/navigation/parts/search-1.vue

@@ -0,0 +1,185 @@
+<template>
+  <div id="search-1">
+    <van-row>
+      <van-col span="24" class="main">
+        <van-col :span="24" class="one">
+          <van-form label-width="5em" @submit="searchBtn">
+            <van-field readonly clickable name="picker" :value="searchForm.empower_date" label="授权年份" placeholder="点击选择" @click="oneShow = true" />
+            <van-popup v-model="oneShow" position="bottom">
+              <van-picker show-toolbar :columns="yearList" @confirm="oneCon" @cancel="oneShow = false" />
+            </van-popup>
+            <van-field readonly clickable name="picker" :value="searchForm.create_date" label="申请年份" placeholder="点击选择" @click="twoShow = true" />
+            <van-popup v-model="twoShow" position="bottom">
+              <van-picker show-toolbar :columns="yearList" @confirm="twoCon" @cancel="twoShow = false" />
+            </van-popup>
+            <van-field v-model="searchForm.field" name="field" label="所属领域" style="display: none" />
+            <van-field readonly clickable name="picker" :value="searchForm.fieldname" label="所属领域" placeholder="点击选择" @click="thrShow = true" />
+            <van-popup v-model="thrShow" position="bottom">
+              <van-picker show-toolbar value-key="name" :columns="fieldList" @confirm="thrCon" @cancel="thrShow = false" />
+            </van-popup>
+            <van-field v-model="searchForm.create_number" name="first_inventor" label="申请号" placeholder="申请号" />
+            <van-field v-model="searchForm.first_inventor" name="first_inventor" label="第一发明人" placeholder="第一发明人" />
+            <van-field v-model="searchForm.apply_personal" name="apply_personal" label="所在学校" placeholder="所在学校" disabled />
+            <van-field v-model="searchForm.on_obligee" name="on_obligee" label="专利权人" placeholder="专利权人" />
+            <van-field name="type" label="专利类型">
+              <template #input>
+                <van-radio-group v-model="searchForm.type" direction="horizontal">
+                  <van-radio name="发明">发明</van-radio>
+                  <van-radio name="实用新型">实用新型</van-radio>
+                  <van-radio name="其他">其他</van-radio>
+                </van-radio-group>
+              </template>
+            </van-field>
+            <van-field name="is_empower" label="是否授权">
+              <template #input>
+                <van-radio-group v-model="searchForm.is_empower" direction="horizontal">
+                  <van-radio name="0">已授权</van-radio>
+                  <van-radio name="1">未授权</van-radio>
+                </van-radio-group>
+              </template>
+            </van-field>
+            <van-field name="term" label="专利状态">
+              <template #input>
+                <van-radio-group v-model="searchForm.term" direction="horizontal">
+                  <van-radio name="有效">有效</van-radio>
+                  <van-radio name="审中">审中</van-radio>
+                </van-radio-group>
+              </template>
+            </van-field>
+            <van-field name="is_lose" label="是否失效">
+              <template #input>
+                <van-radio-group v-model="searchForm.is_lose" direction="horizontal">
+                  <van-radio name="0">失效</van-radio>
+                  <van-radio name="1">未失效</van-radio>
+                </van-radio-group>
+              </template>
+            </van-field>
+            <van-field name="empower_sort" label="授权日排序">
+              <template #input>
+                <van-radio-group v-model="searchForm.empower_sort" direction="horizontal">
+                  <van-radio name="0">升序</van-radio>
+                  <van-radio name="1">降序</van-radio>
+                </van-radio-group>
+              </template>
+            </van-field>
+            <van-col span="24" class="btn">
+              <van-button type="danger" size="small" @click="reseatBtn">重置条件</van-button>
+              <van-button type="info" size="small" native-type="submit">提交查询</van-button>
+            </van-col>
+          </van-form>
+        </van-col>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'search-1',
+  props: {
+    searchForm: { type: Object },
+  },
+  components: {},
+  data: function () {
+    return {
+      // 年份列表
+      yearList: [
+        '2000',
+        '2001',
+        '2002',
+        '2003',
+        '2004',
+        '2005',
+        '2006',
+        '2007',
+        '2008',
+        '2009',
+        '2010',
+        '2011',
+        '2012',
+        '2013',
+        '2014',
+        '2015',
+        '2016',
+        '2017',
+        '2018',
+        '2019',
+        '2020',
+        '2021',
+      ],
+      // 选择授权年份
+      oneShow: false,
+      // 选择授权年份
+      twoShow: false,
+      // 选择所属领域
+      thrShow: false,
+      fieldList: [
+        { num: 'A', name: '人类生活必需' },
+        { num: 'B', name: '作业;运输' },
+        { num: 'C', name: '化学;冶金' },
+        { num: 'D', name: '纺织;造纸' },
+        { num: 'E', name: '固定建筑物' },
+        { num: 'F', name: '机械工程;照明;加热;武器;爆破' },
+        { num: 'G', name: '物理' },
+        { num: 'H', name: '电学' },
+      ],
+    };
+  },
+  created() {},
+  methods: {
+    // 选择授权年份
+    oneCon(value) {
+      this.$set(this.searchForm, `empower_date`, value);
+      this.oneShow = false;
+    },
+    // 选择申请年份
+    twoCon(value) {
+      this.$set(this.searchForm, `create_date`, value);
+      this.twoShow = false;
+    },
+    // 选择所属领域
+    thrCon(value) {
+      this.$set(this.searchForm, `field`, value.num);
+      this.$set(this.searchForm, `fieldname`, value.name);
+      this.thrShow = false;
+    },
+    // 重置条件
+    reseatBtn() {
+      this.$emit('reseatBtn');
+    },
+    // 提交查询
+    searchBtn() {
+      this.$emit('search', this.searchForm);
+    },
+  },
+  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 {
+    text-align: center;
+    .btn {
+      text-align: center;
+      margin: 8px 0;
+      .van-button {
+        margin: 0 8px;
+      }
+    }
+  }
+}
+</style>

+ 84 - 0
src/views/patent/mech/patent/parts/detail-1.vue

@@ -0,0 +1,84 @@
+<template>
+  <div id="detail-1">
+    <van-row>
+      <van-col span="24" class="main">
+        <van-col span="24" class="one">
+          <van-image :src="img_url"></van-image>
+        </van-col>
+        <van-col span="24" class="two">
+          <van-form>
+            <van-field v-model="form.term" name="term" label="专利有效性" />
+            <van-field v-model="form.name" name="name" label="名称" />
+            <van-field v-model="form.create_number" name="create_number" label="申请号" />
+            <van-field v-model="form.create_date" name="create_date" label="申请日" />
+            <van-field v-model="form.success_number" name="success_number" label="公开(公告)号" />
+            <van-field v-model="form.success_date" name="success_date" label="公开(公告)日" />
+            <van-field v-model="form.type" name="type" label="专利类型" />
+            <van-field v-model="form.inventor" name="inventor" label="发明人" />
+            <van-field v-model="form.address" name="address" label="发明人地址" />
+            <van-field v-model="form.apply_personal" name="apply_personal" label="申请人" />
+            <van-field v-model="form.agent_personal" name="agent_personal" label="代理人" />
+            <van-field v-model="form.agent" name="agent" label="代理机构" />
+            <van-field v-model="form.abstract" name="abstract" label="摘要" rows="1" autosize type="textarea" />
+          </van-form>
+        </van-col>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'detail-1',
+  props: {
+    form: { type: Object },
+  },
+  components: {},
+  data: function () {
+    return {
+      img_url: '',
+    };
+  },
+  created() {},
+  methods: {
+    searchImg(data) {
+      if (data && data.length > 0) {
+        var url = data.map((item) => item.url)[0];
+        this.$set(this, `img_url`, url);
+      } else {
+        var url = require('@/assets/fmzl.jpg');
+        this.$set(this, `img_url`, url);
+      }
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    form: {
+      deep: true,
+      immediate: true,
+      handler(val) {
+        this.searchImg(val.img_url);
+      },
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.main {
+  .one {
+    height: 220px;
+    border-bottom: 1px solid #f1f1f1;
+    .van-image {
+      width: 100%;
+      height: 219px;
+    }
+  }
+}
+</style>

+ 94 - 0
src/views/patent/mech/patent/parts/list-1.vue

@@ -0,0 +1,94 @@
+<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">
+          <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>{{ getDate(item.success_date) }}</span>
+            </van-col>
+          </van-col>
+          <van-col span="24" class="btn">
+            <van-button type="info" size="small" @click="detail(item)">查看信息</van-button>
+          </van-col>
+        </van-col>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+const moment = require('moment');
+export default {
+  name: 'list-1',
+  props: { list: { type: Array } },
+  components: {},
+  data: function () {
+    return {};
+  },
+  created() {},
+  methods: {
+    detail(data) {
+      this.$emit('detail', data);
+    },
+    // 过滤时间
+    getDate(val) {
+      let newDate = moment(val).format('YYYY-MM-DD');
+      if (newDate) return newDate;
+    },
+  },
+  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;
+        }
+      }
+    }
+    .btn {
+      text-align: center;
+      .van-button {
+        margin: 0 10px;
+      }
+    }
+  }
+}
+</style>

+ 83 - 0
src/views/patent/mech/patent/parts/list-4.vue

@@ -0,0 +1,83 @@
+<template>
+  <div id="list-4">
+    <van-col span="24" class="main">
+      <van-col span="24" class="list" v-for="(item, index) in list" :key="index">
+        <van-col span="24" class="other">
+          <van-col span="24" class="otherInfo">
+            <span>{{ item.name || '暂无' }}</span>
+          </van-col>
+          <van-col span="24" class="otherInfo">
+            专利失效日期:<span>{{ item.lose_date || '暂无' }}</span>
+          </van-col>
+          <van-col span="24" class="otherInfo">
+            预警信息:<span>{{ item.content }}</span>
+          </van-col>
+        </van-col>
+      </van-col>
+    </van-col>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'list-4',
+  props: {
+    list: { type: Array },
+  },
+  components: {},
+  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>
+.main {
+  padding: 8px 0 0 0;
+  .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;
+          line-height: 20px;
+        }
+      }
+    }
+    .btn {
+      text-align: center;
+      .van-button {
+        margin: 0 5px;
+      }
+    }
+  }
+}
+</style>

+ 72 - 0
src/views/patent/mech/transaction/index.vue

@@ -0,0 +1,72 @@
+<template>
+  <div id="index">
+    <admin-frame @search="search" :limit="limit" :total="total" topType="2" @back="back" :rightArrow="false" :useNav="false">
+      <template v-slot:info>
+        <list-1 :list="list" @detail="detail"></list-1>
+      </template>
+    </admin-frame>
+  </div>
+</template>
+
+<script>
+import list1 from './parts/list-1.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: 'index',
+  props: {},
+  components: {
+    adminFrame,
+    list1,
+  },
+  data: function () {
+    return {
+      list: [],
+      limit: 5,
+      total: 0,
+    };
+  },
+  async created() {
+    await this.search();
+  },
+  methods: {
+    ...patenttrans(['query']),
+    async search({ skip = 0, limit = this.limit, ...info } = {}) {
+      if (this.type) info.type = this.type;
+      info.admin_id = this.user.id;
+      let res = await this.query({ skip, limit, ...info });
+      if (this.$checkRes(res)) {
+        this.$set(this, `list`, res.data);
+        this.$set(this, `total`, res.total);
+      }
+    },
+    // 查看详情
+    detail(data) {
+      this.$router.push({ path: '/patent/mech/transaction/info', query: { id: data.id, type: this.type } });
+    },
+    // 返回
+    back() {
+      this.$router.push({ path: '/patent/index' });
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    type() {
+      return this.$route.query.type;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 66 - 0
src/views/patent/mech/transaction/info.vue

@@ -0,0 +1,66 @@
+<template>
+  <div id="detail">
+    <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/info-1.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: 'detail',
+  props: {},
+  components: {
+    adminFrame,
+    info1,
+  },
+  data: function () {
+    return {
+      form: {},
+    };
+  },
+  async created() {
+    await this.search();
+  },
+  methods: {
+    ...patenttrans(['fetch', 'update']),
+    async search() {
+      let res = await this.fetch(this.id);
+      if (this.$checkRes(res)) {
+        this.$set(this, `form`, res.data);
+      }
+    },
+    // 返回
+    back() {
+      this.$router.push({ path: '/patent/mech/transaction/index', query: { type: this.type } });
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    id() {
+      return this.$route.query.id;
+    },
+    type() {
+      return this.$route.query.type;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 76 - 0
src/views/patent/mech/transaction/parts/info-1.vue

@@ -0,0 +1,76 @@
+<template>
+  <div id="info-1">
+    <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: 'info-1',
+  props: {
+    form: { type: Object },
+  },
+  components: {},
+  data: function () {
+    return {};
+  },
+  created() {},
+  methods: {
+    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>

+ 98 - 0
src/views/patent/mech/transaction/parts/list-1.vue

@@ -0,0 +1,98 @@
+<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 span="24" class="otherInfo">
+              状态:<span>{{ getStu(item.status) }}</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);
+    },
+    // 整理状态
+    getStu(data) {
+      if (data == '0') return '待交易';
+      else if (data == '1') return '填写完合同,等待机构审核';
+      else if (data == '-1') return '填写合同审核失败,重填';
+      else if (data == '2') return '合同审核通过,待用户确认';
+      else if (data == '3') return '用户确认成功,机构归档';
+      else if (data == '-3') return '归档失败';
+      else if (data == '4') return '归档成功';
+    },
+  },
+  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>