guhongwei 4 years ago
parent
commit
7cb5493f18
100 changed files with 6002 additions and 1624 deletions
  1. 2 0
      .env
  2. 33 0
      .eslintrc.js
  3. 0 2
      .gitignore
  4. 27 1
      README.md
  5. 0 1
      mobile-official.git/HEAD
  6. 0 8
      mobile-official.git/config
  7. 0 1
      mobile-official.git/description
  8. 0 15
      mobile-official.git/hooks/applypatch-msg.sample
  9. 0 24
      mobile-official.git/hooks/commit-msg.sample
  10. 0 114
      mobile-official.git/hooks/fsmonitor-watchman.sample
  11. 0 8
      mobile-official.git/hooks/post-update.sample
  12. 0 14
      mobile-official.git/hooks/pre-applypatch.sample
  13. 0 49
      mobile-official.git/hooks/pre-commit.sample
  14. 0 53
      mobile-official.git/hooks/pre-push.sample
  15. 0 169
      mobile-official.git/hooks/pre-rebase.sample
  16. 0 24
      mobile-official.git/hooks/pre-receive.sample
  17. 0 42
      mobile-official.git/hooks/prepare-commit-msg.sample
  18. 0 128
      mobile-official.git/hooks/update.sample
  19. 0 6
      mobile-official.git/info/exclude
  20. BIN
      mobile-official.git/objects/pack/pack-8f4ef10b6ccdc103d7dc03d8b89582dd09c96f2e.idx
  21. BIN
      mobile-official.git/objects/pack/pack-8f4ef10b6ccdc103d7dc03d8b89582dd09c96f2e.pack
  22. 0 2
      mobile-official.git/packed-refs
  23. 1148 748
      package-lock.json
  24. 18 13
      package.json
  25. 7 22
      src/App.vue
  26. BIN
      src/assets/achieve.png
  27. BIN
      src/assets/bendi1.png
  28. BIN
      src/assets/bendi2.png
  29. BIN
      src/assets/bendi3.png
  30. BIN
      src/assets/bendi4.png
  31. BIN
      src/assets/bendi5.png
  32. BIN
      src/assets/bendi6.png
  33. BIN
      src/assets/export.png
  34. BIN
      src/assets/huodong.png
  35. BIN
      src/assets/question.png
  36. BIN
      src/assets/test.jpg
  37. BIN
      src/assets/test1.jpg
  38. BIN
      src/assets/找专家.png
  39. 0 130
      src/components/HelloWorld.vue
  40. 226 0
      src/components/parts/chat.vue
  41. 85 0
      src/components/upload.vue
  42. 203 0
      src/layout/adminuser/release.vue
  43. 49 0
      src/layout/common/footInfo.vue
  44. 46 0
      src/layout/common/topInfo.vue
  45. 76 0
      src/layout/common/upload.vue
  46. 87 0
      src/layout/dock/applyForm.vue
  47. 131 0
      src/layout/duijiehui/detail.vue
  48. 111 0
      src/layout/duijiehui/examineinfo.vue
  49. 219 0
      src/layout/market/exportDetails.vue
  50. 135 0
      src/layout/market/prodDetail.vue
  51. 193 0
      src/layout/market/release.vue
  52. 105 0
      src/layout/matter/detailinfo.vue
  53. 135 0
      src/layout/myProduct/prodDetails.vue
  54. 189 0
      src/layout/myProduct/release.vue
  55. 92 0
      src/layout/transaction/detaliinfo.vue
  56. 185 0
      src/layout/user/person.vue
  57. 21 7
      src/main.js
  58. 19 0
      src/plugins/axios.js
  59. 42 0
      src/plugins/check-res.js
  60. 5 0
      src/plugins/element.js
  61. 6 0
      src/plugins/filters.js
  62. 27 0
      src/plugins/loading.js
  63. 4 0
      src/plugins/meta.js
  64. 33 0
      src/plugins/methods.js
  65. 20 0
      src/plugins/setting.js
  66. 65 0
      src/plugins/stomp.js
  67. 5 0
      src/plugins/vant.js
  68. 25 0
      src/plugins/var.js
  69. 243 15
      src/router/index.js
  70. 39 0
      src/store/chat.js
  71. 19 0
      src/store/common/mutations.js
  72. 1 0
      src/store/common/state.js
  73. 47 5
      src/store/index.js
  74. 23 0
      src/store/onlive/gensign.js
  75. 50 0
      src/store/onlive/room.js
  76. 39 0
      src/store/onlive/user.js
  77. 43 0
      src/store/place.js
  78. 39 0
      src/store/user.js
  79. 49 0
      src/store/user/auth-user.js
  80. 34 0
      src/store/user/wxchattest.js
  81. 117 0
      src/util/axios-wrapper.js
  82. 10 0
      src/util/filters.js
  83. 30 0
      src/util/menus.js
  84. 50 0
      src/util/methods-util.js
  85. 47 0
      src/util/optionTitles.js
  86. 96 0
      src/util/qrcode.vue
  87. 69 0
      src/util/user-util.js
  88. 0 5
      src/views/About.vue
  89. 0 18
      src/views/Home.vue
  90. 92 0
      src/views/adminCenter/duijiehui/apply.vue
  91. 132 0
      src/views/adminCenter/duijiehui/detail.vue
  92. 129 0
      src/views/adminCenter/duijiehui/examine.vue
  93. 92 0
      src/views/adminCenter/duijiehui/index.vue
  94. 162 0
      src/views/adminCenter/duijiehui/parts/applyList.vue
  95. 151 0
      src/views/adminCenter/duijiehui/parts/list.vue
  96. 92 0
      src/views/adminCenter/enterpriseProduct/index.vue
  97. 136 0
      src/views/adminCenter/enterpriseProduct/parts/list.vue
  98. 105 0
      src/views/adminCenter/transaction/detail.vue
  99. 92 0
      src/views/adminCenter/transaction/index.vue
  100. 0 0
      src/views/adminCenter/transaction/parts/list.vue

+ 2 - 0
.env

@@ -0,0 +1,2 @@
+VUE_APP_AXIOS_BASE_URL = ''
+VUE_APP_ROUTER="/platmobile"

+ 33 - 0
.eslintrc.js

@@ -0,0 +1,33 @@
+// https://eslint.org/docs/user-guide/configuring
+
+module.exports = {
+  root: true,
+  env: {
+    node: true,
+  },
+  extends: ['plugin:vue/essential', '@vue/prettier'],
+  plugins: ['vue'],
+  rules: {
+    'max-len': [
+      'warn',
+      {
+        code: 250,
+      },
+    ],
+    'no-unused-vars': 'off',
+    'no-console': 'off',
+    'prettier/prettier': [
+      'warn',
+      {
+        singleQuote: true,
+        trailingComma: 'es5',
+        bracketSpacing: true,
+        jsxBracketSameLine: true,
+        printWidth: 160,
+      },
+    ],
+  },
+  parserOptions: {
+    parser: 'babel-eslint',
+  },
+};

+ 0 - 2
.gitignore

@@ -1,6 +1,5 @@
 .DS_Store
 node_modules
-/dist
 
 # local env files
 .env.local
@@ -10,7 +9,6 @@ node_modules
 npm-debug.log*
 yarn-debug.log*
 yarn-error.log*
-pnpm-debug.log*
 
 # Editor directories and files
 .idea

+ 27 - 1
README.md

@@ -1,4 +1,4 @@
-# live-mobile
+# mobile-official
 
 ## Project setup
 ```
@@ -22,3 +22,29 @@ npm run lint
 
 ### Customize configuration
 See [Configuration Reference](https://cli.vuejs.org/config/).
+
+
+
+测试用户接口
+超级管理员
+http://free.liaoningdoupo.com/api/auth/wxchattest?redirect_uri=http://localhost:8002/live/index&type=0&openid=o3ORKt8yN1OHAJWrX1ApOf2vWM5U
+
+测试合作机构管理员
+http://free.liaoningdoupo.com/api/auth/wxchattest?redirect_uri=http://localhost:8002/live/index&type=0&openid=o3ORKt5e0Xkt14t4UfJyiKNfWdFI
+
+测试合作机构业务管理员
+http://free.liaoningdoupo.com/api/auth/wxchattest?redirect_uri=http://localhost:8002/live/index&type=0&openid=o3ORKt0piAr7qAJ_yvO-QywHtPgc
+
+临时
+http://free.liaoningdoupo.com/api/auth/wxchattest?redirect_uri=http://localhost:8002/live/index&type=0&openid=o3ORKtyLBFA09hrQM3F2mYAkexfo
+
+个人
+http://free.liaoningdoupo.com/api/auth/wxchattest?redirect_uri=http://localhost:8002/live/index&type=0&openid=o3ORKt-mgL0w8r3ZqNRTH01Kfbko
+
+企业
+http://free.liaoningdoupo.com/api/auth/wxchattest?redirect_uri=http://localhost:8002/live/index&type=0&openid=o3ORKt5VIqOJ_8F3eE69qYMu7I2o
+
+专家
+http://free.liaoningdoupo.com/api/auth/wxchattest?redirect_uri=http://localhost:8002/live/index&type=0&openid=o3ORKt0F_bQkB6hWqN7xzNz-OdqI
+
+

+ 0 - 1
mobile-official.git/HEAD

@@ -1 +0,0 @@
-ref: refs/heads/master

+ 0 - 8
mobile-official.git/config

@@ -1,8 +0,0 @@
-[core]
-	repositoryformatversion = 0
-	filemode = false
-	bare = true
-	symlinks = false
-	ignorecase = true
-[remote "origin"]
-	url = http://git.cc-lotus.info/service-platform/mobile-official.git

+ 0 - 1
mobile-official.git/description

@@ -1 +0,0 @@
-Unnamed repository; edit this file 'description' to name the repository.

+ 0 - 15
mobile-official.git/hooks/applypatch-msg.sample

@@ -1,15 +0,0 @@
-#!/bin/sh
-#
-# An example hook script to check the commit log message taken by
-# applypatch from an e-mail message.
-#
-# The hook should exit with non-zero status after issuing an
-# appropriate message if it wants to stop the commit.  The hook is
-# allowed to edit the commit message file.
-#
-# To enable this hook, rename this file to "applypatch-msg".
-
-. git-sh-setup
-commitmsg="$(git rev-parse --git-path hooks/commit-msg)"
-test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"}
-:

+ 0 - 24
mobile-official.git/hooks/commit-msg.sample

@@ -1,24 +0,0 @@
-#!/bin/sh
-#
-# An example hook script to check the commit log message.
-# Called by "git commit" with one argument, the name of the file
-# that has the commit message.  The hook should exit with non-zero
-# status after issuing an appropriate message if it wants to stop the
-# commit.  The hook is allowed to edit the commit message file.
-#
-# To enable this hook, rename this file to "commit-msg".
-
-# Uncomment the below to add a Signed-off-by line to the message.
-# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
-# hook is more suited to it.
-#
-# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
-# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
-
-# This example catches duplicate Signed-off-by lines.
-
-test "" = "$(grep '^Signed-off-by: ' "$1" |
-	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
-	echo >&2 Duplicate Signed-off-by lines.
-	exit 1
-}

+ 0 - 114
mobile-official.git/hooks/fsmonitor-watchman.sample

@@ -1,114 +0,0 @@
-#!/usr/bin/perl
-
-use strict;
-use warnings;
-use IPC::Open2;
-
-# An example hook script to integrate Watchman
-# (https://facebook.github.io/watchman/) with git to speed up detecting
-# new and modified files.
-#
-# The hook is passed a version (currently 1) and a time in nanoseconds
-# formatted as a string and outputs to stdout all files that have been
-# modified since the given time. Paths must be relative to the root of
-# the working tree and separated by a single NUL.
-#
-# To enable this hook, rename this file to "query-watchman" and set
-# 'git config core.fsmonitor .git/hooks/query-watchman'
-#
-my ($version, $time) = @ARGV;
-
-# Check the hook interface version
-
-if ($version == 1) {
-	# convert nanoseconds to seconds
-	$time = int $time / 1000000000;
-} else {
-	die "Unsupported query-fsmonitor hook version '$version'.\n" .
-	    "Falling back to scanning...\n";
-}
-
-my $git_work_tree;
-if ($^O =~ 'msys' || $^O =~ 'cygwin') {
-	$git_work_tree = Win32::GetCwd();
-	$git_work_tree =~ tr/\\/\//;
-} else {
-	require Cwd;
-	$git_work_tree = Cwd::cwd();
-}
-
-my $retry = 1;
-
-launch_watchman();
-
-sub launch_watchman {
-
-	my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty')
-	    or die "open2() failed: $!\n" .
-	    "Falling back to scanning...\n";
-
-	# In the query expression below we're asking for names of files that
-	# changed since $time but were not transient (ie created after
-	# $time but no longer exist).
-	#
-	# To accomplish this, we're using the "since" generator to use the
-	# recency index to select candidate nodes and "fields" to limit the
-	# output to file names only. Then we're using the "expression" term to
-	# further constrain the results.
-	#
-	# The category of transient files that we want to ignore will have a
-	# creation clock (cclock) newer than $time_t value and will also not
-	# currently exist.
-
-	my $query = <<"	END";
-		["query", "$git_work_tree", {
-			"since": $time,
-			"fields": ["name"],
-			"expression": ["not", ["allof", ["since", $time, "cclock"], ["not", "exists"]]]
-		}]
-	END
-
-	print CHLD_IN $query;
-	close CHLD_IN;
-	my $response = do {local $/; <CHLD_OUT>};
-
-	die "Watchman: command returned no output.\n" .
-	    "Falling back to scanning...\n" if $response eq "";
-	die "Watchman: command returned invalid output: $response\n" .
-	    "Falling back to scanning...\n" unless $response =~ /^\{/;
-
-	my $json_pkg;
-	eval {
-		require JSON::XS;
-		$json_pkg = "JSON::XS";
-		1;
-	} or do {
-		require JSON::PP;
-		$json_pkg = "JSON::PP";
-	};
-
-	my $o = $json_pkg->new->utf8->decode($response);
-
-	if ($retry > 0 and $o->{error} and $o->{error} =~ m/unable to resolve root .* directory (.*) is not watched/) {
-		print STDERR "Adding '$git_work_tree' to watchman's watch list.\n";
-		$retry--;
-		qx/watchman watch "$git_work_tree"/;
-		die "Failed to make watchman watch '$git_work_tree'.\n" .
-		    "Falling back to scanning...\n" if $? != 0;
-
-		# Watchman will always return all files on the first query so
-		# return the fast "everything is dirty" flag to git and do the
-		# Watchman query just to get it over with now so we won't pay
-		# the cost in git to look up each individual file.
-		print "/\0";
-		eval { launch_watchman() };
-		exit 0;
-	}
-
-	die "Watchman: $o->{error}.\n" .
-	    "Falling back to scanning...\n" if $o->{error};
-
-	binmode STDOUT, ":utf8";
-	local $, = "\0";
-	print @{$o->{files}};
-}

+ 0 - 8
mobile-official.git/hooks/post-update.sample

@@ -1,8 +0,0 @@
-#!/bin/sh
-#
-# An example hook script to prepare a packed repository for use over
-# dumb transports.
-#
-# To enable this hook, rename this file to "post-update".
-
-exec git update-server-info

+ 0 - 14
mobile-official.git/hooks/pre-applypatch.sample

@@ -1,14 +0,0 @@
-#!/bin/sh
-#
-# An example hook script to verify what is about to be committed
-# by applypatch from an e-mail message.
-#
-# The hook should exit with non-zero status after issuing an
-# appropriate message if it wants to stop the commit.
-#
-# To enable this hook, rename this file to "pre-applypatch".
-
-. git-sh-setup
-precommit="$(git rev-parse --git-path hooks/pre-commit)"
-test -x "$precommit" && exec "$precommit" ${1+"$@"}
-:

+ 0 - 49
mobile-official.git/hooks/pre-commit.sample

@@ -1,49 +0,0 @@
-#!/bin/sh
-#
-# An example hook script to verify what is about to be committed.
-# Called by "git commit" with no arguments.  The hook should
-# exit with non-zero status after issuing an appropriate message if
-# it wants to stop the commit.
-#
-# To enable this hook, rename this file to "pre-commit".
-
-if git rev-parse --verify HEAD >/dev/null 2>&1
-then
-	against=HEAD
-else
-	# Initial commit: diff against an empty tree object
-	against=$(git hash-object -t tree /dev/null)
-fi
-
-# If you want to allow non-ASCII filenames set this variable to true.
-allownonascii=$(git config --bool hooks.allownonascii)
-
-# Redirect output to stderr.
-exec 1>&2
-
-# Cross platform projects tend to avoid non-ASCII filenames; prevent
-# them from being added to the repository. We exploit the fact that the
-# printable range starts at the space character and ends with tilde.
-if [ "$allownonascii" != "true" ] &&
-	# Note that the use of brackets around a tr range is ok here, (it's
-	# even required, for portability to Solaris 10's /usr/bin/tr), since
-	# the square bracket bytes happen to fall in the designated range.
-	test $(git diff --cached --name-only --diff-filter=A -z $against |
-	  LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
-then
-	cat <<\EOF
-Error: Attempt to add a non-ASCII file name.
-
-This can cause problems if you want to work with people on other platforms.
-
-To be portable it is advisable to rename the file.
-
-If you know what you are doing you can disable this check using:
-
-  git config hooks.allownonascii true
-EOF
-	exit 1
-fi
-
-# If there are whitespace errors, print the offending file names and fail.
-exec git diff-index --check --cached $against --

+ 0 - 53
mobile-official.git/hooks/pre-push.sample

@@ -1,53 +0,0 @@
-#!/bin/sh
-
-# An example hook script to verify what is about to be pushed.  Called by "git
-# push" after it has checked the remote status, but before anything has been
-# pushed.  If this script exits with a non-zero status nothing will be pushed.
-#
-# This hook is called with the following parameters:
-#
-# $1 -- Name of the remote to which the push is being done
-# $2 -- URL to which the push is being done
-#
-# If pushing without using a named remote those arguments will be equal.
-#
-# Information about the commits which are being pushed is supplied as lines to
-# the standard input in the form:
-#
-#   <local ref> <local sha1> <remote ref> <remote sha1>
-#
-# This sample shows how to prevent push of commits where the log message starts
-# with "WIP" (work in progress).
-
-remote="$1"
-url="$2"
-
-z40=0000000000000000000000000000000000000000
-
-while read local_ref local_sha remote_ref remote_sha
-do
-	if [ "$local_sha" = $z40 ]
-	then
-		# Handle delete
-		:
-	else
-		if [ "$remote_sha" = $z40 ]
-		then
-			# New branch, examine all commits
-			range="$local_sha"
-		else
-			# Update to existing branch, examine new commits
-			range="$remote_sha..$local_sha"
-		fi
-
-		# Check for WIP commit
-		commit=`git rev-list -n 1 --grep '^WIP' "$range"`
-		if [ -n "$commit" ]
-		then
-			echo >&2 "Found WIP commit in $local_ref, not pushing"
-			exit 1
-		fi
-	fi
-done
-
-exit 0

+ 0 - 169
mobile-official.git/hooks/pre-rebase.sample

@@ -1,169 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2006, 2008 Junio C Hamano
-#
-# The "pre-rebase" hook is run just before "git rebase" starts doing
-# its job, and can prevent the command from running by exiting with
-# non-zero status.
-#
-# The hook is called with the following parameters:
-#
-# $1 -- the upstream the series was forked from.
-# $2 -- the branch being rebased (or empty when rebasing the current branch).
-#
-# This sample shows how to prevent topic branches that are already
-# merged to 'next' branch from getting rebased, because allowing it
-# would result in rebasing already published history.
-
-publish=next
-basebranch="$1"
-if test "$#" = 2
-then
-	topic="refs/heads/$2"
-else
-	topic=`git symbolic-ref HEAD` ||
-	exit 0 ;# we do not interrupt rebasing detached HEAD
-fi
-
-case "$topic" in
-refs/heads/??/*)
-	;;
-*)
-	exit 0 ;# we do not interrupt others.
-	;;
-esac
-
-# Now we are dealing with a topic branch being rebased
-# on top of master.  Is it OK to rebase it?
-
-# Does the topic really exist?
-git show-ref -q "$topic" || {
-	echo >&2 "No such branch $topic"
-	exit 1
-}
-
-# Is topic fully merged to master?
-not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
-if test -z "$not_in_master"
-then
-	echo >&2 "$topic is fully merged to master; better remove it."
-	exit 1 ;# we could allow it, but there is no point.
-fi
-
-# Is topic ever merged to next?  If so you should not be rebasing it.
-only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
-only_next_2=`git rev-list ^master           ${publish} | sort`
-if test "$only_next_1" = "$only_next_2"
-then
-	not_in_topic=`git rev-list "^$topic" master`
-	if test -z "$not_in_topic"
-	then
-		echo >&2 "$topic is already up to date with master"
-		exit 1 ;# we could allow it, but there is no point.
-	else
-		exit 0
-	fi
-else
-	not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
-	/usr/bin/perl -e '
-		my $topic = $ARGV[0];
-		my $msg = "* $topic has commits already merged to public branch:\n";
-		my (%not_in_next) = map {
-			/^([0-9a-f]+) /;
-			($1 => 1);
-		} split(/\n/, $ARGV[1]);
-		for my $elem (map {
-				/^([0-9a-f]+) (.*)$/;
-				[$1 => $2];
-			} split(/\n/, $ARGV[2])) {
-			if (!exists $not_in_next{$elem->[0]}) {
-				if ($msg) {
-					print STDERR $msg;
-					undef $msg;
-				}
-				print STDERR " $elem->[1]\n";
-			}
-		}
-	' "$topic" "$not_in_next" "$not_in_master"
-	exit 1
-fi
-
-<<\DOC_END
-
-This sample hook safeguards topic branches that have been
-published from being rewound.
-
-The workflow assumed here is:
-
- * Once a topic branch forks from "master", "master" is never
-   merged into it again (either directly or indirectly).
-
- * Once a topic branch is fully cooked and merged into "master",
-   it is deleted.  If you need to build on top of it to correct
-   earlier mistakes, a new topic branch is created by forking at
-   the tip of the "master".  This is not strictly necessary, but
-   it makes it easier to keep your history simple.
-
- * Whenever you need to test or publish your changes to topic
-   branches, merge them into "next" branch.
-
-The script, being an example, hardcodes the publish branch name
-to be "next", but it is trivial to make it configurable via
-$GIT_DIR/config mechanism.
-
-With this workflow, you would want to know:
-
-(1) ... if a topic branch has ever been merged to "next".  Young
-    topic branches can have stupid mistakes you would rather
-    clean up before publishing, and things that have not been
-    merged into other branches can be easily rebased without
-    affecting other people.  But once it is published, you would
-    not want to rewind it.
-
-(2) ... if a topic branch has been fully merged to "master".
-    Then you can delete it.  More importantly, you should not
-    build on top of it -- other people may already want to
-    change things related to the topic as patches against your
-    "master", so if you need further changes, it is better to
-    fork the topic (perhaps with the same name) afresh from the
-    tip of "master".
-
-Let's look at this example:
-
-		   o---o---o---o---o---o---o---o---o---o "next"
-		  /       /           /           /
-		 /   a---a---b A     /           /
-		/   /               /           /
-	       /   /   c---c---c---c B         /
-	      /   /   /             \         /
-	     /   /   /   b---b C     \       /
-	    /   /   /   /             \     /
-    ---o---o---o---o---o---o---o---o---o---o---o "master"
-
-
-A, B and C are topic branches.
-
- * A has one fix since it was merged up to "next".
-
- * B has finished.  It has been fully merged up to "master" and "next",
-   and is ready to be deleted.
-
- * C has not merged to "next" at all.
-
-We would want to allow C to be rebased, refuse A, and encourage
-B to be deleted.
-
-To compute (1):
-
-	git rev-list ^master ^topic next
-	git rev-list ^master        next
-
-	if these match, topic has not merged in next at all.
-
-To compute (2):
-
-	git rev-list master..topic
-
-	if this is empty, it is fully merged to "master".
-
-DOC_END

+ 0 - 24
mobile-official.git/hooks/pre-receive.sample

@@ -1,24 +0,0 @@
-#!/bin/sh
-#
-# An example hook script to make use of push options.
-# The example simply echoes all push options that start with 'echoback='
-# and rejects all pushes when the "reject" push option is used.
-#
-# To enable this hook, rename this file to "pre-receive".
-
-if test -n "$GIT_PUSH_OPTION_COUNT"
-then
-	i=0
-	while test "$i" -lt "$GIT_PUSH_OPTION_COUNT"
-	do
-		eval "value=\$GIT_PUSH_OPTION_$i"
-		case "$value" in
-		echoback=*)
-			echo "echo from the pre-receive-hook: ${value#*=}" >&2
-			;;
-		reject)
-			exit 1
-		esac
-		i=$((i + 1))
-	done
-fi

+ 0 - 42
mobile-official.git/hooks/prepare-commit-msg.sample

@@ -1,42 +0,0 @@
-#!/bin/sh
-#
-# An example hook script to prepare the commit log message.
-# Called by "git commit" with the name of the file that has the
-# commit message, followed by the description of the commit
-# message's source.  The hook's purpose is to edit the commit
-# message file.  If the hook fails with a non-zero status,
-# the commit is aborted.
-#
-# To enable this hook, rename this file to "prepare-commit-msg".
-
-# This hook includes three examples. The first one removes the
-# "# Please enter the commit message..." help message.
-#
-# The second includes the output of "git diff --name-status -r"
-# into the message, just before the "git status" output.  It is
-# commented because it doesn't cope with --amend or with squashed
-# commits.
-#
-# The third example adds a Signed-off-by line to the message, that can
-# still be edited.  This is rarely a good idea.
-
-COMMIT_MSG_FILE=$1
-COMMIT_SOURCE=$2
-SHA1=$3
-
-/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE"
-
-# case "$COMMIT_SOURCE,$SHA1" in
-#  ,|template,)
-#    /usr/bin/perl -i.bak -pe '
-#       print "\n" . `git diff --cached --name-status -r`
-# 	 if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;;
-#  *) ;;
-# esac
-
-# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
-# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE"
-# if test -z "$COMMIT_SOURCE"
-# then
-#   /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE"
-# fi

+ 0 - 128
mobile-official.git/hooks/update.sample

@@ -1,128 +0,0 @@
-#!/bin/sh
-#
-# An example hook script to block unannotated tags from entering.
-# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
-#
-# To enable this hook, rename this file to "update".
-#
-# Config
-# ------
-# hooks.allowunannotated
-#   This boolean sets whether unannotated tags will be allowed into the
-#   repository.  By default they won't be.
-# hooks.allowdeletetag
-#   This boolean sets whether deleting tags will be allowed in the
-#   repository.  By default they won't be.
-# hooks.allowmodifytag
-#   This boolean sets whether a tag may be modified after creation. By default
-#   it won't be.
-# hooks.allowdeletebranch
-#   This boolean sets whether deleting branches will be allowed in the
-#   repository.  By default they won't be.
-# hooks.denycreatebranch
-#   This boolean sets whether remotely creating branches will be denied
-#   in the repository.  By default this is allowed.
-#
-
-# --- Command line
-refname="$1"
-oldrev="$2"
-newrev="$3"
-
-# --- Safety check
-if [ -z "$GIT_DIR" ]; then
-	echo "Don't run this script from the command line." >&2
-	echo " (if you want, you could supply GIT_DIR then run" >&2
-	echo "  $0 <ref> <oldrev> <newrev>)" >&2
-	exit 1
-fi
-
-if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
-	echo "usage: $0 <ref> <oldrev> <newrev>" >&2
-	exit 1
-fi
-
-# --- Config
-allowunannotated=$(git config --bool hooks.allowunannotated)
-allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
-denycreatebranch=$(git config --bool hooks.denycreatebranch)
-allowdeletetag=$(git config --bool hooks.allowdeletetag)
-allowmodifytag=$(git config --bool hooks.allowmodifytag)
-
-# check for no description
-projectdesc=$(sed -e '1q' "$GIT_DIR/description")
-case "$projectdesc" in
-"Unnamed repository"* | "")
-	echo "*** Project description file hasn't been set" >&2
-	exit 1
-	;;
-esac
-
-# --- Check types
-# if $newrev is 0000...0000, it's a commit to delete a ref.
-zero="0000000000000000000000000000000000000000"
-if [ "$newrev" = "$zero" ]; then
-	newrev_type=delete
-else
-	newrev_type=$(git cat-file -t $newrev)
-fi
-
-case "$refname","$newrev_type" in
-	refs/tags/*,commit)
-		# un-annotated tag
-		short_refname=${refname##refs/tags/}
-		if [ "$allowunannotated" != "true" ]; then
-			echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
-			echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
-			exit 1
-		fi
-		;;
-	refs/tags/*,delete)
-		# delete tag
-		if [ "$allowdeletetag" != "true" ]; then
-			echo "*** Deleting a tag is not allowed in this repository" >&2
-			exit 1
-		fi
-		;;
-	refs/tags/*,tag)
-		# annotated tag
-		if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
-		then
-			echo "*** Tag '$refname' already exists." >&2
-			echo "*** Modifying a tag is not allowed in this repository." >&2
-			exit 1
-		fi
-		;;
-	refs/heads/*,commit)
-		# branch
-		if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
-			echo "*** Creating a branch is not allowed in this repository" >&2
-			exit 1
-		fi
-		;;
-	refs/heads/*,delete)
-		# delete branch
-		if [ "$allowdeletebranch" != "true" ]; then
-			echo "*** Deleting a branch is not allowed in this repository" >&2
-			exit 1
-		fi
-		;;
-	refs/remotes/*,commit)
-		# tracking branch
-		;;
-	refs/remotes/*,delete)
-		# delete tracking branch
-		if [ "$allowdeletebranch" != "true" ]; then
-			echo "*** Deleting a tracking branch is not allowed in this repository" >&2
-			exit 1
-		fi
-		;;
-	*)
-		# Anything else (is there anything else?)
-		echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
-		exit 1
-		;;
-esac
-
-# --- Finished
-exit 0

+ 0 - 6
mobile-official.git/info/exclude

@@ -1,6 +0,0 @@
-# git ls-files --others --exclude-from=.git/info/exclude
-# Lines that start with '#' are comments.
-# For a project mostly in C, the following would be a good set of
-# exclude patterns (uncomment them if you want to use them):
-# *.[oa]
-# *~

BIN
mobile-official.git/objects/pack/pack-8f4ef10b6ccdc103d7dc03d8b89582dd09c96f2e.idx


BIN
mobile-official.git/objects/pack/pack-8f4ef10b6ccdc103d7dc03d8b89582dd09c96f2e.pack


+ 0 - 2
mobile-official.git/packed-refs

@@ -1,2 +0,0 @@
-# pack-refs with: peeled fully-peeled sorted 
-a9d72b6ab3e1319b3d16a0a13a1e655216763719 refs/heads/master

File diff suppressed because it is too large
+ 1148 - 748
package-lock.json


+ 18 - 13
package.json

@@ -1,5 +1,5 @@
 {
-  "name": "live-mobile",
+  "name": "mobile-official",
   "version": "0.1.0",
   "private": true,
   "scripts": {
@@ -8,29 +8,34 @@
     "lint": "vue-cli-service lint"
   },
   "dependencies": {
+    "@stomp/stompjs": "^5.4.4",
     "axios": "^0.19.2",
-    "core-js": "^3.6.5",
+    "core-js": "^3.6.4",
     "element-ui": "^2.13.2",
-    "loadsh": "0.0.4",
+    "jsonwebtoken": "^8.5.1",
+    "lodash": "^4.17.15",
+    "moment": "^2.26.0",
     "naf-core": "^0.1.2",
+    "trtc-js-sdk": "^4.4.0",
     "vant": "^2.8.5",
     "vue": "^2.6.11",
-    "vue-meta": "^2.4.0",
-    "vue-router": "^3.2.0",
-    "vuex": "^3.4.0"
+    "vue-meta": "^2.3.4",
+    "vue-router": "^3.3.2",
+    "vue-video-player": "^5.0.2",
+    "vuex": "^3.1.3"
   },
   "devDependencies": {
-    "@vue/cli-plugin-babel": "~4.4.0",
-    "@vue/cli-plugin-eslint": "~4.4.0",
-    "@vue/cli-plugin-router": "~4.4.0",
-    "@vue/cli-plugin-vuex": "~4.4.0",
-    "@vue/cli-service": "~4.4.0",
+    "@vue/cli-plugin-babel": "~4.3.0",
+    "@vue/cli-plugin-eslint": "~4.3.0",
+    "@vue/cli-plugin-router": "~4.3.0",
+    "@vue/cli-plugin-vuex": "~4.3.0",
+    "@vue/cli-service": "~4.3.0",
     "@vue/eslint-config-prettier": "^6.0.0",
     "babel-eslint": "^10.1.0",
     "eslint": "^6.7.2",
-    "eslint-plugin-prettier": "^3.1.3",
+    "eslint-plugin-prettier": "^3.1.1",
     "eslint-plugin-vue": "^6.2.2",
-    "less": "^3.0.4",
+    "less": "^3.11.2",
     "less-loader": "^5.0.0",
     "prettier": "^1.19.1",
     "vue-template-compiler": "^2.6.11"

+ 7 - 22
src/App.vue

@@ -1,32 +1,17 @@
 <template>
   <div id="app">
-    <div id="nav">
-      <router-link to="/">Home</router-link> |
-      <router-link to="/about">About</router-link>
-    </div>
     <router-view />
   </div>
 </template>
 
 <style lang="less">
-#app {
-  font-family: Avenir, Helvetica, Arial, sans-serif;
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
-  text-align: center;
-  color: #2c3e50;
+p {
+  padding: 0;
+  margin: 0;
 }
-
-#nav {
-  padding: 30px;
-
-  a {
-    font-weight: bold;
-    color: #2c3e50;
-
-    &.router-link-exact-active {
-      color: #42b983;
-    }
-  }
+.textOver {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
 }
 </style>

BIN
src/assets/achieve.png


BIN
src/assets/bendi1.png


BIN
src/assets/bendi2.png


BIN
src/assets/bendi3.png


BIN
src/assets/bendi4.png


BIN
src/assets/bendi5.png


BIN
src/assets/bendi6.png


BIN
src/assets/export.png


BIN
src/assets/huodong.png


BIN
src/assets/question.png


BIN
src/assets/test.jpg


BIN
src/assets/test1.jpg


BIN
src/assets/找专家.png


+ 0 - 130
src/components/HelloWorld.vue

@@ -1,130 +0,0 @@
-<template>
-  <div class="hello">
-    <h1>{{ msg }}</h1>
-    <p>
-      For a guide and recipes on how to configure / customize this project,<br />
-      check out the
-      <a href="https://cli.vuejs.org" target="_blank" rel="noopener"
-        >vue-cli documentation</a
-      >.
-    </p>
-    <h3>Installed CLI Plugins</h3>
-    <ul>
-      <li>
-        <a
-          href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel"
-          target="_blank"
-          rel="noopener"
-          >babel</a
-        >
-      </li>
-      <li>
-        <a
-          href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router"
-          target="_blank"
-          rel="noopener"
-          >router</a
-        >
-      </li>
-      <li>
-        <a
-          href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex"
-          target="_blank"
-          rel="noopener"
-          >vuex</a
-        >
-      </li>
-      <li>
-        <a
-          href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint"
-          target="_blank"
-          rel="noopener"
-          >eslint</a
-        >
-      </li>
-    </ul>
-    <h3>Essential Links</h3>
-    <ul>
-      <li>
-        <a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a>
-      </li>
-      <li>
-        <a href="https://forum.vuejs.org" target="_blank" rel="noopener"
-          >Forum</a
-        >
-      </li>
-      <li>
-        <a href="https://chat.vuejs.org" target="_blank" rel="noopener"
-          >Community Chat</a
-        >
-      </li>
-      <li>
-        <a href="https://twitter.com/vuejs" target="_blank" rel="noopener"
-          >Twitter</a
-        >
-      </li>
-      <li>
-        <a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a>
-      </li>
-    </ul>
-    <h3>Ecosystem</h3>
-    <ul>
-      <li>
-        <a href="https://router.vuejs.org" target="_blank" rel="noopener"
-          >vue-router</a
-        >
-      </li>
-      <li>
-        <a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a>
-      </li>
-      <li>
-        <a
-          href="https://github.com/vuejs/vue-devtools#vue-devtools"
-          target="_blank"
-          rel="noopener"
-          >vue-devtools</a
-        >
-      </li>
-      <li>
-        <a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener"
-          >vue-loader</a
-        >
-      </li>
-      <li>
-        <a
-          href="https://github.com/vuejs/awesome-vue"
-          target="_blank"
-          rel="noopener"
-          >awesome-vue</a
-        >
-      </li>
-    </ul>
-  </div>
-</template>
-
-<script>
-export default {
-  name: "HelloWorld",
-  props: {
-    msg: String
-  }
-};
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped lang="less">
-h3 {
-  margin: 40px 0 0;
-}
-ul {
-  list-style-type: none;
-  padding: 0;
-}
-li {
-  display: inline-block;
-  margin: 0 10px;
-}
-a {
-  color: #42b983;
-}
-</style>

+ 226 - 0
src/components/parts/chat.vue

@@ -0,0 +1,226 @@
+<template>
+  <div id="chat">
+    <el-row class="chat">
+      <div class="chatList">
+        <ul id="chatSell">
+          <li v-for="(i, index) in list" :key="index">
+            <p>
+              <span>[{{ i.send_time | getTime }}]</span><span style="font-weight: bold;">{{ i.sender_name }}:</span>
+              <span> {{ i.content }}</span>
+            </p>
+          </li>
+        </ul>
+        <el-row type="flex" :gutter="10" style="padding-top:10px;">
+          <el-col :span="19">
+            <el-input v-model="text" size="mini"></el-input>
+          </el-col>
+          <el-col :span="5">
+            <el-button @click="send" size="mini" round style="background: #2c69fe;color: #fff;">发送</el-button>
+          </el-col>
+        </el-row>
+      </div>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: chat } = createNamespacedHelpers('chat');
+var moment = require('moment');
+export default {
+  name: 'chat',
+  props: {},
+  components: {},
+  data: () => {
+    return {
+      list: [],
+      text: '',
+    };
+  },
+  created() {
+    //回车事件
+    // this.enterListen();
+    this.search();
+  },
+  mounted() {
+    this.channel();
+  },
+  methods: {
+    ...chat(['query', 'create']),
+    async search() {
+      const res = await this.query({ skip: 0, limit: 10 });
+      if (this.$checkRes(res)) this.$set(this, `list`, _.reverse(res.data));
+    },
+    async send() {
+      if (!this.user.uid) {
+        this.$message.error('游客不能发言,请先注册');
+        return;
+      }
+      if (this.text != '') {
+        let object = { sender_name: this.user.name, content: this.text };
+        if (this.user.uid) object.sender_id = this.user.uid;
+        //TODO接口
+        let res = await this.create(object);
+        this.$checkRes(res, null, res.errmsg || '发言失败');
+      } else this.$message.error('请输入信息后发送');
+    },
+    channel() {
+      console.log('in function:');
+      this.$stomp({
+        [`/exchange/public_chat`]: this.onMessage,
+      });
+    },
+    onMessage(message) {
+      // console.log('receive a message: ', message.body);
+      let body = _.get(message, 'body');
+      if (body) {
+        body = JSON.parse(body);
+        this.list.push(body);
+        this.text = '';
+        this.$nextTick(() => {
+          document.getElementById('chatSell').scrollTop = document.getElementById('chatSell').scrollHeight + 275;
+        });
+      }
+      // const { content, contenttype, sendid, sendname, icon, groupid, sendtime, type } = message.headers;
+      // let object = { content, contenttype, sendid, sendname, icon, groupid, sendtime, type };
+      // this.list.push(object);
+    },
+    enterListen() {
+      var lett = this;
+      document.onkeydown = function(e) {
+        var key = window.event.keyCode;
+        if (key == 13) {
+          lett.send();
+        }
+      };
+    },
+  },
+  filters: {
+    getTime(date) {
+      if (!date) return '很久以前';
+      let today = moment().format('YYYY-MM-DD');
+      let dd = moment(date).format('YYYY-MM-DD');
+      let time;
+      if (today == dd) time = moment(date).format('HH:mm:ss');
+      else time = moment(date).format('YYYY-MM-DD HH:mm:ss');
+      return time;
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.chat {
+  float: left;
+  width: 100%;
+  height: 340px;
+  border-radius: 5px;
+  box-shadow: 0 0 5px #2c69fe;
+  padding: 0 10px 0px 10px;
+  margin: 4px 0px 0 3px;
+}
+
+.chat .luyanTop {
+  height: 30px;
+  line-height: 30px;
+}
+
+.chat .luyanTop span:first-child {
+  display: inline-block;
+  padding: 0 10px;
+  height: 30px;
+  color: #fff;
+  background-color: #ff8500;
+  border-bottom-left-radius: 10px;
+  border-bottom-right-radius: 10px;
+}
+
+.chat .luyanTop .icon {
+  float: right;
+  background: #f2f4f5;
+  border-radius: 20px;
+  color: #666;
+  padding: 0 5px;
+  margin: 0 0 0 5px;
+}
+
+.chat .luyanTop .icon {
+  cursor: pointer;
+}
+
+.chat .chatList {
+  background: #fff;
+  float: left;
+  width: 100%;
+  height: 340px;
+  overflow: hidden;
+}
+
+.chat .chatList ul {
+  float: left;
+  width: 100%;
+  height: 275px;
+  padding: 5px 0 0 0;
+  overflow: auto;
+  margin: 10px 0 0 0;
+}
+
+.chat .chatList ul li {
+  padding: 0 10px;
+  margin: 0 0 5px 0;
+}
+
+.chat .chatList ul li span:first-child {
+  color: #666;
+  padding: 0 5px 0 0;
+}
+
+.chat .chatList .input {
+  height: 40px;
+  line-height: 40px;
+  float: left;
+  width: 100%;
+}
+
+.chat .chatList .input input[data-v-5189f7b7] {
+  border: 1px solid #ccc;
+  float: left;
+  height: 33px;
+  width: 75%;
+  margin: 19px 3% 0 0;
+}
+.chat .chatList .input button {
+  float: left;
+  background: #ff8500;
+  color: #fff;
+  height: 34px;
+  width: 21%;
+  max-width: 109px;
+  border-radius: 5px;
+}
+.jiabinlist ul {
+  margin: 0;
+  padding: 0;
+}
+
+.anniu {
+  float: left;
+  background: #ff8500;
+  color: #fff;
+  height: 34px;
+  width: 21%;
+  max-width: 109px;
+  margin: 20px 0 0 0;
+  border-radius: 5px;
+}
+</style>

+ 85 - 0
src/components/upload.vue

@@ -0,0 +1,85 @@
+<template>
+  <div id="upload">
+    <el-upload
+      v-if="url"
+      ref="upload"
+      :action="url"
+      :limit="limit"
+      :on-exceed="outLimit"
+      :on-preview="handlePictureCardPreview"
+      :before-remove="handleRemove"
+      :on-success="onSuccess"
+      :show-file-list="false"
+    >
+      <el-avatar :size="80" fit="fill" :src="`${fileUrl}?${new Date().getTime()}`"></el-avatar>
+    </el-upload>
+    <el-dialog :visible.sync="dialogVisible">
+      <img width="100%" :src="dialogImageUrl" alt="" />
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'upload',
+  props: {
+    url: { type: null },
+    limit: { type: Number },
+    data: { type: null },
+    type: { type: String },
+  },
+  components: {},
+  data: () => ({
+    dialogVisible: false,
+    dialogImageUrl: '',
+    fileList: [],
+    fileUrl: '',
+  }),
+  created() {
+    if (this.data) {
+      this.defalutProcess(this.data);
+    }
+  },
+  watch: {
+    data: {
+      handler(val) {
+        this.defalutProcess(val);
+      },
+    },
+  },
+  computed: {},
+  methods: {
+    handlePictureCardPreview(file) {
+      this.dialogImageUrl = file.url;
+      this.dialogVisible = true;
+    },
+    handleRemove(file) {
+      return true;
+    },
+    outLimit() {
+      this.$message.error('只允许上传1张头像');
+    },
+    onSuccess(response, file, fileList) {
+      this.fileUrl = response.uri;
+      //将文件整理好传回父组件
+      this.$emit('upload', { type: this.type, data: response });
+    },
+    defalutProcess(val) {
+      this.fileUrl = this.data;
+      this.$set(this, `fileList`, [{ name: this.type, url: this.data }]);
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-upload-list__item {
+  width: 5rem;
+  height: 5rem;
+}
+/deep/.el-upload.el-upload--picture-card {
+  width: 5rem;
+  height: 5rem;
+  line-height: 5rem;
+}
+</style>

+ 203 - 0
src/layout/adminuser/release.vue

@@ -0,0 +1,203 @@
+<template>
+  <div id="person">
+    <el-col :span="24" class="info">
+      <van-form @submit="onSubmit">
+        <van-field name="radio" label="用户状态" v-if="this.id">
+          <template #input>
+            <van-radio-group v-model="form.status" direction="horizontal">
+              <van-radio name="0">已注册</van-radio>
+              <van-radio name="1">审核成功</van-radio>
+              <van-radio name="2">拒绝</van-radio>
+            </van-radio-group>
+          </template>
+        </van-field>
+
+        <van-field v-model="form.name" name="用户名称" label="用户名称" placeholder="请输入用户名称" :rules="[{ required: true, message: '请输入用户名称' }]" />
+
+        <van-field v-model="form.phone" name="手机号" label="手机号" placeholder="请输入手机号" v-if="this.id" disabled />
+        <van-field v-model="form.phone" name="手机号" label="手机号" placeholder="请输入手机号" v-else />
+        <van-field v-model="form.password" type="password" name="登录密码" label="登录密码" placeholder="请输入登录密码" />
+
+        <van-field
+          v-model="form.cardnumber"
+          name="身份证号"
+          label="身份证号"
+          placeholder="请输入身份证号"
+          :rules="[{ required: true, message: '请输入身份证号' }]"
+        />
+        <van-field v-model="form.email" name="邮箱" label="邮箱" placeholder="请输入邮箱" :rules="[{ required: true, message: '请输入邮箱' }]" />
+        <van-field v-model="form.addr" name="地址" label="地址" placeholder="请输入地址" :rules="[{ required: true, message: '请输入地址' }]" />
+        <van-field name="uploader" label="头像">
+          <!-- <template #input><upload :limit="1" :data="form.img_path" type="img_path" :url="'/files/imgpath/upload'" @upload="uploadSuccess"></upload> </template> -->
+          <template #input><upload :limit="1" :data="form.img_path" type="img_path" :url="'/files/imgpath/upload'" @upload="uploadSuccess"></upload> </template>
+        </van-field>
+        <van-field name="radio" label="用户类型">
+          <template #input>
+            <van-radio-group v-model="form.role" direction="horizontal">
+              <van-radio name="2">个人</van-radio>
+              <van-radio name="3">企业</van-radio>
+              <van-radio name="6">专家</van-radio>
+            </van-radio-group>
+          </template>
+        </van-field>
+        <van-field name="uploader" label="身份证正面" v-if="form.role == '2' || form.role == '3'">
+          <template #input
+            ><upload
+              :limit="1"
+              v-if="form.role == '2' || form.role == '3'"
+              :data="form.cardfile_a"
+              type="cardfile_a"
+              :url="'/files/cardfilea/upload'"
+              @upload="uploadSuccess"
+            ></upload>
+          </template>
+        </van-field>
+        <van-field name="uploader" label="身份证背面" v-if="form.role == '2' || form.role == '3'">
+          <template #input
+            ><upload
+              :limit="1"
+              v-if="form.role == '2' || form.role == '3'"
+              :data="form.cardfile_b"
+              type="cardfile_b"
+              :url="'/files/cardfileb/upload'"
+              @upload="uploadSuccess"
+            ></upload>
+          </template>
+        </van-field>
+        <van-field name="uploader" label="组织机构图片" v-if="form.role == '3'">
+          <template #input
+            ><upload
+              :limit="1"
+              v-if="form.role == '2' || form.role == '3'"
+              :data="form.img_qy"
+              type="img_qy"
+              :url="'/files/img_qy/upload'"
+              @upload="uploadSuccess"
+            ></upload>
+          </template>
+        </van-field>
+        <template v-if="form.role == '3'">
+          <van-field v-model="form.institution_type" name="机构类型" label="机构类型" placeholder="请输入机构类型" />
+          <van-field v-model="form.institution_name" name="机构名称" label="机构名称" placeholder="请输入机构名称" />
+          <van-field v-model="form.institution_code" name="机构代码" label="机构代码" placeholder="请输入机构代码" />
+          <van-field v-model="form.institution_nature" name="机构性质" label="机构性质" placeholder="请输入机构性质" />
+        </template>
+        <van-field v-model="form.office_phone" v-if="form.role == '2' || form.role == '3'" name="办公电话" label="办公电话" placeholder="请输入办公电话" />
+        <van-field v-model="form.profession" v-if="form.role == '2' || form.role == '3'" name="所属行业" label="所属行业" placeholder="请输入所属行业" />
+        <van-field name="radio" label="性别" v-if="form.role == '6'">
+          <template #input>
+            <van-radio-group v-model="form.gender" direction="horizontal">
+              <van-radio name="男">男</van-radio>
+              <van-radio name="女">女</van-radio>
+            </van-radio-group>
+          </template>
+        </van-field>
+        <van-cell title="日期" is-link :value="form.birthday" @click="birthdayPopup" v-if="form.role == '6'" />
+        <van-popup v-model="birthdayShow" position="bottom">
+          <van-datetime-picker type="date" @cancel="birthdayShow = false" @confirm="birthdayPicker" />
+        </van-popup>
+        <van-field v-model="form.level" v-if="form.role == '6'" name="职称级别" label="职称级别" placeholder="请输入职称级别" />
+        <van-field v-model="form.levelname" v-if="form.role == '6'" name="职称" label="职称" placeholder="请输入职称" />
+        <van-field v-model="form.position" v-if="form.role == '6'" name="职务" label="职务" placeholder="请输入职务" />
+        <van-field v-model="form.school" v-if="form.role == '6'" name="院校" label="院校" placeholder="院校" />
+        <van-field readonly clickable name="picker" :value="form.xl" label="学历" v-if="form.role == '6'" placeholder="请选择学历" @click="xlPicker = true" />
+        <van-popup v-model="xlPicker" position="bottom">
+          <van-picker show-toolbar :columns="xlList" @confirm="onConfirm" @cancel="xlPicker = false" />
+        </van-popup>
+        <van-field readonly clickable name="picker" :value="form.xw" label="学位" v-if="form.role == '6'" placeholder="请选择学位" @click="xwPicker = true" />
+        <van-popup v-model="xwPicker" position="bottom">
+          <van-picker show-toolbar :columns="xwList" @confirm="onConfirms" @cancel="xwPicker = false" />
+        </van-popup>
+        <van-field v-model="form.major" v-if="form.role == '6'" name="专业" label="专业" placeholder="请输入专业" />
+        <van-field v-model="form.professional" v-if="form.role == '6'" name="从事专业" label="从事专业 " placeholder="请输入从事专业" />
+        <van-field
+          v-model="form.resume"
+          autosize
+          label="个人简历"
+          v-if="form.role == '2' || form.role == '6'"
+          type="textarea"
+          placeholder="请输入个人简历"
+          show-word-limit
+        />
+        <van-field v-model="form.project" v-if="form.role == '6'" name="项目" label="项目 " placeholder="请输入项目" />
+        <van-field v-model="form.academic" v-if="form.role == '6'" name="学术成就" label="学术成就 " placeholder="请输入学术成就" />
+        <van-field v-model="form.paper" v-if="form.role == '6'" name="论文" label="论文 " placeholder="请输入论文" />
+        <van-field v-model="form.remark" autosize label="备注" v-if="form.role == '6'" type="textarea" placeholder="请输入备注" show-word-limit />
+        <div style="margin: 16px;">
+          <van-button round block type="info" native-type="submit">
+            保存
+          </van-button>
+        </div>
+      </van-form>
+    </el-col>
+  </div>
+</template>
+
+<script>
+import upload from '@/components/upload.vue';
+export default {
+  name: 'person',
+  props: {
+    form: null,
+  },
+  components: {
+    upload,
+  },
+  data: () => ({
+    // 出生日期
+    birthday: '',
+    birthdayShow: false,
+    // 学历
+    xlPicker: false,
+    xlList: ['中专及以上', '大专及以上', '本科及以上', '研究生及以上'],
+    // 学位
+    xwPicker: false,
+    xwList: ['学士', '硕士', '博士', '其他'],
+  }),
+  created() {},
+  computed: {
+    id() {
+      return this.$route.query.id;
+    },
+  },
+  methods: {
+    // 出生日期
+    birthdayPopup() {
+      this.birthdayShow = true;
+    },
+    // 确认选择之后的时间
+    birthdayPicker(val) {
+      let year = val.getFullYear();
+      let month = val.getMonth() + 1;
+      let day = val.getDate();
+      let birthday = `${year}-${month}-${day}`;
+      this.$set(this.form, `birthday`, birthday);
+      this.birthdayShow = false;
+    },
+    // 学历
+    onConfirm(xl) {
+      this.$set(this.form, `xl`, xl);
+      this.xlPicker = false;
+    },
+    // 学位
+    onConfirms(xw) {
+      this.$set(this.form, `xw`, xw);
+      this.xwPicker = false;
+    },
+    onSubmit() {
+      this.$emit('onSubmit', { data: this.form });
+    },
+    // 图片上传
+    uploadSuccess({ type, data }) {
+      console.log(type, data);
+      this.$set(this.form, `${type}`, data.uri);
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.info {
+  margin: 0 0 50px 0;
+}
+</style>

+ 49 - 0
src/layout/common/footInfo.vue

@@ -0,0 +1,49 @@
+<template>
+  <div id="footInfo">
+    <el-row>
+      <el-col :span="24" class="footInfo">
+        <van-tabbar route>
+          <van-tabbar-item to="/live/index">
+            <!-- <van-image width="60" height="60" :src="index" /> -->
+            <p class="text">直播大厅</p>
+          </van-tabbar-item>
+          <van-tabbar-item to="/market/index">
+            <!-- <van-image width="60" height="60" :src="question" /> -->
+            <p class="text">科技超市</p>
+          </van-tabbar-item>
+          <van-tabbar-item to="/service/index">
+            <!-- <van-image width="60" height="60" :src="question" /> -->
+            <p class="text">创新服务</p>
+          </van-tabbar-item>
+          <van-tabbar-item to="/user/index">
+            <!-- <van-image width="60" height="60" :src="user" /> -->
+            <p class="text">个人中心</p>
+          </van-tabbar-item>
+        </van-tabbar>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'footInfo',
+  props: {},
+  components: {},
+  data: () => ({}),
+  created() {},
+  computed: {},
+  methods: {},
+};
+</script>
+
+<style lang="less" scoped>
+p {
+  padding: 0;
+  margin: 0;
+}
+.footInfo {
+  height: 50px;
+  overflow: hidden;
+}
+</style>

+ 46 - 0
src/layout/common/topInfo.vue

@@ -0,0 +1,46 @@
+<template>
+  <div id="topInfo">
+    <el-row>
+      <el-col :span="24" class="topInfos">
+        <van-nav-bar :title="title" :left-arrow="isleftarrow" @click-left="onClickLeft" fixed />
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'topInfo',
+  props: {
+    title: null,
+    isleftarrow: null,
+  },
+  components: {},
+  data: () => ({}),
+  created() {},
+  computed: {},
+  methods: {
+    onClickLeft() {
+      // 点击回退的时候当做地址回退
+      this.$router.go(-1);
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+// .topInfos {
+// }
+/deep/.van-nav-bar {
+  background: #2c69fe;
+}
+/deep/.van-nav-bar__title {
+  color: #fff;
+}
+/deep/.van-nav-bar__text {
+  color: #fff;
+}
+/deep/.van-nav-bar .van-icon {
+  color: #fff;
+}
+</style>

+ 76 - 0
src/layout/common/upload.vue

@@ -0,0 +1,76 @@
+<template>
+  <div id="upload">
+    <el-upload
+      v-if="url"
+      ref="upload"
+      :action="url"
+      list-type="picture-card"
+      :file-list="fileList"
+      :limit="limit"
+      :on-exceed="outLimit"
+      :on-preview="handlePictureCardPreview"
+      :before-remove="handleRemove"
+      :on-success="onSuccess"
+      accept=".jpg,.jpeg,.png,.bmp,.gif,.svg"
+    >
+      <template>
+        <i class="el-icon-plus"></i>
+      </template>
+    </el-upload>
+    <el-dialog :visible.sync="dialogVisible">
+      <img width="100%" :src="dialogImageUrl" alt="" />
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'upload',
+  props: {
+    url: { type: null },
+    limit: { type: Number },
+    data: { type: null },
+    type: { type: String },
+  },
+  components: {},
+  data: () => ({
+    dialogVisible: false,
+    dialogImageUrl: '',
+    fileList: [],
+  }),
+  created() {
+    if (this.data) {
+      this.defalutProcess(this.data);
+    }
+  },
+  watch: {
+    data: {
+      handler(val) {
+        this.defalutProcess(val);
+      },
+    },
+  },
+  computed: {},
+  methods: {
+    handlePictureCardPreview(file) {
+      this.dialogImageUrl = file.url;
+      this.dialogVisible = true;
+    },
+    handleRemove(file) {
+      return true;
+    },
+    outLimit() {
+      this.$message.error('只允许上传1张图片');
+    },
+    onSuccess(response, file, fileList) {
+      //将文件整理好传回父组件
+      this.$emit('upload', { type: this.type, data: response });
+    },
+    defalutProcess(val) {
+      this.$set(this, `fileList`, [{ name: this.type, url: `${this.data}?${new Date().getTime()}` }]);
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 87 - 0
src/layout/dock/applyForm.vue

@@ -0,0 +1,87 @@
+<template>
+  <div id="applyForm">
+    <el-row>
+      <el-col :span="24" class="style">
+        <el-form ref="form" :model="form" :rules="rules" label-width="100px">
+          <el-form-item label="申请人身份" prop="buyer">
+            <el-radio-group v-model="form.buyer">
+              <el-radio label="0">买家</el-radio>
+              <el-radio label="1">卖家</el-radio>
+            </el-radio-group>
+          </el-form-item>
+          <span v-if="form.buyer == '1'">
+            <el-form-item label="选择产品" prop="goodsList">
+              <el-select v-model="form.goodsList" placeholder="请选择选择产品">
+                <el-option v-for="(item, index) in list" :key="index" :label="item.name" :value="item.id"> </el-option>
+              </el-select>
+            </el-form-item>
+          </span>
+          <el-form-item label="联系人" prop="contact">
+            <el-input v-model="form.contact" placeholder="请输入联系人"></el-input>
+          </el-form-item>
+          <el-form-item label="联系电话" prop="contact_tel">
+            <el-input v-model="form.contact_tel" placeholder="请输入联系电话"></el-input>
+          </el-form-item>
+          <el-form-item label="电子邮箱" prop="email">
+            <el-input v-model="form.email" placeholder="请输入电子邮箱"></el-input>
+          </el-form-item>
+          <el-form-item label="单位名称" prop="company">
+            <el-input v-model="form.company" placeholder="请输入单位名称"></el-input>
+          </el-form-item>
+          <el-row style="text-align:center">
+            <el-button type="primary" @click="onSubmit('form')">立即申请</el-button>
+            <el-button @click="restBtn('form')">取消</el-button>
+          </el-row>
+        </el-form>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'applyForm',
+  props: {
+    form: null,
+    list: null,
+  },
+  components: {},
+  data: function() {
+    return {
+      rules: {
+        buyer: [{ required: true, message: '请选择申请身份', trigger: 'blur' }],
+        goodsList: [{ required: false, message: '请选择产品', trigger: 'blur' }],
+        contact: [{ required: true, message: '请输入联系人', trigger: 'blur' }],
+        contact_tel: [{ required: true, message: '请输入联系电话', trigger: 'blur' }],
+        email: [{ required: false, message: '请输入电子邮箱', trigger: 'blur' }],
+        company: [{ required: false, message: '请输入单位名称', trigger: 'blur' }],
+      },
+    };
+  },
+  created() {},
+  methods: {
+    onSubmit() {
+      this.$emit('onSubmit', { data: this.form });
+    },
+    restBtn() {
+      this.$emit('restBtn');
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.style {
+  padding: 0 10px;
+}
+</style>

+ 131 - 0
src/layout/duijiehui/detail.vue

@@ -0,0 +1,131 @@
+<template>
+  <div id="person">
+    <el-col :span="24" class="info">
+      <van-form @submit="onSubmit">
+        <van-field
+          v-model="form.title"
+          name="对接会标题"
+          label="对接会标题"
+          placeholder="请输入对接会标题"
+          :rules="[{ required: true, message: '请输入对接会标题' }]"
+        />
+
+        <van-cell title="开始时间" is-link :value="form.start_time" @click="birthdayPopup" />
+        <van-popup v-model="birthdayShow" position="bottom">
+          <van-datetime-picker type="date" @cancel="birthdayShow = false" @confirm="birthdayPicker" />
+        </van-popup>
+
+        <van-cell title="截止时间" is-link :value="form.join_end" @click="birthdayPopups" />
+        <van-popup v-model="newShow" position="bottom">
+          <van-datetime-picker type="date" @cancel="newShow = false" @confirm="birthdayPickers" />
+        </van-popup>
+      </van-form>
+
+      <el-form ref="form" :model="form" label-width="58px">
+        <el-form-item label="省份">
+          <el-select v-model="form.province" placeholder="请选择省份" @change="changeshenge">
+            <el-option v-for="item in option" :key="item.code" :label="item.name" :value="item.code"> </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="市">
+          <el-select v-model="form.place" placeholder="请选择市">
+            <el-option v-for="item in options" :key="item.code" :label="item.name" :value="item.code"> </el-option>
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="简介">
+          <el-input type="textarea" v-model="form.desc"></el-input>
+        </el-form-item>
+
+        <el-form-item label="对接会视频">
+          <upload :limit="1" :data="form.file_path" type="file_path" listType="" :url="'/files/imgpath/upload'" @upload="uploadSuccess"></upload>
+        </el-form-item>
+      </el-form>
+      <div style="margin: 16px;">
+        <van-button round block type="info" native-type="submit" @click="onSubmit">
+          保存
+        </van-button>
+      </div>
+    </el-col>
+  </div>
+</template>
+
+<script>
+import upload from '@/components/upload.vue';
+export default {
+  name: 'person',
+  props: {
+    form: null,
+    option: null,
+    options: null,
+  },
+  components: {
+    upload,
+  },
+  data: () => ({
+    // 出生日期
+    birthday: '',
+    birthdayShow: false,
+    newShow: false,
+    // 学历
+    xlPicker: false,
+    xlList: ['中专及以上', '大专及以上', '本科及以上', '研究生及以上'],
+    // 学位
+    xwPicker: false,
+    xwList: ['学士', '硕士', '博士', '其他'],
+  }),
+  created() {},
+  computed: {
+    id() {
+      return this.$route.query.id;
+    },
+  },
+  methods: {
+    // 出生日期
+    birthdayPopup() {
+      this.birthdayShow = true;
+    },
+
+    birthdayPopups() {
+      this.newShow = true;
+    },
+    // 确认选择之后的时间
+    birthdayPicker(val) {
+      let year = val.getFullYear();
+      let month = val.getMonth() + 1;
+      let day = val.getDate();
+      let birthday = `${year}-${month}-${day}`;
+      this.$set(this.form, `start_time`, birthday);
+      this.birthdayShow = false;
+    },
+    birthdayPickers(val) {
+      let year = val.getFullYear();
+      let month = val.getMonth() + 1;
+      let day = val.getDate();
+      let birthday = `${year}-${month}-${day}`;
+      this.$set(this.form, `join_end`, birthday);
+      this.newShow = false;
+    },
+
+    changeshenge(value) {
+      this.$emit('placesubmit', { value });
+    },
+    onSubmit() {
+      console.log(this.form);
+
+      this.$emit('onSubmit', { data: this.form });
+    },
+    // 图片上传
+    uploadSuccess({ type, data }) {
+      console.log(type, data);
+      this.$set(this.form, `${type}`, data.uri);
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.info {
+  margin: 0 0 50px 0;
+}
+</style>

+ 111 - 0
src/layout/duijiehui/examineinfo.vue

@@ -0,0 +1,111 @@
+<template>
+  <div id="person">
+    <el-col :span="24" class="info">
+      <van-form @submit="onSubmit">
+        <van-field
+          v-model="form.title"
+          name="对接会标题"
+          label="对接会标题"
+          placeholder="请输入对接会标题"
+          :rules="[{ required: true, message: '请输入对接会标题' }]"
+          disabled
+        />
+
+        <van-field
+          v-model="form.start_time"
+          name="开始时间"
+          label="开始时间"
+          placeholder="请输入开始时间"
+          :rules="[{ required: true, message: '请输入开始时间' }]"
+          disabled
+        />
+
+        <van-field
+          v-model="form.join_end"
+          name="截止时间"
+          label="截止时间"
+          placeholder="请输入截止时间"
+          :rules="[{ required: true, message: '请输入截止时间' }]"
+          disabled
+        />
+      </van-form>
+
+      <el-form ref="form" :model="form" label-width="58px">
+        <el-form-item label="省份">
+          <el-select v-model="form.province" placeholder="请选择省份" @change="changeshenge">
+            <el-option v-for="item in option" :key="item.code" :label="item.name" :value="item.code" disabled> </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="市">
+          <el-select v-model="form.place" placeholder="请选择市">
+            <el-option v-for="item in options" :key="item.code" :label="item.name" :value="item.code" disabled> </el-option>
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="简介">
+          <el-input type="textarea" v-model="form.desc" disabled></el-input>
+        </el-form-item>
+
+        <el-form-item label="对接会视频">
+          <upload :limit="1" :data="form.file_path" type="file_path" listType="" :url="'/files/imgpath/upload'" @upload="uploadSuccess" disabled></upload>
+        </el-form-item>
+
+        <el-form-item label="状态" :disabled="true">
+          <el-radio v-model="form.status" label="1">开始</el-radio>
+          <el-radio v-model="form.status" label="2">结束</el-radio>
+        </el-form-item>
+      </el-form>
+
+      <div style="margin: 16px;">
+        <van-button round block type="info" native-type="submit" @click="onSubmit">
+          保存
+        </van-button>
+      </div>
+    </el-col>
+  </div>
+</template>
+
+<script>
+import upload from '@/components/upload.vue';
+export default {
+  name: 'person',
+  props: {
+    form: null,
+    option: null,
+    options: null,
+  },
+  components: {
+    upload,
+  },
+  data: () => ({
+    // 出生日期
+  }),
+  created() {},
+  computed: {
+    id() {
+      return this.$route.query.id;
+    },
+  },
+  methods: {
+    changeshenge(value) {
+      this.$emit('placesubmit', { value });
+    },
+    onSubmit() {
+      console.log(this.form);
+
+      this.$emit('onSubmit', { data: this.form });
+    },
+    // 图片上传
+    uploadSuccess({ type, data }) {
+      console.log(type, data);
+      this.$set(this.form, `${type}`, data.uri);
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.info {
+  margin: 0 0 50px 0;
+}
+</style>

+ 219 - 0
src/layout/market/exportDetails.vue

@@ -0,0 +1,219 @@
+<template>
+  <div id="exportDetails">
+    <el-row>
+      <el-col :span="24" class="info">
+        <el-col :span="24" class="top">
+          <el-image :src="beijing"></el-image>
+        </el-col>
+        <el-col :span="24" class="message">
+          <el-col :span="24" class="one">
+            <el-image :src="exportInfo.img_path"></el-image>
+            <p>
+              <span>{{ exportInfo.name }}</span>
+              <span>{{ exportInfo.email }}</span>
+            </p>
+          </el-col>
+          <el-col :span="24" class="two">
+            <van-tabs v-model="active" type="card" animated>
+              <van-tab title="基本资料">
+                <el-col :span="24" class="basic">
+                  <p>
+                    <span>性别</span>
+                    <span>{{ exportInfo.gender }}</span>
+                  </p>
+                  <p>
+                    <span>出生年月</span>
+                    <span>{{ exportInfo.birthday }}</span>
+                  </p>
+                  <p>
+                    <span>身份证号</span>
+                    <span>{{ exportInfo.cardnumber }}</span>
+                  </p>
+
+                  <p>
+                    <span>电话号码</span>
+                    <span>{{ exportInfo.phone }}</span>
+                  </p>
+                  <p>
+                    <span>毕业院校</span>
+                    <span>{{ exportInfo.school }}</span>
+                  </p>
+                  <p>
+                    <span>专业</span>
+                    <span>{{ exportInfo.major }}</span>
+                  </p>
+                  <p>
+                    <span>学历</span>
+                    <span>{{ exportInfo.xl }}</span>
+                  </p>
+                  <p>
+                    <span>学位</span>
+                    <span>{{ exportInfo.xw }}</span>
+                  </p>
+                  <p>
+                    <span>地址</span>
+                    <span>{{ exportInfo.addr }}</span>
+                  </p>
+                </el-col>
+              </van-tab>
+              <van-tab title="技术能力">
+                <el-col :span="24" class="basic">
+                  <p>
+                    <span>从事专业</span>
+                    <span>{{ exportInfo.professional }}</span>
+                  </p>
+                  <p>
+                    <span>职称名称</span>
+                    <span>{{ exportInfo.levelname }}</span>
+                  </p>
+                  <p>
+                    <span>职称级别</span>
+                    <span>{{ exportInfo.level }}</span>
+                  </p>
+                  <p>
+                    <span>职务</span>
+                    <span>{{ exportInfo.position }}</span>
+                  </p>
+                  <p>
+                    <span>项目</span>
+                    <span>{{ exportInfo.project }}</span>
+                  </p>
+                  <p>
+                    <span>学术成就</span>
+                    <span>{{ exportInfo.academic }}</span>
+                  </p>
+                  <p>
+                    <span>论文</span>
+                    <span>{{ exportInfo.paper }}</span>
+                  </p>
+                  <p>
+                    <span>备注</span>
+                    <span>{{ exportInfo.remark }}</span>
+                  </p>
+                </el-col>
+              </van-tab>
+              <van-tab title="个人简介">
+                <el-col :span="24" class="resume">
+                  <p>{{ exportInfo.resume }}</p>
+                </el-col>
+              </van-tab>
+            </van-tabs>
+          </el-col>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'exportDetails',
+  props: {
+    exportInfo: null,
+  },
+  components: {},
+  data: function() {
+    return {
+      beijing: require('@/assets/test1.jpg'),
+      active: '1',
+    };
+  },
+  created() {},
+  methods: {},
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.info {
+  background: #fff;
+  .top {
+    height: 150px;
+    overflow: hidden;
+    .el-image {
+      height: 150px;
+      overflow: hidden;
+    }
+  }
+  .message {
+    position: relative;
+    top: -40px;
+    padding: 0 15px;
+    .one {
+      height: 80px;
+      height: 80px;
+      margin: 0 0 15px 0;
+
+      .el-image {
+        float: left;
+        width: 80px;
+        height: 80px;
+        border-radius: 90px;
+      }
+      p {
+        float: left;
+        width: 65%;
+        font-size: 18px;
+        padding: 0 15px;
+        span {
+          display: inline-block;
+          width: 100%;
+          padding: 9px 0px;
+        }
+      }
+    }
+    .two {
+      .basic {
+        font-size: 16px;
+        color: #000;
+        p {
+          padding: 0 10px;
+          min-height: 40px;
+          line-height: 40px;
+          border-bottom: 1px dashed #f6f6f6;
+          span:first-child {
+            display: inline-block;
+            width: 25%;
+            color: #cccccc;
+          }
+        }
+      }
+      .resume {
+        font-size: 16px;
+        padding: 10px;
+        p {
+          line-height: 30px;
+        }
+      }
+    }
+  }
+}
+/deep/.van-tabs--card > .van-tabs__wrap {
+  height: 40px;
+}
+/deep/.van-tabs__nav--card {
+  height: 40px;
+  border: 1px solid #ccc;
+  margin: 0;
+}
+/deep/.van-tabs__nav--card .van-tab {
+  color: #666;
+}
+/deep/.van-tabs__nav--card .van-tab.van-tab--active {
+  background: transparent;
+  color: #2c69fe;
+  font-weight: bold;
+}
+/deep/.van-tabs__nav--card .van-tab {
+  border-right: 1px solid #ccc;
+}
+</style>

+ 135 - 0
src/layout/market/prodDetail.vue

@@ -0,0 +1,135 @@
+<template>
+  <div id="prodDetails">
+    <el-row>
+      <el-col :span="24" class="info">
+        <el-col :span="24" class="top">
+          <el-carousel trigger="click" class="carousel">
+            <template v-if="productInfo.image && productInfo.image.length > 0">
+              <el-carousel-item v-for="(item, index) in productInfo.image" :key="index">
+                <el-image :src="item.url" style="width:100%"> </el-image>
+              </el-carousel-item>
+            </template>
+          </el-carousel>
+          <p class="textOver">{{ productInfo.name }}</p>
+        </el-col>
+        <el-col :span="24" class="message">
+          <p>
+            <span>产品类型</span>
+            <span>{{ productInfo.totaltype === '0' ? '技术' : productInfo.totaltype === '1' ? '产品' : productInfo.totaltype === '2' ? '服务' : '暂无' }}</span>
+          </p>
+          <p>
+            <span>类型</span>
+            <span>{{ productInfo.product_type_name || '暂无' }}</span>
+          </p>
+          <p v-if="productInfo.totaltype == 0">
+            <span>研发阶段</span>
+            <span>{{ productInfo.phase == 1 ? '阶段成果' : productInfo.phase == 2 ? '最终成果' : '暂无' }}</span>
+          </p>
+          <p>
+            <span>交易方式</span>
+            <span>{{ productInfo.business === '0' ? '公用' : productInfo.business === '1' ? '转让' : productInfo.business === '2' ? '竞价' : '暂无' }}</span>
+          </p>
+          <p v-if="productInfo.totaltype == 0 || productInfo.totaltype == 2">
+            <span>应用领域</span>
+            <span>{{ productInfo.field || '暂无' }}</span>
+          </p>
+          <p>
+            <span>服务范围</span>
+            <span>{{ productInfo.scope || '暂无' }}</span>
+          </p>
+          <p>
+            <span>产品单价</span>
+            <span>{{ productInfo.price }}/{{ productInfo.priceunit }}</span>
+          </p>
+          <p>
+            <span>联系人</span>
+            <span>{{ productInfo.contact_user }}</span>
+          </p>
+          <p>
+            <span>联系电话</span>
+            <span>{{ productInfo.contact_tel }}</span>
+          </p>
+          <div class="introduction">
+            <p>产品简介</p>
+            <p>{{ productInfo.introduction }}</p>
+          </div>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'prodDetails',
+  props: {
+    productInfo: null,
+  },
+  components: {},
+  data: function() {
+    return {};
+  },
+  created() {},
+  methods: {},
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.info {
+  .top {
+    background: #fff;
+    min-height: 250px;
+    padding: 0 15px;
+    margin: 0 0 10px 0;
+    .carousel {
+      height: 200px !important;
+      padding: 10px 0;
+    }
+    .el-image {
+      width: 100%;
+      height: 200px;
+    }
+    p {
+      font-size: 18px;
+      color: #000;
+      padding: 0 0 10px 0;
+    }
+  }
+  .message {
+    background: #fff;
+    padding: 0 15px;
+    min-height: 50px;
+    p {
+      min-height: 50px;
+      line-height: 50px;
+      border-bottom: 1px solid #ccc;
+    }
+    span:first-child {
+      display: inline-block;
+      width: 80px;
+      color: #ccc;
+    }
+    span:last-child {
+      color: #000;
+    }
+    div {
+      p {
+        border-bottom: none;
+      }
+    }
+  }
+}
+/deep/.el-carousel__container {
+  height: 200px !important;
+}
+</style>

+ 193 - 0
src/layout/market/release.vue

@@ -0,0 +1,193 @@
+<template>
+  <div id="release">
+    <el-row>
+      <el-col :span="24" class="info">
+        <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+          <el-form-item label="产品类型" prop="totaltype">
+            <el-select v-model="form.totaltype" placeholder="请选择产品类型">
+              <el-option v-for="(item, index) in totaltype_list" :key="index" :value="item.value" :label="item.name"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="产品名称" prop="name">
+            <el-input v-model="form.name" placeholder="请输入产品名称"></el-input>
+          </el-form-item>
+          <el-form-item label="类型">
+            <el-select v-model="form.product_type_id" filterable @change="selectChild">
+              <el-option v-for="(item, index) in columnList" :key="index" :value="item.id" :label="item.name"></el-option>
+            </el-select>
+          </el-form-item>
+          <span v-if="form.totaltype == 0">
+            <el-form-item label="研发阶段">
+              <el-select v-model="form.phase" placeholder="请选择研发阶段">
+                <el-option label="阶段成果" value="1"></el-option>
+                <el-option label="最终成果" value="2"></el-option>
+              </el-select>
+            </el-form-item>
+          </span>
+          <el-form-item label="产品简介">
+            <el-input v-model="form.introduction" placeholder="请输入产品简介"></el-input>
+          </el-form-item>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="产品单价">
+                <el-input v-model="form.price" placeholder="产品单价"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="产品单位">
+                <el-select v-model="form.priceunit" placeholder="单位">
+                  <el-option v-for="(item, index) in priceunit_list" :key="index" :label="item.name" :value="item.name"></el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-form-item label="产品图片" prop="image">
+            <upload
+              :limit="1"
+              :data="form.image"
+              :uploadBtn="true"
+              type="image"
+              :url="`/files/image/upload`"
+              @upload="uploadSuccess"
+              @delete="uploadDelete"
+            ></upload>
+          </el-form-item>
+
+          <span v-if="form.totaltype == 0 || form.totaltype == 2">
+            <el-form-item label="应用领域">
+              <el-input v-model="form.field" placeholder="请输入应用领域"></el-input>
+            </el-form-item>
+          </span>
+          <el-form-item label="服务范围">
+            <el-input type="textarea" v-model="form.scope" placeholder="请输入服务范围"></el-input>
+          </el-form-item>
+          <el-form-item label="交易方式">
+            <el-select v-model="form.business" placeholder="请选择交易方式">
+              <el-option label="公用" value="0"></el-option>
+              <el-option label="竞价" value="1"></el-option>
+              <el-option label="转让" value="2"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="联系人" prop="contact_user">
+            <el-input v-model="form.contact_user" placeholder="请输入联系人"></el-input>
+          </el-form-item>
+          <el-form-item label="联系电话" prop="contact_tel">
+            <el-input v-model="form.contact_tel" placeholder="请输入联系电话"></el-input>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" @click="onSubmit(form)">发布</el-button>
+          </el-form-item>
+        </el-form>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import upload from '@/components/upload.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: maarkettype } = createNamespacedHelpers('maarkettype');
+const { mapActions: marketproduct } = createNamespacedHelpers('marketproduct');
+
+export default {
+  name: 'release',
+  props: {},
+  components: {
+    upload,
+  },
+  data: function() {
+    return {
+      form: {},
+      // 产品类型
+      totaltype_list: [
+        { name: '技术', value: '0' },
+        { name: '产品', value: '1' },
+        { name: '服务', value: '2' },
+      ],
+      // 类型
+      columnList: [],
+      // 单位
+      priceunit_list: [
+        {
+          name: '公斤',
+        },
+        {
+          name: '套',
+        },
+        {
+          name: '件',
+        },
+      ],
+      rules: {
+        totaltype: [{ required: true, message: '请选择产品类型', trigger: 'blur' }],
+        name: [{ required: true, message: '请输入产品名称', trigger: 'blur' }],
+      },
+    };
+  },
+  created() {
+    this.searchType();
+  },
+  methods: {
+    ...maarkettype(['query']),
+    ...marketproduct({ productFetch: 'fetch', productCreate: 'create', productUpdate: 'update', productQuery: 'query' }),
+
+    // 提交发布
+    async onSubmit(form) {
+      form.status = '0';
+      form.userid = this.user.uid;
+      let res;
+      let msg;
+      console.log(form);
+      res = await this.productCreate(form);
+      msg = `${this.keyWord}添加成功`;
+      this.$checkRes(res, '添加成功', '添加失败');
+      this.$router.push({ path: '/userCenter/myProduct/index' });
+    },
+
+    // 查询类型
+    async searchType({ category = 54, ...info } = {}) {
+      const res = await this.query({ category, ...info });
+      if (this.$checkRes(res)) {
+        this.$set(this, `columnList`, res.data);
+      }
+    },
+    // 类型选择
+    selectChild(product_type_id) {
+      let res = this.columnList.filter(fil => fil.id === product_type_id);
+      if (res.length > 0) {
+        this.$set(this.form, `product_type_name`, res[0].name);
+      }
+      this.$forceUpdate();
+    },
+
+    // 图片
+    uploadSuccess({ type, data }) {
+      console.log(type, data);
+      console.log(data.uri);
+      let image = [{ url: data.uri }];
+      console.log(image);
+      this.$set(this.form, `image`, image);
+    },
+    // 删除图片
+    uploadDelete(index) {
+      this.form.image.splice(index, 1);
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.info {
+  margin: 0 0px 50px 0;
+  padding: 15px 0 0 0;
+}
+</style>

+ 105 - 0
src/layout/matter/detailinfo.vue

@@ -0,0 +1,105 @@
+<template>
+  <div id="detailinfo">
+    <el-row>
+      <el-col :span="24" class="info">
+        <el-col :span="24" class="top">
+          <p class="textOver">{{ detailInfo.product_name }}</p>
+        </el-col>
+        <el-col :span="24" class="message">
+          <p>
+            <span>营销人名称:</span>
+            <span>{{ detailInfo.market_username || '暂无' }}</span>
+          </p>
+          <p>
+            <span>购买人名称:</span>
+            <span>{{ detailInfo.username || '暂无' }}</span>
+          </p>
+          <p>
+            <span>状态:</span>
+            <span>{{ detailInfo.status === '0' ? '洽谈' : detailInfo.status === '1' ? '意向' : detailInfo.status === '2' ? '交易' : '暂无' }}</span>
+          </p>
+          <div class="introduction">
+            <p>说明:</p>
+            <p>{{ detailInfo.description || '暂无' }}</p>
+          </div>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'detailinfo',
+  props: {
+    detailInfo: null,
+  },
+  components: {},
+  data: function() {
+    return {};
+  },
+  created() {},
+  methods: {},
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.info {
+  .top {
+    background: #fff;
+    min-height: 40px;
+    padding: 0 15px;
+    margin: 0 0 10px 0;
+    .carousel {
+      height: 200px !important;
+      padding: 10px 0;
+    }
+    .el-image {
+      width: 100%;
+      height: 200px;
+    }
+
+    p {
+      font-size: 18px;
+      // color: #7996b1;
+      padding: 10px 0 10px 0;
+    }
+  }
+  .message {
+    background: #fff;
+    padding: 0 15px;
+    min-height: 50px;
+    p {
+      min-height: 50px;
+      line-height: 50px;
+      border-bottom: 1px solid #ccc;
+    }
+    span:first-child {
+      display: inline-block;
+      width: 98px;
+      color: #ccc;
+    }
+    span:last-child {
+      color: #000;
+    }
+    div {
+      p {
+        border-bottom: none;
+      }
+    }
+  }
+}
+/deep/.el-carousel__container {
+  height: 200px !important;
+}
+</style>

+ 135 - 0
src/layout/myProduct/prodDetails.vue

@@ -0,0 +1,135 @@
+<template>
+  <div id="prodDetails">
+    <el-row>
+      <el-col :span="24" class="info">
+        <el-col :span="24" class="top">
+          <el-carousel trigger="click" class="carousel">
+            <template v-if="productInfo.image && productInfo.image.length > 0">
+              <el-carousel-item v-for="(item, index) in productInfo.image" :key="index">
+                <el-image :src="item.url" style="width:100%"> </el-image>
+              </el-carousel-item>
+            </template>
+          </el-carousel>
+          <p class="textOver">{{ productInfo.name }}</p>
+        </el-col>
+        <el-col :span="24" class="message">
+          <p>
+            <span>产品类型</span>
+            <span>{{ productInfo.totaltype === '0' ? '技术' : productInfo.totaltype === '1' ? '产品' : productInfo.totaltype === '2' ? '服务' : '暂无' }}</span>
+          </p>
+          <p>
+            <span>类型</span>
+            <span>{{ productInfo.product_type_name || '暂无' }}</span>
+          </p>
+          <p>
+            <span>研发阶段</span>
+            <span>{{ productInfo.phase == 1 ? '阶段成果' : productInfo.phase == 2 ? '最终成果' : '暂无' }}</span>
+          </p>
+          <p>
+            <span>交易方式</span>
+            <span>{{ productInfo.business === '0' ? '公用' : productInfo.business === '1' ? '转让' : productInfo.business === '2' ? '竞价' : '暂无' }}</span>
+          </p>
+          <p>
+            <span>应用领域</span>
+            <span>{{ productInfo.field || '暂无' }}</span>
+          </p>
+          <p>
+            <span>服务范围</span>
+            <span>{{ productInfo.scope || '暂无' }}</span>
+          </p>
+          <p>
+            <span>产品单价</span>
+            <span>{{ productInfo.price }}/{{ productInfo.priceunit }}</span>
+          </p>
+          <p>
+            <span>联系人</span>
+            <span>{{ productInfo.contact_user }}</span>
+          </p>
+          <p>
+            <span>联系电话</span>
+            <span>{{ productInfo.contact_tel }}</span>
+          </p>
+          <div class="introduction">
+            <p>产品简介</p>
+            <p>{{ productInfo.introduction }}</p>
+          </div>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'prodDetails',
+  props: {
+    productInfo: null,
+  },
+  components: {},
+  data: function() {
+    return {};
+  },
+  created() {},
+  methods: {},
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.info {
+  .top {
+    background: #fff;
+    min-height: 250px;
+    padding: 0 15px;
+    margin: 0 0 10px 0;
+    .carousel {
+      height: 200px !important;
+      padding: 10px 0;
+    }
+    .el-image {
+      width: 100%;
+      height: 200px;
+    }
+    p {
+      font-size: 18px;
+      color: #000;
+      padding: 0 0 10px 0;
+    }
+  }
+  .message {
+    background: #fff;
+    padding: 0 15px;
+    min-height: 50px;
+    p {
+      min-height: 50px;
+      line-height: 50px;
+      border-bottom: 1px solid #ccc;
+    }
+    span:first-child {
+      display: inline-block;
+      width: 80px;
+      color: #ccc;
+    }
+    span:last-child {
+      color: #000;
+    }
+    div {
+      p {
+        border-bottom: none;
+      }
+    }
+  }
+}
+/deep/.el-carousel__container {
+  height: 200px !important;
+}
+</style>

+ 189 - 0
src/layout/myProduct/release.vue

@@ -0,0 +1,189 @@
+<template>
+  <div id="release">
+    <el-row>
+      <el-col :span="24" class="info">
+        <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+          <el-form-item label="产品类型" prop="totaltype">
+            <el-select v-model="form.totaltype" placeholder="请选择产品类型">
+              <el-option v-for="(item, index) in totaltype_list" :key="index" :value="item.value" :label="item.name"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="产品名称" prop="name">
+            <el-input v-model="form.name" placeholder="请输入产品名称"></el-input>
+          </el-form-item>
+          <el-form-item label="类型">
+            <el-select v-model="form.product_type_id" filterable @change="selectChild">
+              <el-option v-for="(item, index) in columnList" :key="index" :value="item.id" :label="item.name"></el-option>
+            </el-select>
+          </el-form-item>
+          <span v-if="form.totaltype == 0">
+            <el-form-item label="研发阶段">
+              <el-select v-model="form.phase" placeholder="请选择研发阶段">
+                <el-option label="阶段成果" value="1"></el-option>
+                <el-option label="最终成果" value="2"></el-option>
+              </el-select>
+            </el-form-item>
+          </span>
+          <el-form-item label="产品简介">
+            <el-input v-model="form.introduction" placeholder="请输入产品简介"></el-input>
+          </el-form-item>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="产品单价">
+                <el-input v-model="form.price" placeholder="产品单价"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="产品单位">
+                <el-select v-model="form.priceunit" placeholder="单位">
+                  <el-option v-for="(item, index) in priceunit_list" :key="index" :label="item.name" :value="item.name"></el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-form-item label="产品图片" prop="image">
+            <upload
+              :limit="1"
+              :data="form.image"
+              :uploadBtn="true"
+              type="image"
+              :url="`/files/image/upload`"
+              @upload="uploadSuccess"
+              @delete="uploadDelete"
+            ></upload>
+          </el-form-item>
+          <span v-if="form.totaltype == 0 || form.totaltype == 2">
+            <el-form-item label="应用领域">
+              <el-input v-model="form.field" placeholder="请输入应用领域"></el-input>
+            </el-form-item>
+          </span>
+          <el-form-item label="服务范围">
+            <el-input type="textarea" v-model="form.scope" placeholder="请输入服务范围"></el-input>
+          </el-form-item>
+          <el-form-item label="交易方式">
+            <el-select v-model="form.business" placeholder="请选择交易方式">
+              <el-option label="公用" value="0"></el-option>
+              <el-option label="竞价" value="1"></el-option>
+              <el-option label="转让" value="2"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="联系人" prop="contact_user">
+            <el-input v-model="form.contact_user" placeholder="请输入联系人"></el-input>
+          </el-form-item>
+          <el-form-item label="联系电话" prop="contact_tel">
+            <el-input v-model="form.contact_tel" placeholder="请输入联系电话"></el-input>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" @click="onSubmitDraft">保存草稿</el-button>
+            <el-button type="primary" @click="onSubmit">信息发布</el-button>
+          </el-form-item>
+        </el-form>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import upload from '@/components/upload.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: maarkettype } = createNamespacedHelpers('maarkettype');
+
+export default {
+  name: 'release',
+  props: {
+    form: null,
+  },
+  components: {
+    upload,
+  },
+  data: function() {
+    return {
+      // 产品类型
+      totaltype_list: [
+        { name: '技术', value: '0' },
+        { name: '产品', value: '1' },
+        { name: '服务', value: '2' },
+      ],
+      // 类型
+      columnList: [],
+      // 单位
+      priceunit_list: [
+        {
+          name: '公斤',
+        },
+        {
+          name: '套',
+        },
+        {
+          name: '件',
+        },
+      ],
+      rules: {
+        totaltype: [{ required: true, message: '请选择产品类型', trigger: 'blur' }],
+        name: [{ required: true, message: '请输入产品名称', trigger: 'blur' }],
+      },
+    };
+  },
+  created() {
+    this.searchType();
+  },
+  methods: {
+    ...maarkettype(['query']),
+    // 保存草稿
+    onSubmitDraft() {
+      this.$emit('onSubmitDraft', { data: this.form });
+    },
+    // 信息发布
+    onSubmit() {
+      this.$emit('onSubmit', { data: this.form });
+    },
+    // 查询类型
+    async searchType({ category = 54, ...info } = {}) {
+      const res = await this.query({ category, ...info });
+      if (this.$checkRes(res)) {
+        this.$set(this, `columnList`, res.data);
+      }
+    },
+    // 类型选择
+    selectChild(product_type_id) {
+      let res = this.columnList.filter(fil => fil.id === product_type_id);
+      if (res.length > 0) {
+        this.$set(this.form, `product_type_name`, res[0].name);
+      }
+      this.$forceUpdate();
+    },
+
+    // 图片
+    uploadSuccess({ type, data }) {
+      let arr = _.get(this.form, type);
+      if (_.isArray(arr)) {
+        let datas = { name: data.name, url: data.uri };
+        this.form[type].push({ name: data.name, url: data.uri });
+      } else {
+        let newArr = [{ name: data.name, url: data.uri }];
+        this.$set(this.form, `${type}`, newArr);
+      }
+    },
+    // 删除图片
+    uploadDelete(index) {
+      this.form.image.splice(index, 1);
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.info {
+  margin: 0 0px 50px 0;
+  padding: 15px 0 0 0;
+}
+</style>

+ 92 - 0
src/layout/transaction/detaliinfo.vue

@@ -0,0 +1,92 @@
+<template>
+  <div id="person">
+    <el-col :span="24" class="info">
+      <van-form @submit="onSubmit">
+        <van-field
+          v-model="form.product_name"
+          name="产品名称"
+          label="产品名称"
+          placeholder="请输入产品名称"
+          disabled
+          :rules="[{ required: true, message: '请输入产品名称' }]"
+        />
+
+        <van-field
+          v-model="form.market_username"
+          name="营销人名称"
+          label="营销人名称"
+          placeholder="请输入营销人名称"
+          disabled
+          :rules="[{ required: true, message: '请输入营销人名称' }]"
+        />
+
+        <van-field
+          v-model="form.username"
+          name="购买人名称"
+          label="购买人名称"
+          placeholder="请输入购买人名称"
+          disabled
+          :rules="[{ required: true, message: '请输入购买人名称' }]"
+        />
+      </van-form>
+
+      <van-field
+        type="textarea"
+        v-model="form.description"
+        name="描述"
+        label="描述"
+        placeholder="请输入描述"
+        :rules="[{ required: true, message: '请输入描述' }]"
+      />
+      <van-field name="radio" label="审核">
+        <template #input>
+          <van-radio-group v-model="form.status" direction="horizontal">
+            <van-radio name="0">待审核</van-radio>
+            <van-radio name="1">审核通过</van-radio>
+          </van-radio-group>
+        </template>
+      </van-field>
+
+      <div style="margin: 16px;">
+        <van-button round block type="info" native-type="submit" @click="onSubmit">
+          保存
+        </van-button>
+      </div>
+    </el-col>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'person',
+  props: {
+    form: null,
+  },
+  components: {},
+  data: () => ({
+    // 出生日期
+  }),
+  created() {},
+  computed: {
+    id() {
+      return this.$route.query.id;
+    },
+  },
+  methods: {
+    // 出生日期
+
+    onSubmit() {
+      console.log(this.form);
+
+      this.$emit('onSubmit', { data: this.form });
+    },
+    // 图片上传
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.info {
+  margin: 0 0 50px 0;
+}
+</style>

+ 185 - 0
src/layout/user/person.vue

@@ -0,0 +1,185 @@
+<template>
+  <div id="person">
+    <el-col :span="24" class="info">
+      <van-form @submit="onSubmit">
+        <van-field v-model="form.name" name="用户名称" label="用户名称" placeholder="请输入用户名称" :rules="[{ required: true, message: '请输入用户名称' }]" />
+        <van-field v-model="form.phone" name="手机号" label="手机号" placeholder="请输入手机号" disabled />
+        <van-field
+          v-model="form.cardnumber"
+          name="身份证号"
+          label="身份证号"
+          placeholder="请输入身份证号"
+          :rules="[{ required: true, message: '请输入身份证号' }]"
+        />
+        <van-field v-model="form.email" name="邮箱" label="邮箱" placeholder="请输入邮箱" :rules="[{ required: true, message: '请输入邮箱' }]" />
+        <van-field v-model="form.addr" name="地址" label="地址" placeholder="请输入地址" :rules="[{ required: true, message: '请输入地址' }]" />
+        <van-field name="uploader" label="头像">
+          <!-- <template #input><upload :limit="1" :data="form.img_path" type="img_path" :url="'/files/imgpath/upload'" @upload="uploadSuccess"></upload> </template> -->
+          <template #input><upload :limit="1" :data="form.img_path" type="img_path" :url="'/files/imgpath/upload'" @upload="uploadSuccess"></upload> </template>
+        </van-field>
+        <van-field name="radio" label="用户类型">
+          <template #input>
+            <van-radio-group v-model="form.role" direction="horizontal">
+              <van-radio name="2">个人</van-radio>
+              <van-radio name="3">企业</van-radio>
+              <van-radio name="6">专家</van-radio>
+            </van-radio-group>
+          </template>
+        </van-field>
+        <van-field name="uploader" label="身份证正面" v-if="form.role == '2' || form.role == '3'">
+          <template #input
+            ><upload
+              :limit="1"
+              v-if="form.role == '2' || form.role == '3'"
+              :data="form.cardfile_a"
+              type="cardfile_a"
+              :url="'/files/cardfilea/upload'"
+              @upload="uploadSuccess"
+            ></upload>
+          </template>
+        </van-field>
+        <van-field name="uploader" label="身份证背面" v-if="form.role == '2' || form.role == '3'">
+          <template #input
+            ><upload
+              :limit="1"
+              v-if="form.role == '2' || form.role == '3'"
+              :data="form.cardfile_b"
+              type="cardfile_b"
+              :url="'/files/cardfileb/upload'"
+              @upload="uploadSuccess"
+            ></upload>
+          </template>
+        </van-field>
+        <van-field name="uploader" label="组织机构图片" v-if="form.role == '3'">
+          <template #input
+            ><upload
+              :limit="1"
+              v-if="form.role == '2' || form.role == '3'"
+              :data="form.img_qy"
+              type="img_qy"
+              :url="'/files/img_qy/upload'"
+              @upload="uploadSuccess"
+            ></upload>
+          </template>
+        </van-field>
+        <template v-if="form.role == '3'">
+          <van-field v-model="form.institution_type" name="机构类型" label="机构类型" placeholder="请输入机构类型" />
+          <van-field v-model="form.institution_name" name="机构名称" label="机构类型" placeholder="请输入机构名称" />
+          <van-field v-model="form.institution_code" name="机构代码" label="机构代码" placeholder="请输入机构代码" />
+          <van-field v-model="form.institution_nature" name="机构性质" label="机构性质" placeholder="请输入机构性质" />
+        </template>
+        <van-field v-model="form.office_phone" v-if="form.role == '2' || form.role == '3'" name="办公电话" label="办公电话" placeholder="请输入办公电话" />
+        <van-field v-model="form.profession" v-if="form.role == '2' || form.role == '3'" name="所属行业" label="所属行业" placeholder="请输入所属行业" />
+        <van-field name="radio" label="性别" v-if="form.role == '6'">
+          <template #input>
+            <van-radio-group v-model="form.gender" direction="horizontal">
+              <van-radio name="男">男</van-radio>
+              <van-radio name="女">女</van-radio>
+            </van-radio-group>
+          </template>
+        </van-field>
+        <van-cell title="日期" is-link :value="form.birthday" @click="birthdayPopup" v-if="form.role == '6'" />
+        <van-popup v-model="birthdayShow" position="bottom">
+          <van-datetime-picker type="date" @cancel="birthdayShow = false" @confirm="birthdayPicker" />
+        </van-popup>
+        <van-field v-model="form.level" v-if="form.role == '6'" name="职称级别" label="职称级别" placeholder="请输入职称级别" />
+        <van-field v-model="form.levelname" v-if="form.role == '6'" name="职称" label="职称" placeholder="请输入职称" />
+        <van-field v-model="form.position" v-if="form.role == '6'" name="职务" label="职务" placeholder="请输入职务" />
+        <van-field v-model="form.school" v-if="form.role == '6'" name="院校" label="院校" placeholder="院校" />
+        <van-field readonly clickable name="picker" :value="form.xl" label="学历" v-if="form.role == '6'" placeholder="请选择学历" @click="xlPicker = true" />
+        <van-popup v-model="xlPicker" position="bottom">
+          <van-picker show-toolbar :columns="xlList" @confirm="onConfirm" @cancel="xlPicker = false" />
+        </van-popup>
+        <van-field readonly clickable name="picker" :value="form.xw" label="学位" v-if="form.role == '6'" placeholder="请选择学位" @click="xwPicker = true" />
+        <van-popup v-model="xwPicker" position="bottom">
+          <van-picker show-toolbar :columns="xwList" @confirm="onConfirms" @cancel="xwPicker = false" />
+        </van-popup>
+        <van-field v-model="form.major" v-if="form.role == '6'" name="专业" label="专业" placeholder="请输入专业" />
+        <van-field v-model="form.professional" v-if="form.role == '6'" name="从事专业" label="从事专业 " placeholder="请输入从事专业" />
+        <van-field
+          v-model="form.resume"
+          autosize
+          label="个人简历"
+          v-if="form.role == '2' || form.role == '6'"
+          type="textarea"
+          placeholder="请输入个人简历"
+          show-word-limit
+        />
+        <van-field v-model="form.project" v-if="form.role == '6'" name="项目" label="项目 " placeholder="请输入项目" />
+        <van-field v-model="form.academic" v-if="form.role == '6'" name="学术成就" label="学术成就 " placeholder="请输入学术成就" />
+        <van-field v-model="form.paper" v-if="form.role == '6'" name="论文" label="论文 " placeholder="请输入论文" />
+        <van-field v-model="form.remark" autosize label="备注" v-if="form.role == '6'" type="textarea" placeholder="请输入备注" show-word-limit />
+        <div style="margin: 16px;">
+          <van-button round block type="info" native-type="submit">
+            保存
+          </van-button>
+        </div>
+      </van-form>
+    </el-col>
+  </div>
+</template>
+
+<script>
+import upload from '@/components/upload.vue';
+export default {
+  name: 'person',
+  props: {
+    form: null,
+  },
+  components: {
+    upload,
+  },
+  data: () => ({
+    // 出生日期
+    birthday: '',
+    birthdayShow: false,
+    // 学历
+    xlPicker: false,
+    xlList: ['中专及以上', '大专及以上', '本科及以上', '研究生及以上'],
+    // 学位
+    xwPicker: false,
+    xwList: ['学士', '硕士', '博士', '其他'],
+  }),
+  created() {},
+  computed: {},
+  methods: {
+    // 出生日期
+    birthdayPopup() {
+      this.birthdayShow = true;
+    },
+    // 确认选择之后的时间
+    birthdayPicker(val) {
+      let year = val.getFullYear();
+      let month = val.getMonth() + 1;
+      let day = val.getDate();
+      let birthday = `${year}-${month}-${day}`;
+      this.$set(this.form, `birthday`, birthday);
+      this.birthdayShow = false;
+    },
+    // 学历
+    onConfirm(xl) {
+      this.$set(this.form, `xl`, xl);
+      this.xlPicker = false;
+    },
+    // 学位
+    onConfirms(xw) {
+      this.$set(this.form, `xw`, xw);
+      this.xwPicker = false;
+    },
+    onSubmit() {
+      this.$emit('onSubmit', { data: this.form });
+    },
+    // 图片上传
+    uploadSuccess({ type, data }) {
+      console.log(type, data);
+      this.$set(this.form, `${type}`, data.uri);
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.info {
+  margin: 0 0 50px 0;
+}
+</style>

+ 21 - 7
src/main.js

@@ -1,12 +1,26 @@
-import Vue from "vue";
-import App from "./App.vue";
-import router from "./router";
-import store from "./store";
-
+import Vue from 'vue';
+import App from './App.vue';
+import router from './router';
+import store from './store';
+import '@/plugins/element.js';
+import '@/plugins/vant';
+import '@/plugins/axios';
+import '@/plugins/check-res';
+import '@/plugins/meta';
+import '@/plugins/filters';
+import '@/plugins/loading';
+import '@/plugins/var';
+import '@/plugins/methods';
+import '@/plugins/setting';
+import InitStomp from '@/plugins/stomp';
 Vue.config.productionTip = false;
 
 new Vue({
   router,
   store,
-  render: h => h(App)
-}).$mount("#app");
+  render: h => h(App),
+}).$mount('#app');
+InitStomp();
+window.vm = new Vue({
+  router,
+});

+ 19 - 0
src/plugins/axios.js

@@ -0,0 +1,19 @@
+import Vue from 'vue';
+import AxiosWrapper from '@/util/axios-wrapper';
+
+const Plugin = {
+  install(vue, options) {
+    // 3. 注入组件
+    vue.mixin({
+      created() {
+        if (this.$store && !this.$store.$axios) {
+          this.$store.$axios = this.$axios;
+        }
+      },
+    });
+    // 4. 添加实例方法
+    vue.prototype.$axios = new AxiosWrapper(options);
+  },
+};
+
+Vue.use(Plugin, { baseUrl: process.env.VUE_APP_AXIOS_BASE_URL });

+ 42 - 0
src/plugins/check-res.js

@@ -0,0 +1,42 @@
+/* eslint-disable no-underscore-dangle */
+/* eslint-disable no-param-reassign */
+/* eslint-disable no-unused-vars */
+/* eslint-disable no-shadow */
+import Vue from 'vue';
+import _ from 'lodash';
+import { Message } from 'element-ui';
+import { Notify } from 'vant';
+
+const vm = new Vue({});
+const Plugin = {
+  install(Vue, options) {
+    // 4. 添加实例方法
+    Vue.prototype.$checkRes = (res, okText, errText) => {
+      let _okText = okText;
+      let _errText = errText;
+      if (!_.isFunction(okText) && _.isObject(okText) && okText != null) {
+        ({ okText: _okText, errText: _errText } = okText);
+      }
+      const { errcode = 0, errmsg } = res || {};
+      if (errcode === 0) {
+        if (_.isFunction(_okText)) {
+          return _okText();
+        }
+        if (_okText) {
+          Message.success(_okText);
+          Notify({ type: 'success', message: _okText });
+        }
+        return true;
+      }
+      if (_.isFunction(_errText)) {
+        return _errText();
+      }
+      Message.error(_errText || errmsg);
+      Notify({ type: 'danger', message: _okText });
+      // Message({ message: _errText || errmsg, duration: 60000 });
+      return false;
+    };
+  },
+};
+
+Vue.use(Plugin);

+ 5 - 0
src/plugins/element.js

@@ -0,0 +1,5 @@
+import Vue from 'vue';
+import Element from 'element-ui';
+import 'element-ui/lib/theme-chalk/index.css';
+
+Vue.use(Element);

+ 6 - 0
src/plugins/filters.js

@@ -0,0 +1,6 @@
+import Vue from 'vue';
+import filters from '@/util/filters';
+
+for (const method in filters) {
+  Vue.filter(method, filters[method]);
+}

+ 27 - 0
src/plugins/loading.js

@@ -0,0 +1,27 @@
+/* eslint-disable no-console */
+/* eslint-disable no-param-reassign */
+
+import Vue from 'vue';
+
+const Plugin = {
+  // eslint-disable-next-line no-unused-vars
+  install(vue, options) {
+    // 3. 注入组件
+    vue.mixin({
+      created() {
+        // eslint-disable-next-line no-underscore-dangle
+        const isRoot = this.constructor === Vue;
+        // console.log(`rootId:${rootVue_uid}; thisId:${this._uid}`);
+        // if (rootVue_uid !== 3) {
+        //   console.log(this);
+        // }
+        if (isRoot) {
+          const el = document.getElementById('loading');
+          if (el) el.style.display = 'none';
+        }
+      },
+    });
+  },
+};
+
+Vue.use(Plugin, { baseUrl: process.env.VUE_APP_AXIOS_BASE_URL });

+ 4 - 0
src/plugins/meta.js

@@ -0,0 +1,4 @@
+import Vue from 'vue';
+import Meta from 'vue-meta';
+
+Vue.use(Meta);

+ 33 - 0
src/plugins/methods.js

@@ -0,0 +1,33 @@
+import Vue from 'vue';
+import _ from 'lodash';
+const Plugin = {
+  install(Vue, options) {
+    // 3. 注入组件
+    Vue.mixin({
+      created() {
+        if (this.$store && !this.$store.$toUndefined) {
+          this.$store.$toUndefined = this.$toUndefined;
+        }
+      },
+    });
+    // 4. 添加实例方法
+    Vue.prototype.$toUndefined = object => {
+      let keys = Object.keys(object);
+      keys.map(item => {
+        object[item] = object[item] === '' ? (object[item] = undefined) : object[item];
+      });
+      return object;
+    };
+    Vue.prototype.$turnTo = item => {
+      if (item.info_type == 1) {
+        window.open(item.url);
+      } else {
+        let router = window.vm.$router;
+        let route = window.vm.$route.path;
+        router.push({ path: `/info/detail?id=${item.id}` });
+      }
+    };
+  },
+};
+
+Vue.use(Plugin);

+ 20 - 0
src/plugins/setting.js

@@ -0,0 +1,20 @@
+import Vue from 'vue';
+
+Vue.config.weixin = {
+  // baseUrl: process.env.BASE_URL + 'weixin',
+  baseUrl: 'http://10.16.8.209:9005',
+};
+
+Vue.config.stomp = {
+  // brokerURL: 'ws://http://free.liaoningdoupo.com/ws',
+  brokerURL: '/ws', // ws://${location.host}/ws
+  connectHeaders: {
+    host: 'visit',
+    login: 'visit', //visit
+    passcode: 'visit', //visit123
+  },
+  // debug: true,
+  reconnectDelay: 5000,
+  heartbeatIncoming: 4000,
+  heartbeatOutgoing: 4000,
+};

+ 65 - 0
src/plugins/stomp.js

@@ -0,0 +1,65 @@
+/**
+ * 基于WebStomp的消息处理插件
+ */
+
+import Vue from 'vue';
+import _ from 'lodash';
+import assert from 'assert';
+import { Client } from '@stomp/stompjs/esm5/client';
+
+const Plugin = {
+  install(Vue, options) {
+    assert(_.isObject(options));
+    if (options.debug && !_.isFunction(options.debug)) {
+      options.debug = str => {
+        console.log(str);
+      };
+    }
+    assert(_.isString(options.brokerURL));
+    if (!options.brokerURL.startsWith('ws://')) {
+      options.brokerURL = `ws://${location.host}${options.brokerURL}`;
+    }
+
+    // 3. 注入组件
+    Vue.mixin({
+      beforeDestroy: function() {
+        if (this.$stompClient) {
+          this.$stompClient.deactivate();
+          delete this.$stompClient;
+        }
+      },
+    });
+
+    // 4. 添加实例方法
+    Vue.prototype.$stomp = function(subscribes = {}) {
+      // connect to mq
+      const client = new Client(options);
+      client.onConnect = frame => {
+        // Do something, all subscribes must be done is this callback
+        // This is needed because this will be executed after a (re)connect
+        console.log('[stomp] connected');
+        Object.keys(subscribes)
+          .filter(p => _.isFunction(subscribes[p]))
+          .forEach(key => {
+            client.subscribe(key, subscribes[key]);
+          });
+      };
+
+      client.onStompError = frame => {
+        // Will be invoked in case of error encountered at Broker
+        // Bad login/passcode typically will cause an error
+        // Complaint brokers will set `message` header with a brief message. Body may contain details.
+        // Compliant brokers will terminate the connection after any error
+        console.log('Broker reported error: ' + frame.headers['message']);
+        console.log('Additional details: ' + frame.body);
+      };
+
+      client.activate();
+
+      this.$stompClient = client;
+    };
+  },
+};
+export default () => {
+  Vue.use(Plugin, Vue.config.stomp);
+};

+ 5 - 0
src/plugins/vant.js

@@ -0,0 +1,5 @@
+import Vue from 'vue';
+import Vant from 'vant';
+import 'vant/lib/index.css';
+
+Vue.use(Vant);

+ 25 - 0
src/plugins/var.js

@@ -0,0 +1,25 @@
+import Vue from 'vue';
+import _ from 'lodash';
+
+const getSiteId = () => {
+  let host = `${window.location.hostname}`; //`999991.smart.jilinjobswx.cn ${window.location.hostname}`
+  let schId;
+  host = host.replace('http://', '');
+  let arr = host.split('.');
+  if (arr.length > 0) {
+    schId = arr[0];
+    if (schId === 'smart') schId = 'master';
+    else `${schId}`.includes('localhost') || `${schId}`.includes('127.0.0.1') ? (schId = '99991') : '';
+    sessionStorage.setItem('schId', `${schId}`.includes('localhost') || `${schId}`.includes('127.0.0.1') ? '99991' : schId);
+  }
+  return schId;
+};
+const Plugin = {
+  install(vue, options) {
+    // 4. 添加实例方法
+    vue.prototype.$limit = 10;
+    vue.prototype.$site = getSiteId();
+  },
+};
+
+Vue.use(Plugin);

+ 243 - 15
src/router/index.js

@@ -1,28 +1,256 @@
-import Vue from "vue";
-import VueRouter from "vue-router";
-import Home from "../views/Home.vue";
+import Vue from 'vue';
+import VueRouter from 'vue-router';
+import store from '@/store/index';
 
 Vue.use(VueRouter);
 
 const routes = [
+  // 绑定
   {
-    path: "/",
-    name: "Home",
-    component: Home
+    path: '/bind',
+    name: 'bind',
+    meta: { title: '绑定', isleftarrow: false },
+    component: () => import('../views/bind.vue'),
   },
+  // 错误
   {
-    path: "/about",
-    name: "About",
-    // route level code-splitting
-    // this generates a separate chunk (about.[hash].js) for this route
-    // which is lazy-loaded when the route is visited.
-    component: () =>
-      import(/* webpackChunkName: "about" */ "../views/About.vue")
-  }
+    path: '/error',
+    name: '',
+    meta: { title: '错误页面', isleftarrow: false },
+    component: () => import('../views/error.vue'),
+  },
+  // 直播大厅
+  {
+    path: '/live/index',
+    name: 'live_index',
+    meta: { title: '直播大厅', isleftarrow: true },
+    component: () => import('../views/live/index.vue'),
+  },
+  // 直播详情
+  {
+    path: '/live/roomDetail',
+    name: 'live_detail',
+    meta: { title: '直播详情', isleftarrow: true },
+    component: () => import('../views/live/roomDetail.vue'),
+  },
+  // 直播详情
+  {
+    path: '/live/detail',
+    name: 'live_detail',
+    meta: { title: '直播详情', isleftarrow: true },
+    component: () => import('../views/live/detail.vue'),
+  },
+  // 直播房间详情
+  {
+    path: '/onlive/roomInfo',
+    name: 'onlive_roomInfo',
+    meta: { title: '直播房间详情', isleftarrow: true },
+    component: () => import('../views/onlive/roomInfo.vue'),
+  },
+
+  // 科技超市
+  {
+    path: '/market/index',
+    name: 'market_index',
+    meta: { title: '科技超市', isleftarrow: true },
+    component: () => import('../views/market/index.vue'),
+  },
+  // 科技超市-技术-产品-服务详情
+  {
+    path: '/market/prodDetail',
+    name: 'market_prodDetail',
+    meta: { title: '产品详情', isleftarrow: true },
+    component: () => import('../views/market/prodDetail.vue'),
+  },
+  // 科技超市-专家详情
+  {
+    path: '/market/exportDetail',
+    name: 'market_exportDetail',
+    meta: { title: '专家详情', isleftarrow: true },
+    component: () => import('../views/market/exportDetail.vue'),
+  },
+
+  // 科技超市-发布产品
+  {
+    path: '/market/detail',
+    name: 'market_detail',
+    meta: { title: '发布产品', isleftarrow: true },
+    component: () => import('../views/market/detail.vue'),
+  },
+  // 创新服务
+  {
+    path: '/service/index',
+    name: 'service_index',
+    meta: { title: '创新服务', isleftarrow: true },
+    component: () => import('../views/service/index.vue'),
+  },
+  {
+    path: '/service/detail',
+    name: 'service_detail',
+    meta: { title: '创新服务', isleftarrow: true },
+    component: () => import('../views/service/detail.vue'),
+  },
+  // 用户-我的发布
+  {
+    path: '/userCenter/myProduct/index',
+    name: 'myProduct_index',
+    meta: { title: '我的发布', isleftarrow: true },
+    component: () => import('../views/userCenter/myProduct/index.vue'),
+  },
+
+  //用户-我的发布详情
+  {
+    path: '/userCenter/myProduct/detailinfo',
+    name: 'myProduct_detailinfo',
+    meta: { title: '产品详情', isleftarrow: true },
+    component: () => import('../views/userCenter/myProduct/detailinfo.vue'),
+  },
+
+  // 用户-发布产品
+  {
+    path: '/userCenter/myProduct/detail',
+    name: 'myProduct_detail',
+    meta: { title: '发布产品', isleftarrow: true },
+    component: () => import('../views/userCenter/myProduct/detail.vue'),
+  },
+  // 用户-事项管理
+  {
+    path: '/userCenter/matter/index',
+    name: 'matter_index',
+    meta: { title: '事项管理', isleftarrow: true },
+    component: () => import('../views/userCenter/matter/index.vue'),
+  },
+
+  // 用户-事项管理详情
+  {
+    path: '/userCenter/matter/detailinfo',
+    name: 'matter_idetailinfo',
+    meta: { title: '事项详情', isleftarrow: true },
+    component: () => import('../views/userCenter/matter/detailinfo.vue'),
+  },
+
+  // 用户-展会管理
+  {
+    path: '/userCenter/dock/index',
+    name: 'dock_index',
+    meta: { title: '展会管理', isleftarrow: true },
+    component: () => import('../views/userCenter/dock/index.vue'),
+  },
+  // 用户-申请对接会
+  {
+    path: '/userCenter/dock/apply',
+    name: 'dock_apply',
+    meta: { title: '申请对接会', isleftarrow: true },
+    component: () => import('../views/userCenter/dock/apply.vue'),
+  },
+  // 用户-个人中心
+  {
+    path: '/userCenter/user/index',
+    name: 'user_index',
+    meta: { title: '个人中心', isleftarrow: true },
+    component: () => import('../views/userCenter/user/index.vue'),
+  },
+  // // 个人中心
+  {
+    path: '/user/index',
+    name: 'user_index',
+    meta: { title: '个人中心', isleftarrow: true },
+    component: () => import('../views/user/index.vue'),
+  },
+
+  // 管理员个人中心-用户管理
+  {
+    path: '/adminCenter/user/index',
+    name: 'adminCenter_user_index',
+    meta: { title: '用户管理', isleftarrow: true },
+    component: () => import('../views/adminCenter/user/index.vue'),
+  },
+  // 管理员个人中心-编辑审核
+  {
+    path: '/adminCenter/user/detail',
+    name: 'adminCenter_user_detail',
+    meta: { title: '用户详情', isleftarrow: true },
+    component: () => import('../views/adminCenter/user/detail.vue'),
+  },
+  // 管理员个人中心-对接会管理
+  {
+    path: '/adminCenter/duijiehui/index',
+    name: 'adminCenter_user_detail',
+    meta: { title: '对接会管理', isleftarrow: true },
+    component: () => import('../views/adminCenter/duijiehui/index.vue'),
+  },
+  // 管理员个人中心-对接会详情
+  {
+    path: '/adminCenter/duijiehui/detail',
+    name: 'adminCenter_duijiehuir_detail',
+    meta: { title: '对接会详情', isleftarrow: true },
+    component: () => import('../views/adminCenter/duijiehui/detail.vue'),
+  },
+
+  // 管理员个人中心-对接会审核
+  {
+    path: '/adminCenter/duijiehui/examine',
+    name: 'adminCenter_duijiehuiexamine',
+    meta: { title: '对接会状态审核', isleftarrow: true },
+    component: () => import('../views/adminCenter/duijiehui/examine.vue'),
+  },
+
+  // 管理员个人中心-对接会申请状况列表
+  {
+    path: '/adminCenter/duijiehui/apply',
+    name: 'adminCenter_duijiapply',
+    meta: { title: '对接会申请状况列表', isleftarrow: true },
+    component: () => import('../views/adminCenter/duijiehui/apply.vue'),
+  },
+
+  // 管理员个人中心-对接会申请状况列表
+  {
+    path: '/adminCenter/enterpriseProduct/index',
+    name: 'adminCenter_enterpriseProduct',
+    meta: { title: '产品供求审核管理', isleftarrow: true },
+    component: () => import('../views/adminCenter/enterpriseProduct/index.vue'),
+  },
+  // 管理员个人中心-产品供求交易状态审核管理
+  {
+    path: '/adminCenter/transaction/index',
+    name: 'adminCenter_transaction',
+    meta: { title: '产品供求交易状态审核管理', isleftarrow: true },
+    component: () => import('../views/adminCenter/transaction/index.vue'),
+  },
+
+  // 管理员个人中心-产品供求交易状态审核管理
+  {
+    path: '/adminCenter/transaction/detail',
+    name: 'adminCenter_detail',
+    meta: { title: '产品供求交易状态审核管理详情', isleftarrow: true },
+    component: () => import('../views/adminCenter/transaction/detail.vue'),
+  },
+
+  ,
 ];
 
 const router = new VueRouter({
-  routes
+  mode: 'history',
+  base: process.env.NODE_ENV === 'development' ? '' : process.env.VUE_APP_ROUTER,
+  routes,
+});
+router.beforeEach((to, form, next) => {
+  if (to.name === 'user_index') {
+    store.commit('setUser');
+    if (to.name === 'home_index') {
+      next();
+      return;
+    }
+    let user = store.state.user;
+    if (user) {
+      next();
+    }
+    //下面是没登录的情况,需要跳转页面到用户未登录页
+    else next({ name: 'home_index' });
+  } else {
+    store.commit('setUser');
+    next();
+  }
 });
 
 export default router;

+ 39 - 0
src/store/chat.js

@@ -0,0 +1,39 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  interface: `/api/live/chat`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit = undefined, ...info } = {}) {
+    const res = await this.$axios.$get(api.interface, { skip, limit, ...info });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.interface}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.interface}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...info } = {}) {
+    const res = await this.$axios.$post(`${api.interface}/${id}`, { ...info });
+    return res;
+  },
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.interface}/${payload}`);
+    return res;
+  },
+};
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 19 - 0
src/store/common/mutations.js

@@ -0,0 +1,19 @@
+const jwt = require('jsonwebtoken');
+export const setUser = (state, payload) => {
+  let res = true;
+  // 登陆时;
+  if (payload) {
+    state.user = payload;
+  } else {
+    //已经登陆,切换路由时取出用户信息放在总store中
+    let token = sessionStorage.getItem('token');
+    if (token) {
+      state.user = jwt.decode(token);
+    }
+  }
+  return res;
+};
+export const deleteUser = (state, payload) => {
+  state.user = {};
+  localStorage.removeItem('user');
+};

+ 1 - 0
src/store/common/state.js

@@ -0,0 +1 @@
+export const user = undefined;

+ 47 - 5
src/store/index.js

@@ -1,11 +1,53 @@
-import Vue from "vue";
-import Vuex from "vuex";
+import Vue from 'vue';
+import Vuex from 'vuex';
+import login from '@common/store/login';
+import marketproduct from '@common/store/market/marketproduct';
+import expertsuser from '@common/store/market/exportuser';
+import maarkettype from '@common/store/market/markettype';
+import productpact from '@common/store/market/productpact';
+import authUser from './user/auth-user';
+import dock from '@common/store/live/dock';
+import wxchattest from './user/wxchattest';
+import market from '@common/store/market/market';
+import apply from '@common/store/live/apply';
+import transaction from '@common/store/market/transaction';
+import expertsaudit from '@common/store/market/expertsaudit';
+import exportuser from '@common/store/market/exportuser';
+import user from './user';
+import place from './place';
+import onliveUser from './onlive/user';
+import gensign from './onlive/gensign';
+import room from './onlive/room';
+import chat from './chat';
+import * as ustate from '@/store/common/state';
+import * as umutations from '@/store/common/mutations';
 
 Vue.use(Vuex);
 
 export default new Vuex.Store({
-  state: {},
-  mutations: {},
+  state: { ...ustate },
+  mutations: { ...umutations },
   actions: {},
-  modules: {}
+  modules: {
+    login,
+    market,
+    marketproduct,
+    expertsuser,
+    maarkettype,
+    authUser,
+    dock,
+    wxchattest,
+    apply,
+    transaction,
+    expertsaudit,
+    productpact,
+    exportuser,
+    user,
+    dock,
+    place,
+    onliveUser,
+    room,
+    gensign,
+    chat,
+  },
 });

+ 23 - 0
src/store/onlive/gensign.js

@@ -0,0 +1,23 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  gensignInfo: `/api/onlive/user/gensign`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async gensignFetch({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.gensignInfo}`, payload);
+    return res;
+  },
+};
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 50 - 0
src/store/onlive/room.js

@@ -0,0 +1,50 @@
+// 房间
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  roomInfo: `/api/onlive/room`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit = 10, ...info } = {}) {
+    const res = await this.$axios.$get(api.roomInfo, {
+      skip,
+      limit,
+      ...info,
+    });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.roomInfo}`, payload);
+    return res;
+  },
+  async roomfetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.roomInfo}/roomname`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.roomInfo}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...info } = {}) {
+    const res = await this.$axios.$post(`${api.roomInfo}/update/${id}`, {
+      ...info,
+    });
+    return res;
+  },
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.roomInfo}/${payload}`);
+    return res;
+  },
+};
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 39 - 0
src/store/onlive/user.js

@@ -0,0 +1,39 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  onliveInfo: `/api/onlive/user`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit = 10, ...info } = {}) {
+    const res = await this.$axios.$get(api.onliveInfo, { skip, limit, ...info });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.onliveInfo}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.onliveInfo}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...info } = {}) {
+    const res = await this.$axios.$post(`${api.onliveInfo}/${id}`, { ...info });
+    return res;
+  },
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.onliveInfo}/${payload}`);
+    return res;
+  },
+};
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 43 - 0
src/store/place.js

@@ -0,0 +1,43 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  userInfo: `/api/setting/xzqh/items`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit, ...info } = {}) {
+    const res = await this.$axios.$get(`${api.userInfo}`, {
+      skip,
+      limit,
+      ...info,
+    });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.userInfo}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.userInfo}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...data }) {
+    const res = await this.$axios.$post(`${api.userInfo}/${id}`, data);
+    return res;
+  },
+
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.userInfo}/${payload}`);
+    return res;
+  },
+};
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 39 - 0
src/store/user.js

@@ -0,0 +1,39 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  interface: `/api/market/user`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit = 10, ...info } = {}) {
+    const res = await this.$axios.$get(api.interface, { skip, limit, ...info });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.interface}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.interface}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...info } = {}) {
+    const res = await this.$axios.$post(`${api.interface}/${id}`, { ...info });
+    return res;
+  },
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.interface}/${payload}`);
+    return res;
+  },
+};
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 49 - 0
src/store/user/auth-user.js

@@ -0,0 +1,49 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+//用户的菜单选项增删改查
+Vue.use(Vuex);
+const api = {
+  interface: `/api/auth/user`,
+  getMenu: `/api/auth/user/menus`,
+  bindInfo: `/api/auth/user/bind`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit = undefined, ...info } = {}) {
+    const res = await this.$axios.$get(api.interface, { skip, limit, ...info });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.interface}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    //特殊变化,查用户菜单
+    const res = await this.$axios.$get(`${api.getMenu}`, payload);
+    return res;
+  },
+  async update({ commit }, { id, ...info } = {}) {
+    const res = await this.$axios.$post(`${api.interface}/update/${id}`, {
+      ...info,
+    });
+    return res;
+  },
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.interface}/${payload}`);
+    return res;
+  },
+  async bind({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.bindInfo}`, payload);
+    return res;
+  },
+};
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 34 - 0
src/store/user/wxchattest.js

@@ -0,0 +1,34 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  wxchattestInfo: `/api/auth/wxchattest`,
+};
+const state = () => ({});
+const mutations = {
+  setUser(state, payload) {
+    if (payload) {
+      state.user = payload;
+      sessionStorage.setItem('user', JSON.stringify(payload));
+    } else {
+      let user = sessionStorage.getItem('user');
+      if (user) state.user = JSON.parse(user);
+      else return false;
+    }
+  },
+};
+
+const actions = {
+  async login({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.wxchattestInfo}`, payload);
+    return res;
+  },
+};
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 117 - 0
src/util/axios-wrapper.js

@@ -0,0 +1,117 @@
+/* eslint-disable no-console */
+/* eslint-disable no-param-reassign */
+
+import _ from 'lodash';
+import Axios from 'axios';
+import { Util, Error } from 'naf-core';
+// import { Indicator } from 'mint-ui';
+import util from './user-util';
+
+const { trimData, isNullOrUndefined } = Util;
+const { ErrorCode } = Error;
+
+let currentRequests = 0;
+
+export default class AxiosWrapper {
+  constructor({ baseUrl = '', unwrap = true } = {}) {
+    this.baseUrl = baseUrl;
+    this.unwrap = unwrap;
+  }
+
+  // 替换uri中的参数变量
+  static merge(uri, query = {}) {
+    if (!uri.includes(':')) {
+      return uri;
+    }
+    const keys = [];
+    const regexp = /\/:([a-z0-9_]+)/gi;
+    let res;
+    // eslint-disable-next-line no-cond-assign
+    while ((res = regexp.exec(uri)) != null) {
+      keys.push(res[1]);
+    }
+    keys.forEach(key => {
+      if (!isNullOrUndefined(query[key])) {
+        uri = uri.replace(`:${key}`, query[key]);
+      }
+    });
+    return uri;
+  }
+
+  $get(uri, query, options) {
+    return this.$request(uri, null, query, options);
+  }
+
+  $post(uri, data = {}, query, options) {
+    return this.$request(uri, data, query, options);
+  }
+  $delete(uri, data = {}, router, query, options = {}) {
+    options = { ...options, method: 'delete' };
+    return this.$request(uri, data, query, options, router);
+  }
+  async $request(uri, data, query, options) {
+    // TODO: 合并query和options
+    if (_.isObject(query) && _.isObject(options)) {
+      options = { ...options, params: query, method: 'get' };
+    } else if (_.isObject(query) && !query.params) {
+      options = { params: query };
+    } else if (_.isObject(query) && query.params) {
+      options = query;
+    }
+    if (!options) options = {};
+    if (options.params) options.params = trimData(options.params);
+    const url = AxiosWrapper.merge(uri, options.params);
+    currentRequests += 1;
+    // Indicator.open({
+    //   spinnerType: 'fading-circle',
+    // });
+
+    try {
+      const axios = Axios.create({
+        baseURL: this.baseUrl,
+      });
+      axios.defaults.headers.common.Authorization = util.token;
+      let res = await axios.request({
+        method: isNullOrUndefined(data) ? 'get' : 'post',
+        url,
+        data,
+        responseType: 'json',
+        ...options,
+      });
+      res = res.data;
+      const { errcode, errmsg, details } = res;
+      if (errcode) {
+        console.warn(`[${uri}] fail: ${errcode}-${errmsg} ${details}`);
+        return res;
+      }
+      // unwrap data
+      if (this.unwrap) {
+        res = _.omit(res, ['errmsg', 'details']);
+        const keys = Object.keys(res);
+        if (keys.length === 1 && keys.includes('data')) {
+          res = res.data;
+        }
+      }
+      return res;
+    } catch (err) {
+      let errmsg = '接口请求失败,请稍后重试';
+      if (err.response) {
+        const { status } = err.response;
+        if (status === 401) errmsg = '用户认证失败,请重新登录';
+        if (status === 403) errmsg = '当前用户不允许执行该操作';
+      }
+      console.error(
+        `[AxiosWrapper] 接口请求失败: ${err.config && err.config.url} - 
+        ${err.message}`
+      );
+      return { errcode: ErrorCode.SERVICE_FAULT, errmsg, details: err.message };
+    } finally {
+      /* eslint-disable */
+      currentRequests -= 1;
+      if (currentRequests <= 0) {
+        currentRequests = 0;
+        // Indicator.close();
+      }
+    }
+  }
+}

+ 10 - 0
src/util/filters.js

@@ -0,0 +1,10 @@
+import _ from 'lodash';
+
+const filters = {
+  getName(object) {
+    const { data, searchItem } = object;
+    return _.get(data, searchItem) === undefined ? '' : _.get(data, searchItem);
+  },
+};
+
+export default filters;

+ 30 - 0
src/util/menus.js

@@ -0,0 +1,30 @@
+export const coreMenu = [
+  {
+    path: '/talk/list/in',
+    name: '校内宣讲会',
+  },
+  {
+    path: '/talk/list/out',
+    name: '校外宣讲会',
+  },
+  {
+    path: '/jobfair/list/in',
+    name: '校内招聘会',
+  },
+  {
+    path: '/jobfair/list/out',
+    name: '校外招聘会',
+  },
+  {
+    path: '/jobinfo/list',
+    name: '在线招聘',
+  },
+  {
+    path: '/jobs/list/official',
+    name: '正式岗位',
+  },
+  {
+    path: '/jobs/list/internship',
+    name: '实习岗位',
+  },
+];

+ 50 - 0
src/util/methods-util.js

@@ -0,0 +1,50 @@
+import { Util } from 'naf-core';
+
+const { isNullOrUndefined } = Util;
+
+export default {
+  //判断信息是否过期
+  isDateOff(dataDate) {
+    const now = new Date(new Date().getTime() - 24 * 60 * 60 * 1000);
+    dataDate = new Date(dataDate);
+    return now.getTime() <= dataDate.getTime();
+  },
+  //判断企业是否可以执行此动作/显示
+  checkCorp(data) {
+    const { role, unit, selfUnit, status, displayType, userid } = data;
+    if (!isNullOrUndefined(selfUnit) && !isNullOrUndefined(status)) {
+      return role === 'corp' && selfUnit === unit && status === '0';
+    } else if (!isNullOrUndefined(displayType)) {
+      if (role === 'corp') {
+        return role === displayType;
+      } else {
+        return role === displayType && !isNullOrUndefined(userid);
+      }
+    }
+  },
+  //获取url的参数params
+  getParams() {
+    let str = location.href;
+    let num = str.indexOf('?');
+    const param = {};
+    str = str.substr(num + 1);
+    let num2 = str.indexOf('#');
+    let str2 = '';
+    if (num2 > 0) {
+      str2 = str.substr(0, num2);
+    } else {
+      num2 = str.indexOf('/');
+      str2 = str.substr(0, num2);
+    }
+    const arr = str2.split('&');
+    for (let i = 0; i < arr.length; i++) {
+      num = arr[i].indexOf('=');
+      if (num > 0) {
+        const name = arr[i].substring(0, num);
+        const value = arr[i].substr(num + 1);
+        param[name] = decodeURI(value);
+      }
+    }
+    return param;
+  },
+};

+ 47 - 0
src/util/optionTitles.js

@@ -0,0 +1,47 @@
+export const JOBFAIR_TITLE = [
+  { prop: 'subject', label: '' },
+  { prop: 'address', label: '举办地址' },
+  { prop: 'date', label: '举办日期' },
+  { prop: 'unit', label: '分站信息' },
+];
+
+export const CAMPUS_TITLE = [
+  { prop: 'subject', label: '' },
+  { prop: 'address', label: '举办地址' },
+  { prop: 'status', label: '审核状态' },
+  { prop: 'date', label: '举办日期' },
+  { prop: 'unit', label: '分站信息' },
+];
+
+export const JOBINFO_TITLE = [
+  { prop: 'title', label: '' },
+  { prop: 'count', label: '需求人数' },
+  { prop: 'nature.name', label: '工作性质' },
+  { prop: 'salary.name', label: '薪资待遇' },
+  { prop: 'xlreqs.name', label: '最低学历' },
+  { prop: 'city.name', label: '所在城市' },
+  // { prop: 'expired', label: '状态' },
+];
+
+export const RESUME_TITLE = [{ prop: 'title', label: '' }];
+
+export const LETTER_TITLE = [
+  { prop: 'title', label: '' },
+  { prop: 'corpname', label: '企业名称' },
+  { prop: 'type', label: '类型' },
+  { prop: 'status', label: '状态' },
+];
+
+export const TICKET_TITLE = [
+  { prop: 'subject', label: '' },
+  { prop: 'type', label: '门票类型' },
+  { prop: 'origin', label: '' },
+  { prop: 'date', label: '举办日期' },
+];
+
+export const CORP_JOBFAIR = [
+  { prop: 'subject', label: '' },
+  { prop: 'time', label: '举办时间' },
+  { prop: 'date', label: '举办日期' },
+  { prop: 'unit', label: '分站信息' },
+];

+ 96 - 0
src/util/qrcode.vue

@@ -0,0 +1,96 @@
+<template>
+  <div id="qrcodes" style="width:100%;">
+    <mt-header title="二维码">
+      <mt-button class="bgnone" slot="left" @click="$router.go(-1)">返回</mt-button>
+    </mt-header>
+    <span v-if="user.role === 'user'">
+      <li class="txtQr" style="padding-top:7vh;">学生姓名:{{ userInfo.xm || '' }}</li>
+      <li class="txtQr">门票类型:{{ ticketType }}</li>
+    </span>
+    <div id="qrcode" style="display:flex;justify-content:center;align-items:center;" :style="newHeight" ref="qrcode">
+      <canvas id="canvas" style="display:-webkit-inline-box;width: 4rem !important;height:4rem !important;margin-top: 200px;"></canvas>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapActions, mapState, mapMutations } from 'vuex';
+import QRCode from 'qrcode';
+export default {
+  name: 'qrcodes',
+  data() {
+    return {
+      id: this.$route.query.id || '',
+      ticketType: this.$route.query.type && this.$route.query.type === '0' ? '普通票' : '受限票' || '',
+      popupVisible: false,
+    };
+  },
+  computed: {
+    ...mapState({
+      user: state => state.publics.user,
+      userInfo: state => state.self.userInfo,
+    }),
+    newHeight: {
+      get() {
+        let height;
+        if (this.user.role === 'user') {
+          height = window.screen.availHeight * 0.3 + 'px';
+        } else {
+          height = window.screen.availHeight * 0.6 + 'px';
+        }
+        let style = { height: height };
+        return style;
+      },
+    },
+  },
+  created() {
+    this.$nextTick(() => {
+      this.initQrcode();
+    });
+  },
+  methods: {
+    async initQrcode() {
+      if (!this.booForQrcode) {
+        await QRCode.toCanvas(document.getElementById('canvas'), this.id, {
+          width: 300,
+          margin: 0,
+          color: { dark: this.$route.query.type === '0' ? '#00ff14' : '#FF9900' },
+        });
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.txtQr {
+  font-size: 14px;
+  text-align: center;
+  min-height: 30px;
+  margin-bottom: 1px;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+.mint-header {
+  -webkit-box-align: center;
+  -ms-flex-align: center;
+  align-items: center;
+  background-color: #26a2ff;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  color: #fff;
+  display: -webkit-box;
+  display: -ms-flexbox;
+  display: flex;
+  height: 50px;
+  line-height: 50px;
+  color: #fff;
+  font-size: 16px;
+  background: #2577e3;
+  padding: 0;
+  position: relative;
+  text-align: center;
+  white-space: nowrap;
+}
+</style>

+ 69 - 0
src/util/user-util.js

@@ -0,0 +1,69 @@
+/* eslint-disable no-console */
+export default {
+  get user() {
+    const val = sessionStorage.getItem('user');
+    try {
+      if (val) return JSON.parse(val);
+    } catch (err) {
+      console.error(err);
+    }
+    return null;
+  },
+  set user(userinfo) {
+    sessionStorage.setItem('user', JSON.stringify(userinfo));
+  },
+  get token() {
+    return sessionStorage.getItem('token');
+  },
+  set token(token) {
+    sessionStorage.setItem('token', token);
+  },
+  get openid() {
+    return sessionStorage.getItem('openid');
+  },
+  set openid(openid) {
+    sessionStorage.setItem('openid', openid);
+  },
+  get isGuest() {
+    return !this.user || this.user.role === 'guest';
+  },
+  save({ userinfo, token }) {
+    sessionStorage.setItem('user', JSON.stringify(userinfo));
+    sessionStorage.setItem('token', token);
+  },
+
+  get corpInfo() {
+    const val = sessionStorage.getItem('corpInfo');
+    if (val) return JSON.parse(val);
+    return null;
+  },
+  set corpInfo(corpInfo) {
+    sessionStorage.setItem('corpInfo', JSON.stringify(corpInfo));
+  },
+  saveCorpInfo(corpInfo) {
+    sessionStorage.setItem('corpInfo', JSON.stringify(corpInfo));
+  },
+
+  get unit() {
+    const val = sessionStorage.getItem('unit');
+    if (val) return JSON.parse(val);
+    return null;
+  },
+  set unit(unitList) {
+    sessionStorage.setItem('unit', JSON.stringify(unitList));
+  },
+  saveUnit(unitList) {
+    sessionStorage.setItem('unit', JSON.stringify(unitList));
+  },
+  get userInfo() {
+    const val = sessionStorage.getItem('userInfo');
+    if (val) return JSON.parse(val);
+    return null;
+  },
+  set userInfo(userInfo) {
+    sessionStorage.setItem('userInfo', JSON.stringify(userInfo));
+  },
+  saveUserInfo(userInfo) {
+    sessionStorage.setItem('userInfo', JSON.stringify(userInfo));
+  },
+};

+ 0 - 5
src/views/About.vue

@@ -1,5 +0,0 @@
-<template>
-  <div class="about">
-    <h1>This is an about page</h1>
-  </div>
-</template>

+ 0 - 18
src/views/Home.vue

@@ -1,18 +0,0 @@
-<template>
-  <div class="home">
-    <img alt="Vue logo" src="../assets/logo.png" />
-    <HelloWorld msg="Welcome to Your Vue.js App" />
-  </div>
-</template>
-
-<script>
-// @ is an alias to /src
-import HelloWorld from "@/components/HelloWorld.vue";
-
-export default {
-  name: "Home",
-  components: {
-    HelloWorld
-  }
-};
-</script>

+ 92 - 0
src/views/adminCenter/duijiehui/apply.vue

@@ -0,0 +1,92 @@
+<template>
+  <div id="index">
+    <el-row>
+      <el-col :span="24" class="style">
+        <el-col :span="24" class="top">
+          <NavBar v-show="navShow" :title="title" :isleftarrow="isleftarrow"> </NavBar>
+        </el-col>
+        <el-col :span="24" class="main">
+          <el-col :span="24" class="main">
+            <el-col :span="24" class="one">
+              <applyList></applyList>
+            </el-col>
+          </el-col>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+import NavBar from '@/layout/common/topInfo.vue';
+import applyList from './parts/applyList.vue';
+export default {
+  name: 'index',
+  props: {},
+  components: { NavBar, applyList },
+  data: () => ({
+    // 头部标题
+    title: '',
+    // meta为true
+    isleftarrow: '',
+    // 返回
+    navShow: true,
+    img_path: require('@/assets/logo.png'),
+    active: 0,
+    show: false,
+    newform: {},
+  }),
+  created() {},
+  computed: {},
+  methods: {},
+  mounted() {
+    this.title = this.$route.meta.title;
+    this.isleftarrow = this.$route.meta.isleftarrow;
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.style {
+  width: 100%;
+  min-height: 667px;
+  position: relative;
+  background-color: #f9fafc;
+}
+.top {
+  height: 46px;
+  overflow: hidden;
+  position: relative;
+  z-index: 999;
+}
+.main {
+  min-height: 570px;
+  .two {
+    position: fixed;
+    top: 80%;
+
+    left: 10px;
+    z-index: 999;
+  }
+}
+/deep/.van-tab {
+  text-align: center;
+}
+/deep/.van-tabs--line .van-tabs__wrap {
+  height: 70px;
+  margin: 0 0 10px 0;
+}
+/deep/.van-tab--active {
+  color: red;
+}
+.van-icon {
+  font-size: 20px;
+}
+/deep/.van-popup--bottom {
+  bottom: 0;
+  left: 0;
+  width: 100%;
+  height: 300px;
+}
+</style>

+ 132 - 0
src/views/adminCenter/duijiehui/detail.vue

@@ -0,0 +1,132 @@
+<template>
+  <div id="index">
+    <el-row>
+      <el-col :span="24" class="style">
+        <el-col :span="24" class="top">
+          <NavBar v-show="navShow" :title="title" :isleftarrow="isleftarrow"> </NavBar>
+        </el-col>
+        <el-col :span="24" class="main">
+          <detail :form="form" @onSubmit="onSubmit" @placesubmit="placesubmit" :option="option" :options="options"></detail>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import NavBar from '@/layout/common/topInfo.vue';
+import detail from '@/layout/duijiehui/detail.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: dock } = createNamespacedHelpers('dock');
+const { mapActions: place } = createNamespacedHelpers('place');
+
+export default {
+  name: 'index',
+  props: {},
+  components: {
+    NavBar,
+    detail, //个人信息维护
+  },
+  data: () => ({
+    // 头部标题
+    title: '',
+    // meta为true
+    isleftarrow: '',
+    // 返回
+    navShow: true,
+    // 个人信息
+    form: {},
+    option: [],
+    options: [],
+  }),
+  created() {
+    this.searchinfo();
+    this.search();
+    this.searchplace();
+  },
+  computed: {
+    ...mapState(['user']),
+    id() {
+      return this.$route.query.id;
+    },
+    role() {
+      return this.$route.query.role;
+    },
+  },
+  methods: {
+    ...place({ palcequery: 'query', transactiondtetle: 'delete' }),
+    ...dock({ livefetch: 'fetch', livelist: 'query', livecreate: 'create', liveupdate: 'update' }),
+
+    async placesubmit({ value }) {
+      let level = 2;
+      let parent = value;
+      let res = await this.palcequery({ level, parent });
+      this.$set(this, `options`, res.data);
+    },
+
+    async searchplace() {
+      if (this.id) {
+        let level = 2;
+        let ress = await this.livefetch(this.id);
+        let parent = ress.data.place;
+        let res = await this.palcequery({ level, parent });
+        this.$set(this, `options`, res.data);
+      }
+    },
+
+    async searchinfo() {
+      let level = 1;
+      let res = await this.palcequery({ level });
+      console.log(res.data);
+      console.log(res.data);
+      this.$set(this, `option`, res.data);
+    },
+
+    async search() {
+      if (this.id) {
+        let res = await this.livefetch(this.id);
+        this.$set(this, `form`, res.data);
+      }
+    },
+    async onSubmit({ data }) {
+      console.log(data);
+      if (this.id) {
+        let res = await this.liveupdate(data);
+        this.$checkRes(res, '修改成功', '修改失败');
+      } else {
+        this.form.user_id = this.user.uid;
+        this.form.is_allowed = '1';
+        let res = await this.livecreate(data);
+        this.$checkRes(res, '创建成功', '添加失败');
+      }
+      this.$router.push({ path: './index' });
+    },
+  },
+  mounted() {
+    this.title = this.$route.meta.title;
+    this.isleftarrow = this.$route.meta.isleftarrow;
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.style {
+  width: 100%;
+  min-height: 667px;
+  position: relative;
+  background-color: #f9fafc;
+}
+.top {
+  height: 46px;
+  overflow: hidden;
+  position: relative;
+  z-index: 999;
+}
+.main {
+  min-height: 570px;
+}
+.foot {
+  position: absolute;
+  bottom: 0;
+}
+</style>

+ 129 - 0
src/views/adminCenter/duijiehui/examine.vue

@@ -0,0 +1,129 @@
+<template>
+  <div id="index">
+    <el-row>
+      <el-col :span="24" class="style">
+        <el-col :span="24" class="top">
+          <NavBar v-show="navShow" :title="title" :isleftarrow="isleftarrow"> </NavBar>
+        </el-col>
+        <el-col :span="24" class="main">
+          <examineinfo :form="form" @onSubmit="onSubmit" @placesubmit="placesubmit" :option="option" :options="options"></examineinfo>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import NavBar from '@/layout/common/topInfo.vue';
+import examineinfo from '@/layout/duijiehui/examineinfo.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: dock } = createNamespacedHelpers('dock');
+const { mapActions: place } = createNamespacedHelpers('place');
+
+export default {
+  name: 'index',
+  props: {},
+  components: {
+    NavBar,
+    examineinfo, //个人信息维护
+  },
+  data: () => ({
+    // 头部标题
+    title: '',
+    // meta为true
+    isleftarrow: '',
+    // 返回
+    navShow: true,
+    // 个人信息
+    form: {},
+    option: [],
+    options: [],
+  }),
+  created() {
+    this.searchinfo();
+    this.search();
+    this.searchplace();
+  },
+  computed: {
+    ...mapState(['user']),
+    id() {
+      return this.$route.query.id;
+    },
+    role() {
+      return this.$route.query.role;
+    },
+  },
+  methods: {
+    ...place({ palcequery: 'query', transactiondtetle: 'delete' }),
+    ...dock({ livefetch: 'fetch', livelist: 'query', livecreate: 'create', liveupdate: 'update' }),
+
+    async placesubmit({ value }) {
+      let level = 2;
+      let parent = value;
+      let res = await this.palcequery({ level, parent });
+      this.$set(this, `options`, res.data);
+    },
+
+    async searchplace() {
+      if (this.id) {
+        let level = 2;
+        let ress = await this.livefetch(this.id);
+        let parent = ress.data.place;
+        let res = await this.palcequery({ level, parent });
+        this.$set(this, `options`, res.data);
+      }
+    },
+
+    async searchinfo() {
+      let level = 1;
+      let res = await this.palcequery({ level });
+
+      this.$set(this, `option`, res.data);
+    },
+
+    async search() {
+      let res = await this.livefetch(this.id);
+      this.$set(this, `form`, res.data);
+    },
+    async onSubmit({ data }) {
+      console.log(data);
+      if (this.id) {
+        let res = await this.liveupdate(data);
+        this.$checkRes(res, '修改成功', '修改失败');
+      } else {
+        this.form.user_id = this.user.uid;
+        this.form.is_allowed = '1';
+        let res = await this.livecreate(data);
+        this.$checkRes(res, '创建成功', '添加失败');
+      }
+      this.$router.push({ path: './index' });
+    },
+  },
+  mounted() {
+    this.title = this.$route.meta.title;
+    this.isleftarrow = this.$route.meta.isleftarrow;
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.style {
+  width: 100%;
+  min-height: 667px;
+  position: relative;
+  background-color: #f9fafc;
+}
+.top {
+  height: 46px;
+  overflow: hidden;
+  position: relative;
+  z-index: 999;
+}
+.main {
+  min-height: 570px;
+}
+.foot {
+  position: absolute;
+  bottom: 0;
+}
+</style>

+ 92 - 0
src/views/adminCenter/duijiehui/index.vue

@@ -0,0 +1,92 @@
+<template>
+  <div id="index">
+    <el-row>
+      <el-col :span="24" class="style">
+        <el-col :span="24" class="top">
+          <NavBar v-show="navShow" :title="title" :isleftarrow="isleftarrow"> </NavBar>
+        </el-col>
+        <el-col :span="24" class="main">
+          <el-col :span="24" class="main">
+            <el-col :span="24" class="one">
+              <list></list>
+            </el-col>
+          </el-col>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+import NavBar from '@/layout/common/topInfo.vue';
+import list from './parts/list.vue';
+export default {
+  name: 'index',
+  props: {},
+  components: { NavBar, list },
+  data: () => ({
+    // 头部标题
+    title: '',
+    // meta为true
+    isleftarrow: '',
+    // 返回
+    navShow: true,
+    img_path: require('@/assets/logo.png'),
+    active: 0,
+    show: false,
+    newform: {},
+  }),
+  created() {},
+  computed: {},
+  methods: {},
+  mounted() {
+    this.title = this.$route.meta.title;
+    this.isleftarrow = this.$route.meta.isleftarrow;
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.style {
+  width: 100%;
+  min-height: 667px;
+  position: relative;
+  background-color: #f9fafc;
+}
+.top {
+  height: 46px;
+  overflow: hidden;
+  position: relative;
+  z-index: 999;
+}
+.main {
+  min-height: 570px;
+  .two {
+    position: fixed;
+    top: 80%;
+
+    left: 10px;
+    z-index: 999;
+  }
+}
+/deep/.van-tab {
+  text-align: center;
+}
+/deep/.van-tabs--line .van-tabs__wrap {
+  height: 70px;
+  margin: 0 0 10px 0;
+}
+/deep/.van-tab--active {
+  color: red;
+}
+.van-icon {
+  font-size: 20px;
+}
+/deep/.van-popup--bottom {
+  bottom: 0;
+  left: 0;
+  width: 100%;
+  height: 300px;
+}
+</style>

+ 162 - 0
src/views/adminCenter/duijiehui/parts/applyList.vue

@@ -0,0 +1,162 @@
+<template>
+  <div id="auditList">
+    <el-row>
+      <el-col :span="24" class="info">
+        <!-- <el-col class="newuser"><van-button type="info" size="small" @click="usersubmit()">新建对接会</van-button> </el-col> -->
+        <el-col :span="24" class="list" v-for="(item, index) in list" :key="index">
+          <p class="textOver">
+            <span class="titel">{{ item.user_name }}</span>
+
+            <span style="margin:0 0 0  5px;"><van-button type="info" size="mini" @click="submit(item)">审核通过</van-button> </span>
+
+            <span style="margin:0 0 0  5px;"><van-button type="info" size="mini" @click="jujue(item)">审核拒绝</van-button> </span>
+          </p>
+          <p>
+            <span class="ptwo"
+              ><span>买家/卖家:{{ item.buyer == '0' ? '买家' : item.buyer == '1' ? '卖家' : '' }}</span></span
+            >
+          </p>
+          <p class="newptwo">
+            <span class="ptwo"><span>联系人:</span>{{ item.contact }}</span>
+            <span>联系人电话</span>{{ item.contact_tel }} <span>邮箱:{{ item.email }}</span>
+          </p>
+
+          <p class="newptwo">
+            <span>单位名称:{{ item.company }}</span>
+            <span>申请时间:{{ item.apply_time }}</span>
+          </p>
+
+          <p class="newptwo">
+            <span>申请状态:{{ item.status == '0' ? '待审核' : item.status == '1' ? '已通过' : item.status == '2' ? '已拒绝' : '' }} </span>
+          </p>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: apply } = createNamespacedHelpers('apply');
+const { mapActions: user } = createNamespacedHelpers('user');
+export default {
+  name: 'auditList',
+  props: {},
+  components: {},
+  data: function() {
+    return {
+      list: [],
+    };
+  },
+  created() {
+    this.search();
+  },
+  methods: {
+    ...user(['query', 'delete', 'update']),
+    ...apply({ dockQuery: 'query', dockDteate: 'delete', applyUpdate: 'update' }),
+    async search() {
+      this.$set(this, `list`, this.data.apply);
+    },
+    async submit(item) {
+      console.log(item);
+      item.status = '1';
+      item.dock_id = this.id;
+      item.id = item._id;
+      console.log(item);
+      let res = await this.applyUpdate(item);
+
+      if (this.$checkRes(res)) {
+        this.$message({
+          message: '审核通过',
+          type: 'success',
+        });
+      }
+    },
+    async jujue(item) {
+      console.log(item);
+      item.status = '2';
+      item.dock_id = this.id;
+      item.id = item._id;
+      console.log(item);
+      let res = await this.applyUpdate(item);
+      if (this.$checkRes(res)) {
+        this.$message({
+          message: '审核拒绝',
+          type: 'success',
+        });
+      }
+    },
+  },
+  computed: {
+    data() {
+      return this.$route.query.data;
+    },
+    id() {
+      return this.$route.query.id;
+    },
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.newuser {
+  float: right;
+  padding: 10px 0 10px 10px;
+}
+.info {
+  border-top: 1px solid #f5f5f5;
+  min-height: 400px;
+  .list {
+    background: #fff;
+    padding: 0 10px;
+    border-bottom: 1px solid #ccc;
+    p {
+      font-size: 14px;
+      color: #000;
+      padding: 5px 0;
+    }
+    p:first-child {
+      font-size: 16px;
+    }
+    p:nth-child(2) .ptwo {
+      display: inline-block;
+      width: 50%;
+    }
+    p:nth-child(2) .ptwo span:first-child {
+      color: #ccc;
+    }
+    p:last-child span {
+      color: #ccc;
+    }
+  }
+}
+.content {
+  padding: 16px 16px 160px;
+  height: 160px;
+  background-color: aqua;
+}
+.newptwo {
+  color: #ccc !important;
+}
+/deep/.van-button--small {
+  min-width: 60px;
+  height: 30px;
+  padding: 0 8px;
+  font-size: 12px;
+  margin: 0 5px 0 0;
+}
+.titel {
+  display: inline-block;
+  width: 65%;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  whitewhite-space: nowrap;
+}
+</style>

+ 151 - 0
src/views/adminCenter/duijiehui/parts/list.vue

@@ -0,0 +1,151 @@
+<template>
+  <div id="auditList">
+    <el-row>
+      <el-col :span="24" class="info">
+        <el-col class="newuser"><van-button type="info" size="small" @click="usersubmit()">新建对接会</van-button> </el-col>
+        <el-col :span="24" class="list" v-for="(item, index) in list" :key="index">
+          <el-col :span="20">
+            <p class="textOver">
+              <span class="titel">{{ item.title }}</span>
+            </p>
+            <p>
+              <span class="ptwo"
+                ><span>开始时间:{{ item.start_time || '暂无' }}</span></span
+              >
+            </p>
+            <p class="newptwo">
+              <span class="ptwo"><span>报名截止时间:</span>{{ item.join_end }}</span>
+            </p>
+
+            <p class="newptwo">
+              <span>审核状态:</span>{{ item.is_allowed == '0' ? '待审核' : item.is_allowed == '1' ? '审核成功' : item.is_allowed == '2' ? '审核拒绝' : '' }}
+              <span>对接会状态:</span>{{ item.status == '1' ? '开始' : item.status == '2' ? '结束' : '准备中' }}
+            </p>
+          </el-col>
+          <el-col :span="4">
+            <p><van-button type="danger" size="mini" @click="toDelete(item)">删除</van-button></p>
+            <p><van-button type="info" size="mini" @click="submit(item)">编辑</van-button></p>
+            <p><van-button type="info" size="mini" @click="shenqing(item)">申请情况</van-button></p>
+            <van-button type="primary" style="color:#fff!important;" size="mini" @click="shenhe(item)">审核</van-button>
+          </el-col>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: dock } = createNamespacedHelpers('dock');
+const { mapActions: user } = createNamespacedHelpers('user');
+export default {
+  name: 'auditList',
+  props: {},
+  components: {},
+  data: function() {
+    return {
+      list: [],
+    };
+  },
+  created() {
+    this.search();
+  },
+  methods: {
+    ...user(['query', 'delete', 'update']),
+    ...dock({ dockQuery: 'query', dockDteate: 'delete', dockUpdate: 'update' }),
+    async search() {
+      if (this.user.role == 4) {
+        let user_id = this.user.uid;
+        let res = await this.dockQuery({ user_id });
+        if (this.$checkRes(res)) {
+          this.$set(this, `list`, res.data);
+        }
+      } else {
+        let res = await this.dockQuery();
+        if (this.$checkRes(res)) {
+          this.$set(this, `list`, res.data);
+        }
+      }
+    },
+    async submit(item) {
+      this.$router.push({ path: './detail', query: { id: item.id, role: item.role } });
+    },
+    shenhe(item) {
+      this.$router.push({ path: './examine', query: { id: item.id, role: item.role } });
+    },
+    usersubmit() {
+      this.$router.push({ path: './detail' });
+    },
+    shenqing(item) {
+      this.$router.push({ path: './apply', query: { data: item, id: item.id } });
+    },
+    async toDelete(item) {
+      const res = await this.dockDteate(item.id);
+      if (this.$checkRes(res, '删除成功', res.errmsg || '删除失败')) this.search();
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.newuser {
+  float: right;
+  padding: 10px 0 10px 10px;
+}
+.info {
+  border-top: 1px solid #f5f5f5;
+
+  .list {
+    background: #fff;
+    padding: 0 10px;
+    border-bottom: 1px solid #ccc;
+    p {
+      font-size: 14px;
+      color: #000;
+      padding: 5px 0;
+    }
+    p:first-child {
+      font-size: 16px;
+    }
+    p:nth-child(2) .ptwo {
+      display: inline-block;
+      width: 50%;
+    }
+    p:nth-child(2) .ptwo span:first-child {
+      color: #ccc;
+    }
+    p:last-child span {
+    }
+  }
+}
+
+.content {
+  padding: 16px 16px 160px;
+  height: 160px;
+  background-color: aqua;
+}
+
+/deep/.van-button--small {
+  min-width: 60px;
+  height: 30px;
+  padding: 0 8px;
+  font-size: 12px;
+  margin: 0 5px 0 0;
+}
+.titel {
+  display: inline-block;
+  width: 90%;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  whitewhite-space: nowrap;
+}
+</style>

+ 92 - 0
src/views/adminCenter/enterpriseProduct/index.vue

@@ -0,0 +1,92 @@
+<template>
+  <div id="index">
+    <el-row>
+      <el-col :span="24" class="style">
+        <el-col :span="24" class="top">
+          <NavBar v-show="navShow" :title="title" :isleftarrow="isleftarrow"> </NavBar>
+        </el-col>
+        <el-col :span="24" class="main">
+          <el-col :span="24" class="main">
+            <el-col :span="24" class="one">
+              <list></list>
+            </el-col>
+          </el-col>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+import NavBar from '@/layout/common/topInfo.vue';
+import list from './parts/list.vue';
+export default {
+  name: 'index',
+  props: {},
+  components: { NavBar, list },
+  data: () => ({
+    // 头部标题
+    title: '',
+    // meta为true
+    isleftarrow: '',
+    // 返回
+    navShow: true,
+    img_path: require('@/assets/logo.png'),
+    active: 0,
+    show: false,
+    newform: {},
+  }),
+  created() {},
+  computed: {},
+  methods: {},
+  mounted() {
+    this.title = this.$route.meta.title;
+    this.isleftarrow = this.$route.meta.isleftarrow;
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.style {
+  width: 100%;
+  min-height: 667px;
+  position: relative;
+  background-color: #f9fafc;
+}
+.top {
+  height: 46px;
+  overflow: hidden;
+  position: relative;
+  z-index: 999;
+}
+.main {
+  min-height: 570px;
+  .two {
+    position: fixed;
+    top: 80%;
+
+    left: 10px;
+    z-index: 999;
+  }
+}
+/deep/.van-tab {
+  text-align: center;
+}
+/deep/.van-tabs--line .van-tabs__wrap {
+  height: 70px;
+  margin: 0 0 10px 0;
+}
+/deep/.van-tab--active {
+  color: red;
+}
+.van-icon {
+  font-size: 20px;
+}
+/deep/.van-popup--bottom {
+  bottom: 0;
+  left: 0;
+  width: 100%;
+  height: 300px;
+}
+</style>

+ 136 - 0
src/views/adminCenter/enterpriseProduct/parts/list.vue

@@ -0,0 +1,136 @@
+<template>
+  <div id="auditList">
+    <el-row>
+      <el-col :span="24" class="info">
+        <el-col :span="24" class="list" v-for="(item, index) in list" :key="index">
+          <p class="textOver">
+            <span class="titel">{{ item.name }}</span>
+            <span style="float:right;margin:0 0 0  5px;" v-if="item.status == '0'">
+              <van-button type="info" size="mini" @click="sussess(item)">审核通过</van-button>
+            </span>
+            <span style="float:right;margin:0 0 0  5px;" v-if="item.status == '0'">
+              <van-button type="info" size="mini" @click="fail(item)">审核拒绝</van-button>
+            </span>
+          </p>
+          <p class="listInfo">
+            <span>类型:</span><span>{{ item.status == '0' ? '技术' : item.status == '1' ? '产品' : '服务' }}</span>
+          </p>
+          <p class="listInfo">
+            <span>联系人:</span><span>{{ item.contact_user }}</span>
+          </p>
+          <p class="listInfo">
+            <span>审核状态:</span><span>{{ item.status == '0' ? '待审核' : item.status == '1' ? '审核成功' : item.status == '2' ? '审核拒绝' : '草稿' }}</span>
+          </p>
+          <p class="listInfo">
+            <span>简介:</span><span>{{ item.introduction }}</span>
+          </p>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: product } = createNamespacedHelpers('marketproduct');
+
+export default {
+  name: 'auditList',
+  props: {},
+  components: {},
+  data: function() {
+    return {
+      list: [{ name: '1' }],
+    };
+  },
+  created() {
+    this.searchInfo();
+  },
+  methods: {
+    ...product(['query', 'update']),
+    async searchInfo() {
+      if (this.user.role == '4') {
+        // let userid = this.user.uid;
+        let res = await this.query();
+        this.$set(this, `list`, res.data);
+      } else {
+        let res = await this.query();
+        this.$set(this, `list`, res.data);
+      }
+    },
+    async sussess(item) {
+      item.status = '1';
+      let res = await this.update(item);
+      this.$message({
+        message: '信息审核成功',
+        type: 'success',
+      });
+      this.searchInfo();
+    },
+
+    async fail(item) {
+      item.status = '2';
+      let res = await this.update(item);
+      this.$message({
+        message: '信息审核成功',
+        type: 'success',
+      });
+      this.searchInfo();
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.newuser {
+  float: right;
+  padding: 10px 0 10px 10px;
+}
+.info {
+  border-top: 1px solid #f5f5f5;
+  .list {
+    background: #fff;
+    padding: 0 10px;
+    border-bottom: 1px solid #ccc;
+    p {
+      font-size: 16px;
+      color: #000;
+      padding: 5px 0;
+    }
+    .listInfo {
+      font-size: 14px;
+      color: #000;
+      span:first-child {
+        color: #ccc;
+      }
+    }
+  }
+}
+.content {
+  padding: 16px 16px 160px;
+  height: 160px;
+  background-color: aqua;
+}
+/deep/.van-button--small {
+  min-width: 60px;
+  height: 30px;
+  padding: 0 8px;
+  font-size: 12px;
+  margin: 0 5px 0 0;
+}
+.titel {
+  display: inline-block;
+  width: 65%;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+</style>

+ 105 - 0
src/views/adminCenter/transaction/detail.vue

@@ -0,0 +1,105 @@
+<template>
+  <div id="index">
+    <el-row>
+      <el-col :span="24" class="style">
+        <el-col :span="24" class="top">
+          <NavBar v-show="navShow" :title="title" :isleftarrow="isleftarrow"> </NavBar>
+        </el-col>
+        <el-col :span="24" class="main">
+          <detaliinfo :form="form" @onSubmit="onSubmit"></detaliinfo>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import NavBar from '@/layout/common/topInfo.vue';
+import detaliinfo from '@/layout/transaction/detaliinfo.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: transaction } = createNamespacedHelpers('transaction');
+const { mapActions: productpact } = createNamespacedHelpers('productpact');
+export default {
+  name: 'index',
+  props: {},
+  components: {
+    NavBar,
+    detaliinfo, //个人信息维护
+  },
+  data: () => ({
+    // 头部标题
+    title: '',
+    // meta为true
+    isleftarrow: '',
+    // 返回
+    navShow: true,
+    // 个人信息
+    form: {},
+  }),
+  created() {
+    this.searchInfo();
+  },
+  computed: {
+    ...mapState(['user']),
+    id() {
+      return this.$route.query.id;
+    },
+    role() {
+      return this.$route.query.role;
+    },
+  },
+  methods: {
+    ...transaction({ transactionsfetch: 'fetch', transactionslist: 'query', transactionupdate: 'update' }),
+    ...productpact({ transactionQuery: 'query', productpactFetch: 'findpact', productpactUpdate: 'update' }),
+    async searchInfo() {
+      console.log(this.id);
+
+      const res = await this.productpactFetch(this.id);
+      if (this.$checkRes(res)) {
+        this.$set(this, `form`, res.data);
+      }
+    },
+    async onSubmit({ data }) {
+      const res = await this.productpactUpdate(data);
+      if (this.$checkRes(res)) {
+        data.status = '2';
+        data.id = data.transaction_id;
+        const arr = await this.transactionupdate(data);
+        if (this.$checkRes(arr)) {
+          this.$message({
+            message: '审核通过',
+            type: 'success',
+          });
+        }
+      }
+      this.$router.push({ path: './index' });
+    },
+  },
+  mounted() {
+    this.title = this.$route.meta.title;
+    this.isleftarrow = this.$route.meta.isleftarrow;
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.style {
+  width: 100%;
+  min-height: 667px;
+  position: relative;
+  background-color: #f9fafc;
+}
+.top {
+  height: 46px;
+  overflow: hidden;
+  position: relative;
+  z-index: 999;
+}
+.main {
+  min-height: 570px;
+}
+.foot {
+  position: absolute;
+  bottom: 0;
+}
+</style>

+ 92 - 0
src/views/adminCenter/transaction/index.vue

@@ -0,0 +1,92 @@
+<template>
+  <div id="index">
+    <el-row>
+      <el-col :span="24" class="style">
+        <el-col :span="24" class="top">
+          <NavBar v-show="navShow" :title="title" :isleftarrow="isleftarrow"> </NavBar>
+        </el-col>
+        <el-col :span="24" class="main">
+          <el-col :span="24" class="main">
+            <el-col :span="24" class="one">
+              <list></list>
+            </el-col>
+          </el-col>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+import NavBar from '@/layout/common/topInfo.vue';
+import list from './parts/list.vue';
+export default {
+  name: 'index',
+  props: {},
+  components: { NavBar, list },
+  data: () => ({
+    // 头部标题
+    title: '',
+    // meta为true
+    isleftarrow: '',
+    // 返回
+    navShow: true,
+    img_path: require('@/assets/logo.png'),
+    active: 0,
+    show: false,
+    newform: {},
+  }),
+  created() {},
+  computed: {},
+  methods: {},
+  mounted() {
+    this.title = this.$route.meta.title;
+    this.isleftarrow = this.$route.meta.isleftarrow;
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.style {
+  width: 100%;
+  min-height: 667px;
+  position: relative;
+  background-color: #f9fafc;
+}
+.top {
+  height: 46px;
+  overflow: hidden;
+  position: relative;
+  z-index: 999;
+}
+.main {
+  min-height: 570px;
+  .two {
+    position: fixed;
+    top: 80%;
+
+    left: 10px;
+    z-index: 999;
+  }
+}
+/deep/.van-tab {
+  text-align: center;
+}
+/deep/.van-tabs--line .van-tabs__wrap {
+  height: 70px;
+  margin: 0 0 10px 0;
+}
+/deep/.van-tab--active {
+  color: red;
+}
+.van-icon {
+  font-size: 20px;
+}
+/deep/.van-popup--bottom {
+  bottom: 0;
+  left: 0;
+  width: 100%;
+  height: 300px;
+}
+</style>

+ 0 - 0
src/views/adminCenter/transaction/parts/list.vue


Some files were not shown because too many files changed in this diff