@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
|
||||
{ |
||||
"env": { |
||||
"test": { |
||||
"presets": [ |
||||
[ |
||||
"@babel/preset-env", |
||||
{ |
||||
"targets": { |
||||
"node": "current" |
||||
} |
||||
} |
||||
] |
||||
] |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
# editorconfig.org |
||||
root = true |
||||
|
||||
[*] |
||||
indent_style = space |
||||
indent_size = 2 |
||||
end_of_line = lf |
||||
charset = utf-8 |
||||
trim_trailing_whitespace = true |
||||
insert_final_newline = true |
||||
|
||||
[*.md] |
||||
trim_trailing_whitespace = false |
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
# 前端端口 |
||||
PORT=3000 |
||||
|
||||
#nuxt前端和nginx代理接口地址 |
||||
PROXY_URL=http://192.168.1.154:8080 |
||||
|
||||
# nginx中使用的前端地址 |
||||
NUXT_HOST=http://192.168.1.154:3000 |
||||
|
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
NODE_ENV = 'production' |
||||
|
||||
VUE_APP_TITLE = 'production' |
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
NODE_ENV = 'production' |
||||
|
||||
VUE_APP_TITLE = 'test' |
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
module.exports = { |
||||
root: true, |
||||
env: { |
||||
browser: true, |
||||
node: true |
||||
}, |
||||
parserOptions: { |
||||
parser: '@babel/eslint-parser', |
||||
requireConfigFile: false |
||||
}, |
||||
extends: ['@nuxtjs', 'plugin:nuxt/recommended', 'prettier'], |
||||
plugins: [], |
||||
// add your custom rules here
|
||||
rules: { |
||||
'no-console': 'off' |
||||
} |
||||
}; |
@ -0,0 +1,92 @@
@@ -0,0 +1,92 @@
|
||||
# Created by .ignore support plugin (hsz.mobi) |
||||
### Node template |
||||
# Logs |
||||
/logs |
||||
*.log |
||||
npm-debug.log* |
||||
yarn-debug.log* |
||||
yarn-error.log* |
||||
|
||||
# Runtime data |
||||
pids |
||||
*.pid |
||||
*.seed |
||||
*.pid.lock |
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover |
||||
lib-cov |
||||
|
||||
# Coverage directory used by tools like istanbul |
||||
coverage |
||||
|
||||
# nyc test coverage |
||||
.nyc_output |
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) |
||||
.grunt |
||||
|
||||
# Bower dependency directory (https://bower.io/) |
||||
bower_components |
||||
|
||||
# node-waf configuration |
||||
.lock-wscript |
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html) |
||||
build/Release |
||||
|
||||
# Dependency directories |
||||
node_modules/ |
||||
jspm_packages/ |
||||
|
||||
# TypeScript v1 declaration files |
||||
typings/ |
||||
|
||||
# Optional npm cache directory |
||||
.npm |
||||
|
||||
# Optional eslint cache |
||||
.eslintcache |
||||
|
||||
# Optional REPL history |
||||
.node_repl_history |
||||
|
||||
# Output of 'npm pack' |
||||
*.tgz |
||||
|
||||
# Yarn Integrity file |
||||
.yarn-integrity |
||||
|
||||
# dotenv environment variables file |
||||
.env |
||||
|
||||
# parcel-bundler cache (https://parceljs.org/) |
||||
.cache |
||||
|
||||
# next.js build output |
||||
.next |
||||
|
||||
# nuxt.js build output |
||||
.nuxt |
||||
|
||||
# Nuxt generate |
||||
dist |
||||
|
||||
# vuepress build output |
||||
.vuepress/dist |
||||
|
||||
# Serverless directories |
||||
.serverless |
||||
|
||||
# IDE / Editor |
||||
.idea |
||||
|
||||
# Service worker |
||||
sw.* |
||||
|
||||
# macOS |
||||
.DS_Store |
||||
|
||||
# Vim swap files |
||||
*.swp |
||||
|
||||
.idea |
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh |
||||
. "$(dirname "$0")/_/husky.sh" |
||||
. "$(dirname "$0")/common.sh" |
||||
|
||||
npx lint-staged |
@ -0,0 +1,100 @@
@@ -0,0 +1,100 @@
|
||||
### |
||||
# Place your Prettier ignore content here |
||||
|
||||
### |
||||
# .gitignore content is duplicated here due to https://github.com/prettier/prettier/issues/8506 |
||||
|
||||
# Created by .ignore support plugin (hsz.mobi) |
||||
### Node template |
||||
# Logs |
||||
/logs |
||||
*.log |
||||
npm-debug.log* |
||||
yarn-debug.log* |
||||
yarn-error.log* |
||||
|
||||
# Runtime data |
||||
pids |
||||
*.pid |
||||
*.seed |
||||
*.pid.lock |
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover |
||||
lib-cov |
||||
|
||||
# Coverage directory used by tools like istanbul |
||||
coverage |
||||
|
||||
# nyc test coverage |
||||
.nyc_output |
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) |
||||
.grunt |
||||
|
||||
# Bower dependency directory (https://bower.io/) |
||||
bower_components |
||||
|
||||
# node-waf configuration |
||||
.lock-wscript |
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html) |
||||
build/Release |
||||
|
||||
# Dependency directories |
||||
src/node_modules/ |
||||
jspm_packages/ |
||||
|
||||
# TypeScript v1 declaration files |
||||
typings/ |
||||
|
||||
# Optional npm cache directory |
||||
.npm |
||||
|
||||
# Optional eslint cache |
||||
.eslintcache |
||||
|
||||
# Optional REPL history |
||||
.node_repl_history |
||||
|
||||
# Output of 'npm pack' |
||||
*.tgz |
||||
|
||||
# Yarn Integrity file |
||||
.yarn-integrity |
||||
|
||||
# dotenv environment variables file |
||||
.env |
||||
|
||||
# parcel-bundler cache (https://parceljs.org/) |
||||
.cache |
||||
|
||||
# next.js build output |
||||
.next |
||||
|
||||
# nuxt.js build output |
||||
.nuxt |
||||
|
||||
# Nuxt generate |
||||
dist |
||||
|
||||
# vuepress build output |
||||
.vuepress/dist |
||||
|
||||
# Serverless directories |
||||
.serverless |
||||
|
||||
# IDE / Editor |
||||
.idea |
||||
|
||||
# Service worker |
||||
sw.* |
||||
|
||||
# macOS |
||||
.DS_Store |
||||
|
||||
# Vim swap files |
||||
*.swp |
||||
|
||||
|
||||
**/node_modules/** |
||||
.nuxt/**/* |
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
{ |
||||
"semi": true, |
||||
"singleQuote": true, |
||||
"trailingComma": "none" |
||||
} |
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
# 本地开发 |
||||
## 使用nginx代理 |
||||
1. 安装docker |
||||
2. 登录公司镜像库, user: dnurse_dev, pass:Dnurse@20171201 |
||||
```shell |
||||
docker login repo.dnurse.cn |
||||
``` |
||||
3. 修改.env中的环境变量为本机信息 |
||||
4. 运行命令 |
||||
```shell |
||||
docker-compose up -d # 启动并进入后台 |
||||
docker-compose restart # 重启 |
||||
docker-compose stop # 停止 |
||||
docker-compose rm -f # 删除 |
||||
|
||||
cd src #进入代码目录 |
||||
npm run start # 启动前端 |
||||
``` |
||||
4. 访问 http://127.0.0.1/ |
||||
|
||||
|
||||
## 不用代理 |
||||
1. 修改.env中的环境变量为本机信息 |
||||
2. 运行命令 |
||||
```shell |
||||
cd src #进入代码目录 |
||||
npm run start # 启动前端 |
||||
``` |
||||
|
||||
3.访问 http://127.0.0.1/ |
@ -0,0 +1,133 @@
@@ -0,0 +1,133 @@
|
||||
#!/bin/bash |
||||
|
||||
# ---------------------- |
||||
# KUDU Deployment Script |
||||
# Version: 1.0.17 |
||||
# ---------------------- |
||||
|
||||
# Helpers |
||||
# ------- |
||||
|
||||
exitWithMessageOnError () { |
||||
if [ ! $? -eq 0 ]; then |
||||
echo "An error has occurred during web site deployment." |
||||
echo $1 |
||||
exit 1 |
||||
fi |
||||
} |
||||
|
||||
# Prerequisites |
||||
# ------------- |
||||
|
||||
# Verify node.js installed |
||||
hash node 2>/dev/null |
||||
exitWithMessageOnError "Missing node.js executable, please install node.js, if already installed make sure it can be reached from current environment." |
||||
|
||||
# Setup |
||||
# ----- |
||||
|
||||
SCRIPT_DIR="${BASH_SOURCE[0]%\\*}" |
||||
SCRIPT_DIR="${SCRIPT_DIR%/*}" |
||||
ARTIFACTS=$SCRIPT_DIR/../artifacts |
||||
KUDU_SYNC_CMD=${KUDU_SYNC_CMD//\"} |
||||
|
||||
if [[ ! -n "$DEPLOYMENT_SOURCE" ]]; then |
||||
DEPLOYMENT_SOURCE=$SCRIPT_DIR |
||||
fi |
||||
|
||||
if [[ ! -n "$NEXT_MANIFEST_PATH" ]]; then |
||||
NEXT_MANIFEST_PATH=$ARTIFACTS/manifest |
||||
|
||||
if [[ ! -n "$PREVIOUS_MANIFEST_PATH" ]]; then |
||||
PREVIOUS_MANIFEST_PATH=$NEXT_MANIFEST_PATH |
||||
fi |
||||
fi |
||||
|
||||
if [[ ! -n "$DEPLOYMENT_TARGET" ]]; then |
||||
DEPLOYMENT_TARGET=$ARTIFACTS/wwwroot |
||||
else |
||||
KUDU_SERVICE=true |
||||
fi |
||||
|
||||
if [[ ! -n "$KUDU_SYNC_CMD" ]]; then |
||||
# Install kudu sync |
||||
echo Installing Kudu Sync |
||||
npm install kudusync -g --silent |
||||
exitWithMessageOnError "npm failed" |
||||
|
||||
if [[ ! -n "$KUDU_SERVICE" ]]; then |
||||
# In case we are running locally this is the correct location of kuduSync |
||||
KUDU_SYNC_CMD=kuduSync |
||||
else |
||||
# In case we are running on kudu service this is the correct location of kuduSync |
||||
KUDU_SYNC_CMD=$APPDATA/npm/node_modules/kuduSync/bin/kuduSync |
||||
fi |
||||
fi |
||||
|
||||
# Node Helpers |
||||
# ------------ |
||||
|
||||
selectNodeVersion () { |
||||
if [[ -n "$KUDU_SELECT_NODE_VERSION_CMD" ]]; then |
||||
SELECT_NODE_VERSION="$KUDU_SELECT_NODE_VERSION_CMD \"$DEPLOYMENT_SOURCE\" \"$DEPLOYMENT_TARGET\" \"$DEPLOYMENT_TEMP\"" |
||||
eval $SELECT_NODE_VERSION |
||||
exitWithMessageOnError "select node version failed" |
||||
|
||||
if [[ -e "$DEPLOYMENT_TEMP/__nodeVersion.tmp" ]]; then |
||||
NODE_EXE=`cat "$DEPLOYMENT_TEMP/__nodeVersion.tmp"` |
||||
exitWithMessageOnError "getting node version failed" |
||||
fi |
||||
|
||||
if [[ -e "$DEPLOYMENT_TEMP/__npmVersion.tmp" ]]; then |
||||
NPM_JS_PATH=`cat "$DEPLOYMENT_TEMP/__npmVersion.tmp"` |
||||
exitWithMessageOnError "getting npm version failed" |
||||
fi |
||||
|
||||
if [[ ! -n "$NODE_EXE" ]]; then |
||||
NODE_EXE=node |
||||
fi |
||||
|
||||
NPM_CMD="\"$NODE_EXE\" \"$NPM_JS_PATH\"" |
||||
else |
||||
NPM_CMD=npm |
||||
NODE_EXE=node |
||||
fi |
||||
} |
||||
|
||||
################################################################################################################################## |
||||
# Deployment |
||||
# ---------- |
||||
|
||||
echo Handling node.js deployment. |
||||
|
||||
# 1. KuduSync |
||||
if [[ "$IN_PLACE_DEPLOYMENT" -ne "1" ]]; then |
||||
"$KUDU_SYNC_CMD" -v 50 -f "$DEPLOYMENT_SOURCE" -t "$DEPLOYMENT_TARGET" -n "$NEXT_MANIFEST_PATH" -p "$PREVIOUS_MANIFEST_PATH" -i ".git;.hg;.deployment;deploy.sh" |
||||
exitWithMessageOnError "Kudu Sync failed" |
||||
fi |
||||
|
||||
# 2. Select node version |
||||
selectNodeVersion |
||||
|
||||
# 3. Install npm packages |
||||
if [ -e "$DEPLOYMENT_TARGET/package.json" ]; then |
||||
cd "$DEPLOYMENT_TARGET" |
||||
echo "Running $NPM_CMD install --production" |
||||
eval $NPM_CMD install --production |
||||
exitWithMessageOnError "npm failed" |
||||
cd - > /dev/null |
||||
fi |
||||
|
||||
# 4. Use composer |
||||
echo "composer:$DEPLOYMENT_TARGET" |
||||
if [ -e "$DEPLOYMENT_TARGET/composer.json" ]; then |
||||
echo "Found composer.json" |
||||
echo "COMPOSER_ARGS:$COMPOSER_ARGS" |
||||
pushd "$DEPLOYMENT_TARGET" |
||||
php composer.phar install $COMPOSER_ARGS |
||||
exitWithMessageOnError "Composer install failed" |
||||
popd |
||||
fi |
||||
|
||||
################################################################################################################################## |
||||
echo "Finished successfully." |
@ -0,0 +1,43 @@
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env bash |
||||
# $1 git url |
||||
# $2 artifact path |
||||
# $3 save dir |
||||
# $4 build name |
||||
# $5 source dir |
||||
# $3 comment |
||||
|
||||
GitUrl=$1 |
||||
ArtifactPath=$2 |
||||
SaveDir=$3 |
||||
BuildName=$4 |
||||
SourcePath=$5 |
||||
Comment=$6 |
||||
|
||||
RepoDir=$(dirname ${ArtifactPath}) |
||||
RepoPath="${RepoDir}/repo/${BuildName}/${SaveDir}" |
||||
ScriptDir=$(dirname ${SourcePath}) |
||||
|
||||
cd ${RepoPath} |
||||
|
||||
pwd |
||||
echo $SourcePath |
||||
echo $RepoPath |
||||
echo $ScriptDir |
||||
|
||||
echo "clean old:" |
||||
|
||||
ls -A | grep -v '.git' | xargs rm -rf {} |
||||
|
||||
echo "copy new:" |
||||
cp -R ${SourcePath}/src/. . |
||||
#cp -R ${SourcePath}/app_data . |
||||
#cp -R ${SourcePath}/bin . |
||||
#cp -R ${SourcePath}/ini . |
||||
#cp -R ${SourcePath}/PostDeploymentActions . |
||||
|
||||
|
||||
git add -f . |
||||
|
||||
git commit -a -m "TFS:${Comment}" |
||||
|
||||
git push -u origin --all |
@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env bash |
||||
# $1 git url |
||||
# $2 artifact path |
||||
# $3 save dir |
||||
# $4 build name |
||||
|
||||
GitUrl=$1 |
||||
ArtifactPath=$2 |
||||
SaveDir=$3 |
||||
BuildName=$4 |
||||
|
||||
RepoDir=$(dirname ${ArtifactPath}) |
||||
RepoPath="${RepoDir}/repo/${BuildName}" |
||||
|
||||
mkdir -p ${RepoPath} |
||||
|
||||
cd ${RepoPath} |
||||
|
||||
if [ ! -e ${SaveDir} ] |
||||
then |
||||
git clone $1 ${SaveDir} |
||||
|
||||
cd ${SaveDir} |
||||
git config user.name 'autouser' |
||||
git config user.email 'autouser@dnurse.cn' |
||||
else |
||||
cd ${SaveDir} |
||||
git reset --hard |
||||
git clean -df |
||||
git pull |
||||
fi |
@ -0,0 +1,56 @@
@@ -0,0 +1,56 @@
|
||||
{ |
||||
"name": "novo-pc", |
||||
"version": "1.0.0", |
||||
"private": true, |
||||
"scripts": { |
||||
"dev": "nuxt", |
||||
"build": "cross-env process.env.VUE_APP_TITLE=test nuxt build", |
||||
"build:prod": "cross-env process.env.VUE_APP_TITLE=production nuxt build", |
||||
"start": "node ./server.js", |
||||
"start_prod": "NODE_ENV=production node ./server.js", |
||||
"lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .", |
||||
"lint:js:fix": "eslint --ext \".js,.vue\" --ignore-path .gitignore --fix .", |
||||
"format": "prettier --write \"./**/*.vue\" \"./**/*.js\" \"./**/*.scss\" ", |
||||
"format1": "prettier ", |
||||
"lint:prettier": "prettier --check \"./**/*.vue\" \"./**/*.js\"", |
||||
"lint": "npm run lint:js && npm run lint:prettier", |
||||
"lintfix": "prettier --write --list-different \"./**/*.vue\" \"./**/*.js\" && npm run lint:js:fix" |
||||
}, |
||||
"husky": { |
||||
"hooks": { |
||||
"pre-commit": "lint-staged" |
||||
} |
||||
}, |
||||
"lint-staged": { |
||||
"*.{js,vue}": "eslint --cache", |
||||
"*.**": "prettier --check --ignore-unknown" |
||||
}, |
||||
"dependencies": { |
||||
"@nuxtjs/axios": "^5.13.6", |
||||
"@nuxtjs/robots": "^2.5.0", |
||||
"@nuxtjs/style-resources": "^1.2.1", |
||||
"core-js": "^3.19.3", |
||||
"element-ui": "^2.15.6", |
||||
"koa": "^2.13.4", |
||||
"moment": "^2.29.1", |
||||
"nuxt": "^2.15.8", |
||||
"vue": "^2.6.14", |
||||
"vue-qr": "^3.2.2" |
||||
}, |
||||
"devDependencies": { |
||||
"@nuxtjs/eslint-config": "^6.0.1", |
||||
"@nuxtjs/eslint-module": "^3.0.2", |
||||
"@nuxtjs/proxy": "^2.1.0", |
||||
"cross-env": "^7.0.3", |
||||
"eslint": "^7.29.0", |
||||
"eslint-config-prettier": "^8.3.0", |
||||
"eslint-plugin-nuxt": "^2.0.0", |
||||
"eslint-plugin-vue": "^7.12.1", |
||||
"husky": "^7.0.4", |
||||
"lint-staged": "^12.1.3", |
||||
"node-sass": "^6.0.1", |
||||
"prettier": "^2.5.1", |
||||
"qs": "^6.10.2", |
||||
"sass-loader": "^10.2.0" |
||||
} |
||||
} |
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash |
||||
# $1 git url |
||||
# $2 artifact path |
||||
|
||||
|
||||
SOURCE=$1 |
||||
DEST=$2 |
||||
|
||||
cp -R ${SOURCE}/src ${DEST} |
||||
rm -rf ${DEST}/src/node_modules |
@ -0,0 +1,62 @@
@@ -0,0 +1,62 @@
|
||||
#user nobody; |
||||
worker_processes auto; |
||||
|
||||
#error_log logs/error.log; |
||||
#error_log logs/error.log notice; |
||||
#error_log logs/error.log info; |
||||
|
||||
#pid run/nginx.pid; |
||||
|
||||
|
||||
events { |
||||
worker_connections 32768; |
||||
accept_mutex off; |
||||
multi_accept on; |
||||
use epoll; |
||||
} |
||||
|
||||
|
||||
http { |
||||
include mime.types; |
||||
default_type application/octet-stream; |
||||
|
||||
#log_format main '$remote_addr - $remote_user [$time_local] "$request" ' |
||||
# '$status $body_bytes_sent "$http_referer" ' |
||||
# '"$http_user_agent" "$http_x_forwarded_for"'; |
||||
|
||||
#access_log logs/access.log main; |
||||
|
||||
log_format logstash '$http_host $server_addr $remote_addr [$time_local] "$request" ' |
||||
'$request_body $status $body_bytes_sent "$http_referer" "$http_user_agent" ' |
||||
'$request_time $upstream_response_time $http_x_user_sn $http_x_log_id'; |
||||
#tcp_nopush on; |
||||
|
||||
sendfile off; |
||||
|
||||
keepalive_timeout 5; |
||||
keepalive_requests 500; |
||||
|
||||
client_header_timeout 10; |
||||
client_body_timeout 10; |
||||
reset_timedout_connection on; |
||||
send_timeout 10; |
||||
|
||||
limit_conn_zone $binary_remote_addr zone=addr:5m; |
||||
limit_conn addr 500; |
||||
|
||||
gzip on; |
||||
gzip_disable "msie6"; |
||||
gzip_proxied any; |
||||
gzip_min_length 1000; |
||||
gzip_comp_level 6; |
||||
gzip_types text/plain text/css application |
||||
|
||||
#keepalive_timeout 0; |
||||
client_max_body_size 100m; |
||||
|
||||
server_tokens off; |
||||
|
||||
include /etc/nginx/sites-enabled/*; |
||||
} |
||||
#daemon off; |
||||
|
@ -0,0 +1,77 @@
@@ -0,0 +1,77 @@
|
||||
server { |
||||
listen 80; ## listen for ipv4; this line is default and implied |
||||
listen [::]:80 default ipv6only=on; ## listen for ipv6 |
||||
|
||||
root /var/www/html/public; |
||||
index index.php index.html index.htm; |
||||
|
||||
access_log /var/log/nginx/access.log logstash; |
||||
|
||||
# Make site accessible from http://localhost/ |
||||
server_name _; |
||||
|
||||
# Disable sendfile as per https://docs.vagrantup.com/v2/synced-folders/virtualbox.html |
||||
sendfile off; |
||||
|
||||
client_max_body_size 64M; |
||||
|
||||
|
||||
# deny access to . files, for security |
||||
# |
||||
location ~ /\. { |
||||
log_not_found off; |
||||
deny all; |
||||
} |
||||
|
||||
location ^~ /.well-known { |
||||
allow all; |
||||
auth_basic off; |
||||
} |
||||
|
||||
add_header X-Frame-Options "SAMEORIGIN"; |
||||
add_header X-XSS-Protection "1; mode=block"; |
||||
add_header X-Content-Type-Options "nosniff"; |
||||
|
||||
index index.html index.htm index.php; |
||||
|
||||
charset utf-8; |
||||
|
||||
rewrite ^/uploadfile/ https://sancdiabeteswebn201.blob.core.chinacloudapi.cn$request_uri? permanent; |
||||
|
||||
set_by_lua $api_host_env 'return os.getenv("API_HOST")'; |
||||
set_by_lua $nuxt_host_env 'return os.getenv("NUXT_HOST")'; |
||||
|
||||
location /web { |
||||
proxy_pass ${api_host_env}; |
||||
proxy_http_version 1.1; |
||||
proxy_set_header Upgrade $http_upgrade; |
||||
proxy_set_header Connection "Upgrade"; |
||||
} |
||||
|
||||
location ^~ / { |
||||
proxy_pass ${nuxt_host_env}; |
||||
proxy_http_version 1.1; |
||||
proxy_set_header Upgrade $http_upgrade; |
||||
proxy_set_header Connection "Upgrade"; |
||||
} |
||||
|
||||
location = /favicon.ico { access_log off; log_not_found off; } |
||||
location = /robots.txt { access_log off; log_not_found off; } |
||||
|
||||
error_page 404 /index.php; |
||||
|
||||
location ~ \.php$ { |
||||
fastcgi_pass unix:/var/run/php-fpm.sock; |
||||
fastcgi_index index.php; |
||||
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; |
||||
include fastcgi_params; |
||||
} |
||||
|
||||
location ~ /\.(?!well-known).* { |
||||
deny all; |
||||
} |
||||
|
||||
location ~* \.(jpg|jpeg|gif|png|css|js|ico|webp|tiff|ttf|svg)$ { |
||||
expires 5d; |
||||
} |
||||
} |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
opcache.enable=1 |
||||
opcache.enable_cli=0 |
||||
opcache.memory_consumption=512 |
||||
opcache.interned_strings_buffer=64 |
||||
opcache.max_accelerated_files=20000 |
||||
opcache.save_comments=1 |
||||
opcache.fast_shutdown=1 |
||||
expose_php=false |
||||
opcache.validate_timestamps=1 |
||||
opcache.file_cache=/tmp |
||||
|
||||
|
||||
xdebug.remote_enable=1 |
||||
xdebug.remote_log=/tmp/xdebug.log |
||||
xdebug.remote_autostart=false |
||||
xdebug.remote_port=9000 |
||||
xdebug.remote_host=192.168.1.37 |
||||
xdebug.idekey="dnurse" |
||||
xdebug.profiler_output_dir=/var/www/html/public |
||||
xdebug.profiler_enable_trigger=1 |
||||
|
||||
;http 请求后加参数 XDEBUG_SESSION_START=dnurse |
||||
;cli 先设置变量 export XDEBUG_CONFIG="idekey=dnurse" |
||||
;cli 先设置变量 export PHP_IDE_CONFIG="serverName=novo-open" |
||||
;extension=xhprof.so |
||||
;xhprof.output_dir=/var/www/html/public |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
[program:nginx] |
||||
command=/var/www/template/nginx/run-nginx.sh |
||||
autostart=true |
||||
autorestart=true |
||||
priority=6 |
||||
stdout_events_enabled=true |
||||
stderr_events_enabled=true |
||||
stdout_logfile=/dev/stdout |
||||
stdout_logfile_maxbytes=0 |
||||
stderr_logfile=/dev/stderr |
||||
stderr_logfile_maxbytes=0 |
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
[program:php-fpm] |
||||
command = /usr/local/sbin/php-fpm --nodaemonize --fpm-config /usr/local/etc/php-fpm.d/www.conf |
||||
autostart=true |
||||
autorestart=true |
||||
priority=5 |
||||
stdout_logfile=/dev/stdout |
||||
stdout_logfile_maxbytes=0 |
||||
stderr_logfile=/dev/stderr |
||||
stderr_logfile_maxbytes=0 |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
[program:nginx] |
||||
command=/var/www/html/api/scripts/queue.sh |
||||
user =nginx |
||||
autostart=true |
||||
autorestart=true |
||||
priority=6 |
||||
stdout_events_enabled=true |
||||
stderr_events_enabled=true |
||||
stdout_logfile=/dev/stdout |
||||
stdout_logfile_maxbytes=0 |
||||
stderr_logfile=/dev/stderr |
||||
stderr_logfile_maxbytes=0 |
@ -0,0 +1,74 @@
@@ -0,0 +1,74 @@
|
||||
server { |
||||
listen 80; ## listen for ipv4; this line is default and implied |
||||
listen [::]:80 default ipv6only=on; ## listen for ipv6 |
||||
|
||||
root /var/www/html/public; |
||||
index index.php index.html index.htm; |
||||
|
||||
access_log /var/log/nginx/access.log logstash; |
||||
|
||||
# Make site accessible from http://localhost/ |
||||
server_name _; |
||||
|
||||
# Disable sendfile as per https://docs.vagrantup.com/v2/synced-folders/virtualbox.html |
||||
sendfile off; |
||||
|
||||
client_max_body_size 64M; |
||||
|
||||
|
||||
# deny access to . files, for security |
||||
# |
||||
location ~ /\. { |
||||
log_not_found off; |
||||
deny all; |
||||
} |
||||
|
||||
location ^~ /.well-known { |
||||
allow all; |
||||
auth_basic off; |
||||
} |
||||
|
||||
add_header X-Frame-Options "SAMEORIGIN"; |
||||
add_header X-XSS-Protection "1; mode=block"; |
||||
add_header X-Content-Type-Options "nosniff"; |
||||
|
||||
index index.html index.htm index.php; |
||||
|
||||
charset utf-8; |
||||
|
||||
rewrite ^/uploadfile/ https://sancdiabeteswebn201.blob.core.chinacloudapi.cn${DOLLAR}request_uri? permanent; |
||||
|
||||
location /web { |
||||
proxy_pass ${PROXY_URL}; |
||||
proxy_http_version 1.1; |
||||
proxy_set_header Upgrade ${DOLLAR}http_upgrade; |
||||
proxy_set_header Connection "Upgrade"; |
||||
} |
||||
|
||||
location ^~ / { |
||||
proxy_pass ${NUXT_HOST}; |
||||
proxy_http_version 1.1; |
||||
proxy_set_header Upgrade ${DOLLAR}http_upgrade; |
||||
proxy_set_header Connection "Upgrade"; |
||||
} |
||||
|
||||
location = /favicon.ico { access_log off; log_not_found off; } |
||||
location = /robots.txt { access_log off; log_not_found off; } |
||||
|
||||
error_page 404 /index.php; |
||||
|
||||
location ~ \.php${DOLLAR} { |
||||
fastcgi_pass unix:/var/run/php-fpm.sock; |
||||
fastcgi_index index.php; |
||||
fastcgi_param SCRIPT_FILENAME ${DOLLAR}realpath_root${DOLLAR}fastcgi_script_name; |
||||
include fastcgi_params; |
||||
} |
||||
|
||||
location ~ /\.(?!well-known).* { |
||||
deny all; |
||||
} |
||||
|
||||
location ~* \.(jpg|jpeg|gif|png|css|js|ico|webp|tiff|ttf|svg)${DOLLAR} { |
||||
expires 5d; |
||||
} |
||||
} |
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash |
||||
export DOLLAR='$' |
||||
envsubst < /var/www/template/nginx/default.conf > /etc/nginx/sites-available/default.conf |
||||
/usr/sbin/nginx -g "daemon off;" |
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
version: '2' |
||||
services: |
||||
php-fpm: |
||||
image: repo.dnurse.cn/library/nginx-php-7.4-xdebug:v1.2 |
||||
ports: |
||||
- '80:80' |
||||
env_file: |
||||
- .env |
||||
environment: |
||||
SKIP_COMPOSER: 'true' |
||||
SKIP_CHOWN: 'true' |
||||
ERRORS: '1' |
||||
ENABLE_XDEBUG: '1' |
||||
volumes: |
||||
- ./dev/conf/supervisor/nginx.conf:/etc/supervisor/conf.d/nginx.conf |
||||
- ./dev/conf/supervisor/php-fpm.conf:/etc/supervisor/conf.d/php-fpm.conf |
||||
# - ./dev/conf/nginx:/etc/nginx/sites-available |
||||
- ./dev/conf/template:/var/www/template |
||||
- ./src:/var/www/html |
||||
# - ./dev/conf/nginx.conf:/etc/nginx/nginx.conf |
||||
- ./dev/conf/php/opcache.ini:/usr/local/etc/php/conf.d/opcache.ini |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env bash |
||||
curDirName=$(basename `pwd`) |
||||
dockerId="${curDirName}_php-fpm_1" |
||||
|
||||
hasPod=$(docker ps | grep ${dockerId} | wc -l) |
||||
if [[ ${hasPod} -eq 0 ]]; then |
||||
curDirName="${curDirName//-/}" |
||||
dockerId="${curDirName}_php-fpm_1" |
||||
fi |
||||
|
||||
docker exec -it $dockerId bash |
||||
|
@ -0,0 +1,120 @@
@@ -0,0 +1,120 @@
|
||||
/* eslint-disable nuxt/no-cjs-in-config */ |
||||
|
||||
module.exports = { |
||||
srcDir: './src', |
||||
loading: false, |
||||
// Global page headers: https://go.nuxtjs.dev/config-head
|
||||
head: { |
||||
title: '糖尿病网 - 服务糖尿病患者的知识社区', |
||||
htmlAttrs: { |
||||
lang: 'en' |
||||
}, |
||||
meta: [ |
||||
{ charset: 'utf-8' }, |
||||
{ |
||||
name: 'viewport', |
||||
content: |
||||
'initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,width=device-width,user-scalable=no,viewport-fit=cover' |
||||
}, |
||||
{ |
||||
hid: 'description', |
||||
name: 'description', |
||||
content: |
||||
'糖尿病网,服务糖尿病患者的知识平台!以帮助糖尿病患者科学管理身体为目标,提供最新鲜、专业的健康管理资讯。' |
||||
}, |
||||
{ |
||||
hid: 'keywords', |
||||
name: 'keywords', |
||||
content: |
||||
'糖尿病,健康管理,控糖,血糖,血糖管理,科普,知识社区,专业资讯,干货,糖友,疾病,公益,有用,深度,饮食知识' |
||||
}, |
||||
{ name: 'format-detection', content: 'telephone=no' } |
||||
], |
||||
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }], |
||||
script: [ |
||||
{ |
||||
src: 'https://hm.baidu.com/hm.js?c17780012e32ae356918a39fe159755e' |
||||
} |
||||
] |
||||
}, |
||||
router: { |
||||
middleware: ['device'] |
||||
}, |
||||
// Global CSS: https://go.nuxtjs.dev/config-css
|
||||
css: [ |
||||
'element-ui/lib/theme-chalk/index.css', |
||||
'video.js/dist/video-js.css', |
||||
'vue-video-player/src/custom-theme.css' |
||||
], |
||||
|
||||
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
|
||||
plugins: [ |
||||
'@/plugins/element-ui', |
||||
'@/plugins/axios', |
||||
'@/plugins/filters', |
||||
{ src: '@/plugins/vueqr', ssr: true }, |
||||
{ src: '@/plugins/video', ssr: false }, |
||||
{ src: '~/plugins/swiper.js', ssr: false }, |
||||
{ src: '~/plugins/wx-share.js', ssr: false }, |
||||
{ src: '~/plugins/baidu.js', ssr: false } |
||||
], |
||||
|
||||
// Auto import components: https://go.nuxtjs.dev/config-components
|
||||
components: true, |
||||
|
||||
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
|
||||
buildModules: |
||||
process.env.NODE_ENV !== 'production' ? ['@nuxtjs/eslint-module'] : [], |
||||
styleResources: { |
||||
scss: ['~/assets/css/common.scss'] |
||||
}, |
||||
// Modules: https://go.nuxtjs.dev/config-modules
|
||||
modules: ['@nuxtjs/axios', '@nuxtjs/style-resources', '@nuxtjs/robots'], |
||||
axios: { |
||||
prefix: '/web', |
||||
credentials: true, |
||||
proxy: process.env.NODE_ENV !== 'production', |
||||
timeout: 2000, |
||||
debug: false |
||||
}, |
||||
proxy: { |
||||
'/web/': process.env.PROXY_URL |
||||
}, |
||||
|
||||
robots: { |
||||
UserAgent: '*', |
||||
Disallow: '/user' |
||||
}, |
||||
|
||||
publicRuntimeConfig: { |
||||
axios: { |
||||
browserBaseURL: |
||||
process.env.NODE_ENV !== 'production' |
||||
? null |
||||
: process.env.BROWSER_BASE_URL + '/web' |
||||
} |
||||
}, |
||||
|
||||
privateRuntimeConfig: { |
||||
axios: { |
||||
baseURL: |
||||
process.env.NODE_ENV !== 'production' |
||||
? null |
||||
: process.env.PROXY_URL + '/web' |
||||
} |
||||
}, |
||||
|
||||
// Build Configuration: https://go.nuxtjs.dev/config-build
|
||||
build: { |
||||
transpile: [/^element-ui/] |
||||
}, |
||||
server: { |
||||
port: process.env.PORT || 3000, // default: 3000
|
||||
// host: '0.0.0.0' // default: localhost
|
||||
host: 'localhost' |
||||
}, |
||||
telemetry: false, |
||||
env: { |
||||
VUE_APP_TITLE: process.env.VUE_APP_TITLE |
||||
} |
||||
}; |
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
{ |
||||
"name": "novo-pc", |
||||
"version": "1.0.0", |
||||
"private": true, |
||||
"scripts": { |
||||
"dev": "nuxt", |
||||
"build": "cross-env process.env.VUE_APP_TITLE=test nuxt build", |
||||
"build:prod": "cross-env process.env.VUE_APP_TITLE=production nuxt build", |
||||
"start": "node ./server.js", |
||||
"start_prod": "NODE_ENV=production node ./server.js", |
||||
"lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .", |
||||
"lint:js:fix": "eslint --ext \".js,.vue\" --ignore-path .gitignore --fix .", |
||||
"format": "prettier --write \"./**/*.vue\" \"./**/*.js\" \"./**/*.scss\" ", |
||||
"format1": "prettier ", |
||||
"lint:prettier": "prettier --check \"./**/*.vue\" \"./**/*.js\"", |
||||
"lint": "npm run lint:js && npm run lint:prettier", |
||||
"lintfix": "prettier --write --list-different \"./**/*.vue\" \"./**/*.js\" && npm run lint:js:fix", |
||||
"prepare": "husky install", |
||||
"generate": "nuxt generate" |
||||
}, |
||||
"husky": { |
||||
"hooks": { |
||||
"pre-commit": "lint-staged" |
||||
} |
||||
}, |
||||
"lint-staged": { |
||||
"*.{js,vue}": "eslint --cache", |
||||
"*.**": "prettier --check --ignore-unknown" |
||||
}, |
||||
"dependencies": { |
||||
"@nuxtjs/axios": "^5.13.6", |
||||
"@nuxtjs/robots": "^2.5.0", |
||||
"@nuxtjs/style-resources": "^1.2.1", |
||||
"core-js": "^3.19.3", |
||||
"dotenv": "^16.5.0", |
||||
"element-ui": "^2.15.6", |
||||
"koa": "^2.13.4", |
||||
"moment": "^2.29.1", |
||||
"nuxt": "^2.15.8", |
||||
"vue": "^2.6.14", |
||||
"vue-awesome-swiper": "^3.1.3", |
||||
"vue-qr": "^3.2.2", |
||||
"vue-server-renderer": "^2.6.14", |
||||
"vue-template-compiler": "^2.6.14", |
||||
"vue-video-player": "^5.0.2", |
||||
"webpack": "^4.46.0", |
||||
"weixin-js-sdk": "^1.6.0" |
||||
}, |
||||
"devDependencies": { |
||||
"@nuxtjs/eslint-config": "^6.0.1", |
||||
"@nuxtjs/eslint-module": "^3.0.2", |
||||
"@nuxtjs/proxy": "^2.1.0", |
||||
"cross-env": "^7.0.3", |
||||
"eslint": "^7.29.0", |
||||
"eslint-config-prettier": "^8.3.0", |
||||
"eslint-plugin-nuxt": "^2.0.0", |
||||
"eslint-plugin-vue": "^7.12.1", |
||||
"husky": "^7.0.4", |
||||
"lint-staged": "^12.1.3", |
||||
"node-sass": "^6.0.1", |
||||
"prettier": "^2.5.1", |
||||
"qs": "^6.10.2", |
||||
"sass-loader": "^10.2.0", |
||||
"video.js": "^8.23.3" |
||||
} |
||||
} |
@ -0,0 +1,64 @@
@@ -0,0 +1,64 @@
|
||||
{ |
||||
"name": "novo-pc", |
||||
"version": "1.0.0", |
||||
"private": true, |
||||
"scripts": { |
||||
"dev": "nuxt", |
||||
"build": "cross-env process.env.VUE_APP_TITLE=test nuxt build", |
||||
"build:prod": "cross-env process.env.VUE_APP_TITLE=production nuxt build", |
||||
"start": "node ./server.js", |
||||
"start_prod": "NODE_ENV=production node ./server.js", |
||||
"lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .", |
||||
"lint:js:fix": "eslint --ext \".js,.vue\" --ignore-path .gitignore --fix .", |
||||
"format": "prettier --write \"./**/*.vue\" \"./**/*.js\" \"./**/*.scss\" ", |
||||
"format1": "prettier ", |
||||
"lint:prettier": "prettier --check \"./**/*.vue\" \"./**/*.js\"", |
||||
"lint": "npm run lint:js && npm run lint:prettier", |
||||
"lintfix": "prettier --write --list-different \"./**/*.vue\" \"./**/*.js\" && npm run lint:js:fix", |
||||
"prepare": "husky install", |
||||
"generate": "nuxt generate" |
||||
}, |
||||
"husky": { |
||||
"hooks": { |
||||
"pre-commit": "lint-staged" |
||||
} |
||||
}, |
||||
"lint-staged": { |
||||
"*.{js,vue}": "eslint --cache", |
||||
"*.**": "prettier --check --ignore-unknown" |
||||
}, |
||||
"dependencies": { |
||||
"@nuxtjs/axios": "^5.13.6", |
||||
"@nuxtjs/robots": "^2.5.0", |
||||
"@nuxtjs/style-resources": "^1.2.1", |
||||
"core-js": "^3.19.3", |
||||
"element-ui": "^2.15.6", |
||||
"koa": "^2.13.4", |
||||
"moment": "^2.29.1", |
||||
"nuxt": "^2.15.8", |
||||
"vue": "^2.6.14", |
||||
"vue-awesome-swiper": "^3.1.3", |
||||
"vue-qr": "^3.2.2", |
||||
"vue-server-renderer": "^2.6.14", |
||||
"vue-template-compiler": "^2.6.14", |
||||
"vue-video-player": "^5.0.2", |
||||
"webpack": "^4.46.0", |
||||
"weixin-js-sdk": "^1.6.0" |
||||
}, |
||||
"devDependencies": { |
||||
"@nuxtjs/eslint-config": "^6.0.1", |
||||
"@nuxtjs/eslint-module": "^3.0.2", |
||||
"@nuxtjs/proxy": "^2.1.0", |
||||
"cross-env": "^7.0.3", |
||||
"eslint": "^7.29.0", |
||||
"eslint-config-prettier": "^8.3.0", |
||||
"eslint-plugin-nuxt": "^2.0.0", |
||||
"eslint-plugin-vue": "^7.12.1", |
||||
"husky": "^7.0.4", |
||||
"lint-staged": "^12.1.3", |
||||
"node-sass": "^6.0.1", |
||||
"prettier": "^2.5.1", |
||||
"qs": "^6.10.2", |
||||
"sass-loader": "^10.2.0" |
||||
} |
||||
} |
@ -0,0 +1,54 @@
@@ -0,0 +1,54 @@
|
||||
const Koa = require('koa'); |
||||
const { Nuxt, Builder } = require('nuxt'); |
||||
|
||||
const dotenv = require('dotenv'); |
||||
|
||||
console.log('==========env:', process.env.NODE_ENV); |
||||
|
||||
if (process.env.NODE_ENV !== 'production') { |
||||
// dotenv.config('.env');
|
||||
} else { |
||||
console.log('===+++++++++++'); |
||||
|
||||
// dotenv.config('./.env.production');
|
||||
} |
||||
dotenv.config('.env'); |
||||
|
||||
console.log( |
||||
'===+++++++++++', |
||||
process.env.BROWSER_BASE_URL, |
||||
process.env.PROXY_URL |
||||
); |
||||
|
||||
// console.log("==========env2:", process.env);
|
||||
|
||||
async function start() { |
||||
const app = new Koa(); |
||||
|
||||
// Import and Set Nuxt.js options
|
||||
const config = require('./nuxt.config.js'); |
||||
config.dev = process.env.NODE_ENV !== 'production'; |
||||
|
||||
const { host, port } = config.server; |
||||
|
||||
// Instantiate nuxt.js
|
||||
const nuxt = new Nuxt(config); |
||||
|
||||
// Build in development
|
||||
if (config.dev) { |
||||
const builder = new Builder(nuxt); |
||||
await builder.build(); |
||||
} |
||||
|
||||
app.use((ctx) => { |
||||
ctx.status = 200; |
||||
ctx.respond = false; // Mark request as handled for Koa
|
||||
ctx.req.ctx = ctx; // This might be useful later on, e.g. in nuxtServerInit or with nuxt-stash
|
||||
nuxt.render(ctx.req, ctx.res); |
||||
}); |
||||
|
||||
app.listen(port, host); |
||||
console.log('Server listening on ' + host + ':' + port); // eslint-disable-line no-console
|
||||
} |
||||
|
||||
start(); |
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
$outer-width: 1258px; |
||||
$content-width: 1080px; |
||||
$body-color: #fff; |
||||
$bg-color: #f5f5f8; |
||||
|
||||
$main-blue-color: #001965; |
||||
|
||||
$font-color1: #292b2c; |
||||
$font-color2: #5d6269; |
||||
$font-color3: #939aa7; |
||||
|
||||
$extra-blue: #005ad2; |
||||
$extra-red: #e6553f; |
||||
$extra-yellow: #eaab00; |
||||
$extra-green: #2a918b; |
||||
$extra-pink: #eea7bf; |
||||
|
||||
@mixin textEllipsisMore1Line($lines) { |
||||
display: -webkit-box; |
||||
-webkit-box-orient: vertical; |
||||
-webkit-line-clamp: $lines; |
||||
overflow: hidden; |
||||
} |
||||
@mixin roundFun($width) { |
||||
width: $width; |
||||
height: $width; |
||||
border-radius: $width/2; |
||||
} |
@ -0,0 +1,227 @@
@@ -0,0 +1,227 @@
|
||||
@import 'variable'; |
||||
* { |
||||
margin: 0; |
||||
border: none; |
||||
padding: 0; |
||||
} |
||||
html { |
||||
height: 100%; |
||||
} |
||||
body { |
||||
position: relative; |
||||
min-width: 320px; |
||||
min-height: 100%; |
||||
background: $body-color; |
||||
font-family: MicrosoftYaHei; |
||||
font-size: 0; |
||||
.outer-container { |
||||
min-width: $outer-width; |
||||
&.isMobile { |
||||
min-width: auto; |
||||
.content-container { |
||||
padding: 60px 0 62px; |
||||
width: 100%; |
||||
.left-content { |
||||
display: block !important; |
||||
margin-right: 0 !important; |
||||
width: 100% !important; |
||||
} |
||||
.footer-outer { |
||||
position: absolute !important; |
||||
min-width: auto !important; |
||||
} |
||||
.load-more { |
||||
width: 100% !important; |
||||
} |
||||
.common-flex { |
||||
display: block !important; |
||||
} |
||||
.common-other-content { |
||||
margin: 0 !important; |
||||
h6 { |
||||
margin-bottom: 10px !important; |
||||
font-size: 20px !important; |
||||
line-height: 28px !important; |
||||
} |
||||
.font-content { |
||||
p, |
||||
b, |
||||
h5, |
||||
h6 { |
||||
margin-bottom: 8px !important; |
||||
font-size: 16px !important; |
||||
line-height: 24px !important; |
||||
word-break: break-all; |
||||
} |
||||
h5 { |
||||
font-size: 18px !important; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
&.hasLoginBottom { |
||||
padding-bottom: calc(constant(safe-area-inset-bottom) + 55px); |
||||
padding-bottom: calc(env(safe-area-inset-bottom) + 55px); |
||||
.bottom-outer, |
||||
.footer-outer { |
||||
bottom: calc(constant(safe-area-inset-bottom) + 55px); |
||||
bottom: calc(env(safe-area-inset-bottom) + 55px); |
||||
} |
||||
.fixed-box { |
||||
bottom: calc(constant(safe-area-inset-bottom) + 65px) !important; |
||||
bottom: calc(env(safe-area-inset-bottom) + 65px) !important; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.content-container { |
||||
margin: 0 auto; |
||||
width: $content-width; |
||||
} |
||||
img { |
||||
vertical-align: top; |
||||
-o-object-fit: cover; |
||||
object-fit: cover; |
||||
} |
||||
a { |
||||
text-decoration: none; |
||||
} |
||||
.text-ellipsis { |
||||
display: block; |
||||
overflow: hidden; |
||||
white-space: nowrap; |
||||
text-overflow: ellipsis; |
||||
} |
||||
.left-content { |
||||
display: inline-block; |
||||
margin-right: 32px; |
||||
width: 723px; |
||||
} |
||||
.right-content { |
||||
float: right; |
||||
display: inline-block; |
||||
width: 325px; |
||||
} |
||||
.common-flex { |
||||
//display: flex; |
||||
//justify-content: space-between; |
||||
//flex-wrap: wrap; |
||||
display: grid; |
||||
grid-template-columns: repeat(4, 25%); |
||||
} |
||||
.load-more { |
||||
margin: 0 auto; |
||||
width: 357px; |
||||
height: 50px; |
||||
background: $bg-color; |
||||
border-radius: 4px; |
||||
font-size: 18px; |
||||
font-family: PingFangSC-Regular, PingFang SC; |
||||
font-weight: 400; |
||||
color: $font-color3; |
||||
line-height: 50px; |
||||
text-align: center; |
||||
} |
||||
.footer-outer { |
||||
position: fixed; |
||||
bottom: 0; |
||||
left: 0; |
||||
width: 100%; |
||||
min-width: $outer-width; |
||||
background: $bg-color; |
||||
z-index: 9; |
||||
} |
||||
.common-title { |
||||
padding: 20px 0 10px; |
||||
text-align: left; |
||||
font-size: 24px; |
||||
font-family: PingFangSC-Medium, PingFang SC; |
||||
font-weight: 500; |
||||
color: $main-blue-color; |
||||
line-height: 33px; |
||||
a { |
||||
float: right; |
||||
font-size: 16px; |
||||
font-family: PingFangSC-Regular, PingFang SC; |
||||
font-weight: 400; |
||||
color: $font-color2; |
||||
i { |
||||
color: $main-blue-color; |
||||
} |
||||
} |
||||
} |
||||
p.go-follow { |
||||
margin-bottom: 23px; |
||||
height: 50px; |
||||
background: $extra-red; |
||||
border-radius: 4px; |
||||
text-align: center; |
||||
cursor: pointer; |
||||
font-size: 18px; |
||||
font-family: PingFangSC-Medium, PingFang SC; |
||||
font-weight: 500; |
||||
color: $body-color; |
||||
line-height: 50px; |
||||
} |
||||
.common-other-content { |
||||
margin: 44px 0; |
||||
padding: 30px; |
||||
box-sizing: border-box; |
||||
h6 { |
||||
margin-bottom: 20px; |
||||
font-size: 24px; |
||||
font-family: PingFangSC-Medium, PingFang SC; |
||||
font-weight: 500; |
||||
color: $main-blue-color; |
||||
line-height: 33px; |
||||
} |
||||
.font-content { |
||||
p, |
||||
b, |
||||
h5, |
||||
h6 { |
||||
margin-bottom: 12px; |
||||
font-size: 18px; |
||||
color: $font-color2; |
||||
line-height: 30px; |
||||
} |
||||
h5 { |
||||
font-size: 20px; |
||||
} |
||||
} |
||||
} |
||||
.el-message { |
||||
top: 50% !important; |
||||
i { |
||||
font-size: 16px; |
||||
} |
||||
@media screen and (max-width: 500px) { |
||||
min-width: 200px; |
||||
max-width: 80%; |
||||
} |
||||
} |
||||
.video-player-box { |
||||
.vjs-big-play-button { |
||||
top: 50%; |
||||
left: 50%; |
||||
border: none; |
||||
outline: none; |
||||
width: 68px; |
||||
height: 67px; |
||||
transform: translate(-50%, -50%); |
||||
background: url(~assets/images/video_play_icon.png) center no-repeat; |
||||
background-color: transparent !important; |
||||
background-size: 68px 67px; |
||||
.vjs-icon-placeholder::before { |
||||
display: none; |
||||
} |
||||
} |
||||
.vjs-control-bar button { |
||||
outline: none; |
||||
//outline: 2px; |
||||
} |
||||
} |
||||
.el-avatar > img { |
||||
width: 100%; |
||||
} |
||||
} |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 74 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 372 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 968 B |
After Width: | Height: | Size: 969 B |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 392 B |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 952 B |
After Width: | Height: | Size: 5.4 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 124 KiB |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 9.1 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,508 @@
@@ -0,0 +1,508 @@
|
||||
<!-- |
||||
* @Author: your name |
||||
* @Date: 2020-03-18 13:26:53 |
||||
* @LastEditTime: 2020-09-02 22:05:29 |
||||
* @LastEditors: Please set LastEditors |
||||
* @Description: In User Settings Edit |
||||
* @FilePath: /vue-barrage/src/views/src/barrage_new.vue |
||||
--> |
||||
<template> |
||||
<div class="z_barrage-container"> |
||||
<canvas |
||||
ref="canvasContainer" |
||||
:width="containerWidth" |
||||
:height="containerHeight" |
||||
style="display: none" |
||||
/> |
||||
<div class="z_container" :style="{ height: containerHeight / 2 + 'px' }"> |
||||
<canvas |
||||
id="canvas" |
||||
ref="canvas" |
||||
class="z_barrage" |
||||
:width="containerWidth" |
||||
:height="containerHeight" |
||||
:style="{ |
||||
width: containerWidth / 2 + 'px', |
||||
height: containerHeight / 2 + 'px' |
||||
}" |
||||
/> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
// import faceMap from '../../assets/emoji' |
||||
let aniId, aniId1; |
||||
export default { |
||||
name: 'Barrage', |
||||
props: { |
||||
barrageList: { |
||||
type: Array, |
||||
default: () => [] |
||||
}, |
||||
speed: { |
||||
type: Number, |
||||
default: 4 |
||||
}, |
||||
loop: { |
||||
type: Boolean, |
||||
default: true |
||||
}, |
||||
channels: { |
||||
type: Number, |
||||
default: 2 |
||||
}, |
||||
barrageHeight: { |
||||
type: Number, |
||||
default: 60 |
||||
}, |
||||
screenPercent: { |
||||
type: Number, |
||||
default: 0.3 |
||||
}, |
||||
borderColor: { |
||||
type: String, |
||||
default: '' |
||||
}, |
||||
background: { |
||||
type: String, |
||||
default: '' |
||||
}, |
||||
deviceType: { |
||||
type: String, |
||||
default: 'pc' |
||||
}, |
||||
linearGradient: { |
||||
type: Object, |
||||
default: () => { |
||||
return { |
||||
startColor: '', |
||||
endColor: '' |
||||
}; |
||||
} |
||||
} |
||||
}, |
||||
data() { |
||||
return { |
||||
newBarrageArray: [], // 新增弹幕之后的总弹幕 |
||||
barrageArray: [], |
||||
barrageQueue: [], |
||||
containerWidth: 0, |
||||
containerHeight: 0, |
||||
channelsArray: [], |
||||
barrageChannels: 1 |
||||
}; |
||||
}, |
||||
watch: { |
||||
barrageList(val) { |
||||
if (val.length !== 0) { |
||||
this.barrageQueue = JSON.parse(JSON.stringify(val)); |
||||
this.newBarrageArray = JSON.parse(JSON.stringify(val)); |
||||
this.initData(); |
||||
window.cancelAnimationFrame(aniId); |
||||
aniId = window.requestAnimationFrame(this.render); |
||||
} |
||||
} |
||||
}, |
||||
mounted() { |
||||
this.containerWidth = |
||||
this.deviceType === 'pc' ? 723 * 2 : document.body.clientWidth * 2; |
||||
this.containerHeight = 365 * 2; // 设定总高度 |
||||
this.barrageChannels = this.channels; // 总高度对应的轨道数 |
||||
this.ctx = this.$refs.canvas.getContext('2d'); |
||||
this.ctx1 = this.$refs.canvasContainer.getContext('2d'); |
||||
this.barrageClickEvent(); |
||||
}, |
||||
methods: { |
||||
/** |
||||
* 数据初始化 |
||||
*/ |
||||
initData() { |
||||
for (let i = 0; i < this.barrageQueue.length; i++) { |
||||
// 此处处理只显示50个字符 |
||||
let tagImg = null; |
||||
let img = null; |
||||
if (this.barrageQueue[i].icon) { |
||||
img = new Image(); |
||||
img.src = this.barrageQueue[i].icon; |
||||
} |
||||
if (this.barrageQueue[i].tagImage) { |
||||
tagImg = new Image(); |
||||
tagImg.src = this.barrageQueue[i].tagImage; |
||||
} |
||||
const content = this.dealStr(this.barrageQueue[i].content); |
||||
this.barrageArray.push({ |
||||
id: this.barrageQueue[i].id, |
||||
content, |
||||
x: this.containerWidth + this.barrageHeight, |
||||
icon: img, |
||||
tagImage: tagImg, |
||||
width: |
||||
this.ctx1.measureText(content).width * 3.6 + |
||||
(this.barrageQueue[i].icon ? 60 : 0), |
||||
color: this.barrageQueue[i].color || '#FFFFFF', |
||||
bgColor: this.barrageQueue[i].bgColor || 'rgba(0,0,0,0.4)' |
||||
}); |
||||
} |
||||
this.initChannel(); |
||||
}, |
||||
/** |
||||
* 初始化轨道数据 |
||||
*/ |
||||
initChannel() { |
||||
for (let i = 0; i < this.barrageChannels; i++) { |
||||
const item = this.barrageArray.shift(); |
||||
if (item) { |
||||
this.channelsArray[i] = [item]; |
||||
} else { |
||||
this.channelsArray[i] = []; |
||||
} |
||||
} |
||||
}, |
||||
/** |
||||
* 渲染 |
||||
*/ |
||||
render() { |
||||
this.ctx.clearRect(0, 0, this.containerWidth, this.containerHeight); |
||||
this.ctx.font = '36px Microsoft YaHei'; |
||||
this.draw(); |
||||
window.cancelAnimationFrame(aniId1); |
||||
aniId1 = window.requestAnimationFrame(this.render); |
||||
}, |
||||
draw() { |
||||
for (let i = 0; i < this.channelsArray.length; i++) { |
||||
for (let j = 0; j < this.channelsArray[i].length; j++) { |
||||
try { |
||||
const barrage = this.channelsArray[i][j]; |
||||
barrage.x -= this.speed; |
||||
if (barrage.x <= this.containerWidth) { |
||||
// 弹幕显示 |
||||
this.borderColor && |
||||
this.drawRoundRectBorder( |
||||
this.ctx, |
||||
barrage.x - this.barrageHeight / 2, |
||||
i * (this.barrageHeight + 60) + 20, |
||||
barrage.width + this.barrageHeight, |
||||
this.barrageHeight, |
||||
this.barrageHeight / 2 |
||||
); |
||||
this.drawRoundRect( |
||||
this.ctx, |
||||
barrage.bgColor, |
||||
barrage.x - this.barrageHeight / 2, |
||||
i * (this.barrageHeight + 60) + 21, |
||||
barrage.width + this.barrageHeight, |
||||
this.barrageHeight - 2, |
||||
this.barrageHeight / 2 |
||||
); |
||||
this.ctx.fillStyle = `${barrage.color}`; |
||||
this.ctx.fillText( |
||||
barrage.content, |
||||
barrage.x + (barrage.icon ? this.barrageHeight / 2 + 10 : -5), |
||||
i * (this.barrageHeight + 60) + this.barrageHeight - 25 |
||||
); |
||||
if (barrage.icon) { |
||||
this.circleImg( |
||||
this.ctx, |
||||
barrage.icon, |
||||
barrage.x - 40, |
||||
i * (this.barrageHeight + 60) + 40, |
||||
40 |
||||
); |
||||
} |
||||
if (barrage.tagImage) { |
||||
this.originImg( |
||||
this.ctx, |
||||
barrage.tagImage, |
||||
barrage.x - this.barrageHeight - 10, |
||||
i * (this.barrageHeight + 60) + 20, |
||||
this.barrageHeight, |
||||
this.barrageHeight |
||||
); |
||||
} |
||||
} |
||||
if (barrage.x < -(barrage.width + this.barrageHeight)) { |
||||
// 弹幕删除 |
||||
const arr = this.channelsArray.reduce((a, b) => a.concat(b)); |
||||
if (this.loop) { |
||||
if (this.checkBarrageStatus(arr)) { |
||||
this.barrageQueue = []; |
||||
this.barrageQueue = JSON.parse( |
||||
JSON.stringify(this.newBarrageArray) |
||||
); |
||||
this.initData(); |
||||
} |
||||
} |
||||
} |
||||
// 弹幕插入时机判断 |
||||
if ( |
||||
barrage.x <= |
||||
Math.floor(this.containerWidth - barrage.width - 40) && |
||||
barrage.x >= |
||||
Math.floor( |
||||
this.containerWidth - barrage.width - 40 - this.speed |
||||
) && |
||||
j === this.channelsArray[i].length - 1 && |
||||
this.barrageArray.length !== 0 |
||||
) { |
||||
const item = this.barrageArray.shift(); |
||||
this.channelsArray[i].push(item); |
||||
} |
||||
} catch (e) { |
||||
console.log(e); |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
/** |
||||
* 重置数据 |
||||
*/ |
||||
add(obj) { |
||||
const content = this.dealStr(obj.content); |
||||
let img = null; |
||||
let tagImg = null; |
||||
if (obj.icon) { |
||||
img = new Image(); |
||||
img.src = obj.icon; |
||||
} |
||||
if (obj.tagImage) { |
||||
tagImg = new Image(); |
||||
tagImg.src = obj.tagImage; |
||||
} |
||||
const item = { |
||||
id: obj.id, |
||||
content, |
||||
x: this.containerWidth + this.barrageHeight, |
||||
icon: obj.icon ? img : '', |
||||
tagImage: obj.tagImage ? tagImg : '', |
||||
width: |
||||
this.ctx1.measureText(content).width * 3 + |
||||
(obj.icon ? this.barrageHeight : 0), |
||||
color: obj.color || '#FFFFFF', |
||||
bgColor: obj.bgColor || 'rgba(0,0,0,0.4)' |
||||
}; |
||||
const originItem = { |
||||
id: obj.id, |
||||
content: obj.content, |
||||
icon: obj.icon, |
||||
tagImage: obj.tagImage, |
||||
color: obj.color || '#FFFFFF', |
||||
bgColor: obj.bgColor || 'rgba(0,0,0,0.4)' |
||||
}; |
||||
if (this.barrageArray.length === 0) { |
||||
// 剩余弹幕数为0 |
||||
this.newBarrageArray.unshift(originItem); |
||||
} else { |
||||
this.barrageArray.unshift(item); |
||||
const insertIndex = this.barrageList.length - this.barrageArray.length; |
||||
this.newBarrageArray.splice(insertIndex, 0, originItem); |
||||
} |
||||
}, |
||||
/** |
||||
* 弹幕点击事件 |
||||
*/ |
||||
barrageClickEvent() { |
||||
document.getElementById('canvas').addEventListener( |
||||
'click', |
||||
(e) => { |
||||
const p = this.getEventPosition(e); |
||||
const channelIndex = Math.floor(p.y / (this.barrageHeight + 36)); |
||||
const tempArray = JSON.parse( |
||||
JSON.stringify(this.channelsArray[channelIndex]) |
||||
); |
||||
for (let i = 0; i < tempArray.length; i++) { |
||||
const channelItemArray = tempArray[i]; |
||||
if ( |
||||
p.x > channelItemArray.x && |
||||
p.x < channelItemArray.x + channelItemArray.width |
||||
) { |
||||
if (channelItemArray.id) { |
||||
this.$emit('doLike', channelItemArray.id); |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
false |
||||
); |
||||
}, |
||||
/** |
||||
* 获取点击位置 |
||||
*/ |
||||
getEventPosition(ev) { |
||||
let x, y; |
||||
if (ev.layerX || ev.layerX === 0) { |
||||
x = ev.layerX; |
||||
y = ev.layerY; |
||||
} else if (ev.offsetX || ev.offsetX === 0) { |
||||
x = ev.offsetX; |
||||
y = ev.offsetY; |
||||
} |
||||
return { x: 2 * x, y: 2 * y }; |
||||
}, |
||||
/** |
||||
* 判断所有的弹幕是否滚动完成 |
||||
* @params arr |
||||
*/ |
||||
checkBarrageStatus(arr) { |
||||
for (let i = 0; i < arr.length; i++) { |
||||
if (arr[i].x > -arr[i].width) return false; |
||||
} |
||||
return true; |
||||
}, |
||||
/** |
||||
* 处理字符 |
||||
*/ |
||||
dealStr(str) { |
||||
return str.length > 50 ? `${str.substring(0, 50)}...` : str; |
||||
}, |
||||
/** |
||||
* 获取随机颜色 |
||||
*/ |
||||
getColor() { |
||||
return `#${Math.floor(Math.random() * 16777215).toString(16)}`; |
||||
}, |
||||
/** |
||||
* 裁剪图片 |
||||
* @param ctx |
||||
* @param img |
||||
* @param x |
||||
* @param y |
||||
* @param r |
||||
*/ |
||||
circleImg(ctx, img, x, y, r) { |
||||
ctx.save(); |
||||
const d = 2 * r; |
||||
const cx = x + r; |
||||
const cy = y + r; |
||||
ctx.beginPath(); |
||||
ctx.arc(cx, cy, r, 0, 2 * Math.PI); |
||||
ctx.clip(); |
||||
ctx.drawImage(img, x, y, d, d); |
||||
ctx.restore(); |
||||
ctx.closePath(); |
||||
}, |
||||
/** |
||||
* 绘制原始图片 |
||||
* @param ctx |
||||
* @param img |
||||
* @param x |
||||
* @param y |
||||
* @param width |
||||
* @param height |
||||
*/ |
||||
originImg(ctx, img, x, y, width, height) { |
||||
try { |
||||
ctx.beginPath(); |
||||
ctx.drawImage(img, x, y, width, height); |
||||
ctx.closePath(); |
||||
} catch (e) { |
||||
console.log(e); |
||||
} |
||||
}, |
||||
/** |
||||
* 绘画圆角矩形 |
||||
* @param context |
||||
* @param bgColor |
||||
* @param x |
||||
* @param y |
||||
* @param width |
||||
* @param height |
||||
* @param radius |
||||
*/ |
||||
drawRoundRect(context, bgColor, x, y, width, height, radius) { |
||||
if (this.linearGradient.startColor && this.linearGradient.endColor) { |
||||
const linearGrad = context.createLinearGradient(x, y, x, y + height); |
||||
linearGrad.addColorStop(0, this.linearGradient.startColor); |
||||
linearGrad.addColorStop(1, this.linearGradient.endColor); |
||||
context.fillStyle = linearGrad || bgColor; |
||||
} else { |
||||
context.fillStyle = this.background || bgColor; |
||||
} |
||||
context.beginPath(); |
||||
context.arc(x + radius, y + radius, radius, Math.PI, (Math.PI * 3) / 2); |
||||
context.lineTo(width - radius + x, y); |
||||
context.arc( |
||||
width - radius + x, |
||||
radius + y, |
||||
radius, |
||||
(Math.PI * 3) / 2, |
||||
Math.PI * 2 |
||||
); |
||||
context.lineTo(width + x, height + y - radius); |
||||
context.arc( |
||||
width - radius + x, |
||||
height - radius + y, |
||||
radius, |
||||
0, |
||||
Math.PI / 2 |
||||
); |
||||
context.lineTo(radius + x, height + y); |
||||
context.arc( |
||||
radius + x, |
||||
height - radius + y, |
||||
radius, |
||||
Math.PI / 2, |
||||
Math.PI |
||||
); |
||||
context.fill(); |
||||
context.closePath(); |
||||
}, |
||||
/** |
||||
* 绘画圆角矩形 |
||||
* @param context |
||||
* @param x |
||||
* @param y |
||||
* @param width |
||||
* @param height |
||||
* @param radius 半径 |
||||
*/ |
||||
drawRoundRectBorder(context, x, y, width, height, radius) { |
||||
context.beginPath(); |
||||
context.lineWidth = 2; |
||||
context.strokeStyle = this.borderColor; |
||||
context.arc(x + radius, y + radius, radius, Math.PI, (Math.PI * 3) / 2); |
||||
context.lineTo(width - radius + x, y); |
||||
context.arc( |
||||
width - radius + x, |
||||
radius + y, |
||||
radius, |
||||
(Math.PI * 3) / 2, |
||||
Math.PI * 2 |
||||
); |
||||
context.lineTo(width + x, height + y - radius); |
||||
context.arc( |
||||
width - radius + x, |
||||
height - radius + y, |
||||
radius, |
||||
0, |
||||
Math.PI / 2 |
||||
); |
||||
context.lineTo(radius + x, height + y); |
||||
context.arc( |
||||
radius + x, |
||||
height - radius + y, |
||||
radius, |
||||
Math.PI / 2, |
||||
Math.PI |
||||
); |
||||
context.stroke(); |
||||
context.closePath(); |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="css" scoped> |
||||
.z_barrage-container { |
||||
pointer-events: none; |
||||
} |
||||
.z_container { |
||||
width: 100%; |
||||
overflow: hidden; |
||||
} |
||||
.z_barrage { |
||||
position: absolute; |
||||
top: 0; |
||||
left: 0; |
||||
} |
||||
</style> |
@ -0,0 +1,440 @@
@@ -0,0 +1,440 @@
|
||||
<template> |
||||
<div> |
||||
<div |
||||
class="fixed-box" |
||||
:class="{ isMobile: deviceType !== 'pc' }" |
||||
:style="{ right: right + 'px' }" |
||||
> |
||||
<div v-if="scrollTop > 200" @click="goTop"> |
||||
<i class="el-icon-arrow-up"></i><span>TOP</span> |
||||
</div> |
||||
<template v-if="deviceType !== 'pc'"> |
||||
<div |
||||
v-if="showCollect" |
||||
:style="{ color: isCollect == 1 ? '#EAAB00' : '' }" |
||||
@click="collectClick" |
||||
> |
||||
<i class="el-icon-star-on"></i |
||||
><span>{{ isCollect == 1 ? '已' : '' }}收藏</span> |
||||
</div> |
||||
<div v-if="showShare" @click="showSharePop"> |
||||
<i class="el-icon-share"></i><span>分享</span> |
||||
</div> |
||||
<div v-if="showComment" @click="commentClick"> |
||||
<img src="~/assets/images/comment.png" alt="" /><span>评论</span> |
||||
</div> |
||||
<div v-if="showLike" @click="likeClick"> |
||||
<img |
||||
v-if="isLike == 1" |
||||
src="~/assets/images/like_chosen.png" |
||||
alt="" |
||||
/><img v-else src="~/assets/images/like.png" alt="" /><span |
||||
:style="{ color: isLike == 1 ? '#E6553F' : '' }" |
||||
>{{ likeNum }}</span |
||||
> |
||||
</div> |
||||
</template> |
||||
</div> |
||||
<div |
||||
v-if="deviceType === 'pc'" |
||||
class="fixed-box left-fixed" |
||||
:style="{ |
||||
position: hasScroll ? 'fixed' : 'absolute', |
||||
top: hasScroll ? '236px' : '', |
||||
left: left + 'px' |
||||
}" |
||||
> |
||||
<div |
||||
v-if="showCollect" |
||||
:style="{ color: isCollect == 1 ? '#EAAB00' : '' }" |
||||
@click="collectClick" |
||||
> |
||||
<i class="el-icon-star-on"></i |
||||
><span>{{ isCollect == 1 ? '已' : '' }}收藏</span> |
||||
</div> |
||||
<el-popover |
||||
placement="right" |
||||
width="174" |
||||
:visible-arrow="false" |
||||
popper-class="share-hover-box" |
||||
trigger="hover" |
||||
> |
||||
<div class="share-box"> |
||||
<el-popover |
||||
placement="top-start" |
||||
width="176" |
||||
:visible-arrow="false" |
||||
popper-class="wechat-qrcode-box" |
||||
trigger="hover" |
||||
> |
||||
<div class="qrcode-box"> |
||||
<p> |
||||
<img |
||||
src="~/assets/images/wechat_color.png" |
||||
alt="扫码分享至微信" |
||||
/>扫码分享至微信 |
||||
</p> |
||||
<vue-qr class="bicode" :size="220" :text="codeValue"></vue-qr> |
||||
</div> |
||||
<p slot="reference" @click="share('微信')"> |
||||
<img src="~/assets/images/share_wechat.png" alt="" /> |
||||
</p> |
||||
</el-popover> |
||||
<p @click="share('qq')"> |
||||
<img src="~/assets/images/share_qq.png" alt="" /> |
||||
</p> |
||||
<p @click="share('微博')"> |
||||
<img src="~/assets/images/share_weibo.png" alt="" /> |
||||
</p> |
||||
</div> |
||||
<div v-if="showShare" slot="reference" @click="pcShareClick"> |
||||
<i class="el-icon-share"></i><span>分享</span> |
||||
</div> |
||||
</el-popover> |
||||
<div v-if="showComment" @click="commentClick"> |
||||
<img src="~/assets/images/comment.png" alt="" /><span>评论</span> |
||||
</div> |
||||
<div v-if="showLike" @click="likeClick"> |
||||
<img |
||||
v-if="isLike == 1" |
||||
src="~/assets/images/like_chosen.png" |
||||
alt="" |
||||
/><img v-else src="~/assets/images/like.png" alt="" /><span |
||||
:style="{ color: isLike == 1 ? '#E6553F' : '' }" |
||||
>{{ likeNum }}</span |
||||
> |
||||
</div> |
||||
</div> |
||||
<div |
||||
v-if="sharePopupShow" |
||||
class="share-popup" |
||||
@click="sharePopupShow = false" |
||||
> |
||||
<template v-if="env === 'wechat' || env === 'weibo' || env === 'qq'"> |
||||
<img src="~/assets/images/share_point.png" /> |
||||
<div> |
||||
<p>点击右上角</p> |
||||
<p>分享给朋友</p> |
||||
</div> |
||||
</template> |
||||
<template v-else> |
||||
<p>点击浏览器分享图标,发送好友</p> |
||||
</template> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
export default { |
||||
props: { |
||||
showCollect: Boolean, |
||||
showShare: Boolean, |
||||
showComment: Boolean, |
||||
showLike: Boolean, |
||||
isLike: { |
||||
type: Number, |
||||
default: 0 |
||||
}, |
||||
likeNum: { |
||||
type: Number, |
||||
default: 0 |
||||
}, |
||||
isCollect: { |
||||
type: Number, |
||||
default: 0 |
||||
}, |
||||
isLogin: { |
||||
type: Boolean, |
||||
default: false |
||||
} |
||||
}, |
||||
data() { |
||||
return { |
||||
scrollTop: 0, |
||||
left: -89, |
||||
right: 0, |
||||
codeValue: '', |
||||
hasScroll: false, |
||||
sharePopupShow: false |
||||
}; |
||||
}, |
||||
computed: { |
||||
deviceType() { |
||||
return this.$store.state.device.deviceType; |
||||
}, |
||||
env() { |
||||
return this.$store.state.device.env; |
||||
} |
||||
}, |
||||
mounted() { |
||||
const that = this; |
||||
let href = window.location.href; |
||||
if (that.$route.name !== 'video-id') { |
||||
const origin = |
||||
process.env.VUE_APP_TITLE !== 'production' |
||||
? 'https://apptest.diabetes.com.cn' |
||||
: 'https://app.diabetes.com.cn'; |
||||
if (that.$route.name === 'doctor-id') { |
||||
href = origin + '/expert-video'; |
||||
} else { |
||||
href = origin + '/library/detail/' + that.$route.params.id; |
||||
} |
||||
} |
||||
this.codeValue = href; |
||||
if (that.deviceType !== 'pc' && that.env === 'wechat' && that.showShare) { |
||||
that.wxShare( |
||||
{ |
||||
title: document.title, |
||||
desc: document |
||||
.querySelector('meta[name="description"]') |
||||
.getAttribute('content'), |
||||
url: href, |
||||
image: location.origin + require('~/assets/images/mobile_logo.png') |
||||
}, |
||||
() => { |
||||
that.sharePopupShow = false; |
||||
} |
||||
); |
||||
} |
||||
this.right = (document.documentElement.offsetWidth - 1258) / 2; |
||||
this.$nextTick(() => { |
||||
window.addEventListener('scroll', function () { |
||||
that.hasScroll = true; |
||||
// 变量scrollTop是滚动条滚动时,距离顶部的距离 |
||||
const scrollTop = |
||||
document.documentElement.scrollTop || document.body.scrollTop; |
||||
const scrollLeft = |
||||
document.documentElement.scrollLeft || document.body.scrollLeft; |
||||
that.scrollTop = scrollTop; |
||||
if (document.documentElement.offsetWidth < 1258) { |
||||
that.right = |
||||
0 - (1258 - document.documentElement.offsetWidth) + scrollLeft; |
||||
that.left = 0 - scrollLeft; |
||||
} else { |
||||
that.right = (document.documentElement.offsetWidth - 1258) / 2; |
||||
that.left = (document.documentElement.offsetWidth - 1258) / 2; |
||||
} |
||||
}); |
||||
}); |
||||
}, |
||||
methods: { |
||||
goTop() { |
||||
document.documentElement.scrollTop = 0; |
||||
document.body.scrollTop = 0; |
||||
}, |
||||
commentClick() { |
||||
this.$emit('commentClick'); |
||||
}, |
||||
likeClick() { |
||||
this.$emit('likeClick'); |
||||
}, |
||||
collectClick() { |
||||
this.$emit('collectClick'); |
||||
}, |
||||
share(types) { |
||||
const title = document.title; |
||||
|
||||
// 当内容中没有图片时,设置分享图片为网站logo |
||||
|
||||
// 获取当前网页url |
||||
const url = document.location.href; |
||||
|
||||
// 获取网页描述 |
||||
const description = document |
||||
.querySelector('meta[name="description"]') |
||||
.getAttribute('content'); |
||||
|
||||
// 获取网页关键字 |
||||
const keywords = document |
||||
.querySelector('meta[name="keywords"]') |
||||
.getAttribute('content'); |
||||
|
||||
if (types === '微博') { |
||||
window.open( |
||||
'http://service.weibo.com/share/share.php?url=' + |
||||
url + |
||||
'&sharesource=weibo&title=' + |
||||
title + |
||||
' ' + |
||||
description, |
||||
'_blank' |
||||
); |
||||
} |
||||
// qq好友接口的传参 |
||||
if (types === 'qq') { |
||||
window.open( |
||||
'http://connect.qq.com/widget/shareqq/index.html?url=' + |
||||
url + |
||||
'&sharesource=qq&title=' + |
||||
title + |
||||
'&summary=' + |
||||
description + |
||||
'&desc=' + |
||||
keywords, |
||||
'_blank' |
||||
); |
||||
} |
||||
if (this.$route.name !== 'article-id') { |
||||
this.baiduStat( |
||||
(this.$route.name === 'video-id' ? '视频' : '一问医答') + '详情页', |
||||
'click', |
||||
(this.$route.name === 'video-id' ? '视频' : '一问医答') + |
||||
'分享-' + |
||||
types |
||||
); |
||||
} |
||||
}, |
||||
pcShareClick() { |
||||
if (this.$route.name === 'article-id') { |
||||
this.baiduStat('文章详情页', 'click', '文章内分享'); |
||||
} |
||||
}, |
||||
showSharePop() { |
||||
const that = this; |
||||
that.sharePopupShow = true; |
||||
this.baiduStat('移动端', 'click', '移动端-分享页面'); |
||||
if (this.env !== 'wechat') { |
||||
setTimeout(() => { |
||||
that.sharePopupShow = false; |
||||
}, 3000); |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
<style lang="scss"> |
||||
.fixed-box { |
||||
position: fixed; |
||||
bottom: 130px; |
||||
right: 0; |
||||
width: 60px; |
||||
z-index: 9; |
||||
div { |
||||
margin-top: 1px; |
||||
width: 62px; |
||||
height: 62px; |
||||
background: $bg-color; |
||||
border-radius: 4px; |
||||
text-align: center; |
||||
cursor: pointer; |
||||
color: $font-color2; |
||||
|
||||
i, |
||||
span { |
||||
font-size: 14px; |
||||
font-family: PingFangSC-Regular, PingFang SC; |
||||
font-weight: 400; |
||||
line-height: 20px; |
||||
} |
||||
i { |
||||
margin-top: 12px; |
||||
font-size: 30px; |
||||
} |
||||
img { |
||||
margin-top: 10px; |
||||
width: 26px; |
||||
} |
||||
span { |
||||
display: block; |
||||
} |
||||
} |
||||
&.isMobile { |
||||
top: auto !important; |
||||
right: 15px !important; |
||||
bottom: 70px !important; |
||||
transform: scale(0.85); |
||||
transform-origin: bottom; |
||||
} |
||||
&.left-fixed { |
||||
position: absolute; |
||||
top: 150px; |
||||
bottom: auto; |
||||
left: -89px; |
||||
} |
||||
} |
||||
.share-hover-box { |
||||
border: none; |
||||
box-shadow: none; |
||||
padding: 11px 0 11px 11px; |
||||
height: 61px; |
||||
background: $bg-color; |
||||
box-sizing: border-box; |
||||
transform: translateX(-15px); |
||||
border-radius: 0 50px 50px 0; |
||||
.share-box { |
||||
font-size: 0; |
||||
& > span, |
||||
& > p { |
||||
display: inline-block; |
||||
margin-right: 12px; |
||||
background: $body-color; |
||||
cursor: pointer; |
||||
@include roundFun(40px); |
||||
img { |
||||
@include roundFun(40px); |
||||
} |
||||
} |
||||
} |
||||
&.left-show { |
||||
transform: translateX(15px) scale(0.85); |
||||
transform-origin: bottom; |
||||
border-radius: 50px 0 0 50px; |
||||
} |
||||
} |
||||
.wechat-qrcode-box { |
||||
border: 1px solid #ededed; |
||||
padding: 14px 0 16px; |
||||
background: $body-color; |
||||
box-sizing: border-box; |
||||
.qrcode-box { |
||||
text-align: center; |
||||
p { |
||||
margin-bottom: 6px; |
||||
font-size: 16px; |
||||
color: $font-color1; |
||||
line-height: 28px; |
||||
img { |
||||
width: 28px; |
||||
height: 28px; |
||||
} |
||||
} |
||||
& > img { |
||||
width: 110px; |
||||
} |
||||
} |
||||
} |
||||
.share-popup { |
||||
position: fixed; |
||||
top: 0; |
||||
left: 0; |
||||
width: 100%; |
||||
height: 100%; |
||||
background: rgba(0, 0, 0, 0.5); |
||||
z-index: 10; |
||||
p { |
||||
font-size: 16px; |
||||
color: #fff; |
||||
text-align: center; |
||||
} |
||||
div { |
||||
text-align: right; |
||||
float: right; |
||||
position: absolute; |
||||
right: 0; |
||||
top: 60px; |
||||
width: 150px; |
||||
p { |
||||
display: block; |
||||
} |
||||
} |
||||
img { |
||||
width: 210px; |
||||
height: 124px; |
||||
float: right; |
||||
} |
||||
& > p { |
||||
position: absolute; |
||||
bottom: 20px; |
||||
width: 100%; |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,101 @@
@@ -0,0 +1,101 @@
|
||||
<template> |
||||
<div |
||||
:key="detail.id" |
||||
class="doctor-item" |
||||
@click="goDoctor(detail.video_list[0].id)" |
||||
> |
||||
<img :src="detail.expert_img" :alt="detail.username" /> |
||||
<h5>{{ detail.username }} {{ detail.title }}</h5> |
||||
<p class="text-ellipsis">{{ detail.hospital_name }}</p> |
||||
<p class="text-ellipsis">{{ detail.department }}</p> |
||||
<div class="expert-video-list"> |
||||
<template v-for="(video, index) in detail.video_list"> |
||||
<p |
||||
v-if="index < 2" |
||||
:key="'live' + video.id" |
||||
@click.stop="goDoctor(video.id)" |
||||
> |
||||
<img src="~/assets/images/doctor_play_icon.png" alt="" /> |
||||
<span>{{ video.title }}</span> |
||||
</p> |
||||
</template> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
export default { |
||||
props: { |
||||
detail: { |
||||
type: Object, |
||||
default: null |
||||
}, |
||||
columnNum: { |
||||
type: Number, |
||||
default: 1 |
||||
} |
||||
}, |
||||
created() {}, |
||||
methods: { |
||||
goDoctor(id) { |
||||
this.$emit('addStat'); |
||||
const { href } = this.$router.resolve({ |
||||
path: '/doctor/' + id |
||||
}); |
||||
window.open(href, '_blank'); |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
<style lang="scss"> |
||||
.doctor-item { |
||||
padding: 20px 10px 0; |
||||
width: 230px; |
||||
height: 385px; |
||||
background: $bg-color; |
||||
border-radius: 4px; |
||||
box-sizing: border-box; |
||||
text-align: center; |
||||
cursor: pointer; |
||||
& > img { |
||||
margin: 0 auto; |
||||
border: 1px solid #ededed; |
||||
background: $body-color; |
||||
@include roundFun(108px); |
||||
} |
||||
h5 { |
||||
margin-top: 10px; |
||||
font-size: 18px; |
||||
font-family: MicrosoftYaHei-Bold, MicrosoftYaHei; |
||||
font-weight: bold; |
||||
color: $main-blue-color; |
||||
line-height: 24px; |
||||
} |
||||
& > p { |
||||
font-size: 16px; |
||||
color: $font-color3; |
||||
line-height: 21px; |
||||
} |
||||
& > p:nth-child(3) { |
||||
margin: 11px 0 1px; |
||||
} |
||||
.expert-video-list { |
||||
margin-top: 21px; |
||||
p { |
||||
display: flex; |
||||
margin-bottom: 22px; |
||||
text-align: left; |
||||
align-items: center; |
||||
img { |
||||
margin-right: 10px; |
||||
@include roundFun(30px); |
||||
} |
||||
span { |
||||
@include textEllipsisMore1Line(2); |
||||
font-size: 16px; |
||||
color: $font-color1; |
||||
line-height: 21px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,95 @@
@@ -0,0 +1,95 @@
|
||||
<template> |
||||
<div class="doctor-video-box" @click="goDoctor(video.id)"> |
||||
<h6>{{ video.title }}</h6> |
||||
<span>{{ video.record_num }}次播放</span> |
||||
<p class="play-video"> |
||||
<img |
||||
src="~/assets/images/mobile_doctor_play.png" |
||||
alt="点击播放" |
||||
/>点击播放 |
||||
</p> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
export default { |
||||
props: { |
||||
video: { |
||||
type: Object, |
||||
default: null |
||||
} |
||||
}, |
||||
created() {}, |
||||
methods: { |
||||
goDoctor(id) { |
||||
this.$emit('addStat'); |
||||
const { href } = this.$router.resolve({ |
||||
path: '/doctor/' + id |
||||
}); |
||||
window.location.href = href; |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
<style lang="scss"> |
||||
.doctor-video-box { |
||||
position: relative; |
||||
padding: 20px 15px; |
||||
/*height: 127px;*/ |
||||
background: $body-color; |
||||
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.06); |
||||
box-sizing: border-box; |
||||
cursor: pointer; |
||||
h6 { |
||||
font-size: 18px; |
||||
font-family: PingFangSC-Medium, PingFang SC; |
||||
font-weight: 500; |
||||
color: #333; |
||||
line-height: 25px; |
||||
@include textEllipsisMore1Line(2); |
||||
} |
||||
span { |
||||
display: inline-block; |
||||
margin: 11px 0 0 -15px; |
||||
padding: 0 9px 0 14px; |
||||
height: 30px; |
||||
background: #f7f7fa; |
||||
border-radius: 0 69px 69px 0; |
||||
font-size: 14px; |
||||
font-family: PingFangSC-Regular, PingFang SC; |
||||
font-weight: 400; |
||||
color: #7d7d7d; |
||||
line-height: 30px; |
||||
} |
||||
p { |
||||
float: right; |
||||
margin-top: 10px; |
||||
width: 134px; |
||||
height: 32px; |
||||
background: linear-gradient(180deg, #fad961 0%, #f76b1c 100%); |
||||
border-radius: 20px; |
||||
font-size: 16px; |
||||
font-family: PingFangSC-Medium, PingFang SC; |
||||
font-weight: 500; |
||||
color: #fafafc; |
||||
line-height: 32px; |
||||
text-align: center; |
||||
img { |
||||
position: relative; |
||||
top: 5px; |
||||
display: inline-block; |
||||
margin-right: 6px; |
||||
width: 21px; |
||||
height: 21px; |
||||
} |
||||
} |
||||
&::after { |
||||
content: ''; |
||||
position: absolute; |
||||
bottom: 0; |
||||
left: 12px; |
||||
width: calc(100% - 24px); |
||||
height: 1px; |
||||
background: #ddd; |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,251 @@
@@ -0,0 +1,251 @@
|
||||
<template> |
||||
<div |
||||
class="mobile-header" |
||||
:style="{ position: isIndex ? (needFixed ? 'fixed' : '') : 'fixed' }" |
||||
> |
||||
<div ref="mobileHeader"> |
||||
<div> |
||||
<p |
||||
v-for="item in tabArr" |
||||
:key="item.name" |
||||
:class="{ chosenMobileTab: activeTab === item.name }" |
||||
@click="handleClick(item)" |
||||
> |
||||
{{ item.font }} |
||||
</p> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
function getDay() { |
||||
const today = new Date(); |
||||
const y = today.getFullYear(); |
||||
let m = today.getMonth() + 1; |
||||
let d = today.getDate(); |
||||
m = m < 10 ? '0' + m : m; |
||||
d = d < 10 ? '0' + d : d; |
||||
return y + '-' + m + '-' + d; |
||||
} |
||||
export default { |
||||
props: { |
||||
isIndex: { |
||||
type: Boolean, |
||||
default: false |
||||
}, |
||||
needFixed: { |
||||
type: Boolean, |
||||
default: false |
||||
}, |
||||
bannerHeight: { |
||||
type: Number, |
||||
default: 0 |
||||
}, |
||||
isMore: { |
||||
type: Boolean, |
||||
default: false |
||||
} |
||||
}, |
||||
data() { |
||||
return { |
||||
activeTab: '', |
||||
tabArr: [ |
||||
{ |
||||
font: '推荐', |
||||
name: 'index', |
||||
url: '/', |
||||
statInfo: { category: '推荐', des: '推荐tab' } |
||||
}, |
||||
{ |
||||
font: '视频', |
||||
name: 'video', |
||||
url: '/video', |
||||
statInfo: { category: '视频', des: '视频tab' } |
||||
}, |
||||
{ |
||||
font: '一问医答', |
||||
name: 'doctor', |
||||
url: '/doctor', |
||||
statInfo: { category: '一问医答', des: '一问医答tab' } |
||||
}, |
||||
{ |
||||
font: '药物', |
||||
name: 'article-medicine', |
||||
url: '/article?labelId=-1', |
||||
statInfo: { category: '文章', des: '文章-药物tab' } |
||||
}, |
||||
{ |
||||
font: '饮食', |
||||
name: 'article-food', |
||||
url: '/article?labelId=2', |
||||
statInfo: { category: '文章', des: '文章-饮食tab' } |
||||
}, |
||||
{ |
||||
font: '运动', |
||||
name: 'article-sport', |
||||
url: '/article?labelId=3', |
||||
statInfo: { category: '文章', des: '文章-运动tab' } |
||||
}, |
||||
{ |
||||
font: '并发症', |
||||
name: 'article-complication', |
||||
url: '/article?labelId=17', |
||||
statInfo: { category: '文章', des: '文章-并发症tab' } |
||||
}, |
||||
{ |
||||
font: '监测', |
||||
name: 'article-survey', |
||||
url: '/article?labelId=-2', |
||||
statInfo: { category: '文章', des: '文章-监测tab' } |
||||
}, |
||||
{ |
||||
font: '心理', |
||||
name: 'article-mind', |
||||
url: '/article?labelId=18', |
||||
statInfo: { category: '文章', des: '文章-心理tab' } |
||||
} |
||||
] |
||||
}; |
||||
}, |
||||
created() { |
||||
let activeName = this.$route.name; |
||||
if (this.$route.name === 'article') { |
||||
const labelId = Number(this.$route.query.labelId); |
||||
let affixArticle = ''; |
||||
switch (labelId) { |
||||
case -1: |
||||
affixArticle = 'medicine'; |
||||
break; |
||||
case 2: |
||||
affixArticle = 'food'; |
||||
break; |
||||
case 3: |
||||
affixArticle = 'sport'; |
||||
break; |
||||
case 17: |
||||
affixArticle = 'complication'; |
||||
break; |
||||
case -2: |
||||
affixArticle = 'survey'; |
||||
break; |
||||
case 18: |
||||
affixArticle = 'mind'; |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
activeName += '-' + affixArticle; |
||||
} |
||||
this.activeTab = activeName; |
||||
}, |
||||
mounted() { |
||||
if (!this.isMore) { |
||||
if (this.activeTab === 'index') { |
||||
if (!localStorage.getItem('indexTabAniDay')) { |
||||
this.animationFun(); |
||||
localStorage.setItem('indexTabAniDay', getDay()); |
||||
} else { |
||||
let _day = localStorage.getItem('indexTabAniDay'); |
||||
if (getDay() !== _day) { |
||||
this.animationFun(); |
||||
_day = getDay(); |
||||
localStorage.setItem('indexTabAniDay', _day); |
||||
} |
||||
} |
||||
} |
||||
const left = |
||||
document.getElementsByClassName('chosenMobileTab')[0].offsetLeft; |
||||
const centerL = |
||||
((document.documentElement.clientWidth || document.body.clientWidth) - |
||||
70) / |
||||
2; |
||||
document |
||||
.getElementsByClassName('mobile-header')[0] |
||||
.scrollTo(left - centerL, 0); |
||||
} |
||||
}, |
||||
methods: { |
||||
animationFun() { |
||||
const windowW = |
||||
document.documentElement.clientWidth || document.body.clientWidth; |
||||
const tabW = this.$refs.mobileHeader.clientWidth; |
||||
this.$refs.mobileHeader.animate( |
||||
[{ marginLeft: '0' }, { marginLeft: windowW - tabW + 'px' }], |
||||
{ |
||||
duration: 1000, |
||||
delay: 1000 |
||||
} |
||||
); |
||||
this.$refs.mobileHeader.animate( |
||||
[ |
||||
{ marginLeft: windowW - tabW + 'px' }, |
||||
{ marginLeft: windowW - tabW + 'px' } |
||||
], |
||||
{ |
||||
duration: 200, |
||||
delay: 2000 |
||||
} |
||||
); |
||||
this.$refs.mobileHeader.animate( |
||||
[{ marginLeft: windowW - tabW + 'px' }, { marginLeft: 0 }], |
||||
{ |
||||
duration: 1000, |
||||
delay: 2200 |
||||
} |
||||
); |
||||
}, |
||||
handleClick(item) { |
||||
if (item.name !== this.activeTab) { |
||||
this.baiduStat( |
||||
(this.isMore ? '更多页面-' : '导航栏-') + item.statInfo.category, |
||||
'click', |
||||
item.statInfo.des |
||||
); |
||||
const { href } = this.$router.resolve({ |
||||
path: item.url |
||||
}); |
||||
|
||||
window.location.href = href; |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
<style lang="scss"> |
||||
.mobile-header { |
||||
overflow-x: scroll; |
||||
top: 60px; |
||||
display: flex; |
||||
border-bottom: 1px solid $bg-color; |
||||
width: 100%; |
||||
height: 48px; |
||||
background: $body-color; |
||||
white-space: nowrap; |
||||
z-index: 2; |
||||
& > div { |
||||
& > div { |
||||
display: flex; |
||||
overflow: hidden; |
||||
height: 48px; |
||||
position: relative; |
||||
p { |
||||
flex: none; |
||||
width: 70px; |
||||
font-size: 15px; |
||||
font-family: PingFangSC-Regular, PingFang SC; |
||||
font-weight: 400; |
||||
color: $font-color1; |
||||
line-height: 48px; |
||||
text-align: center; |
||||
cursor: pointer; |
||||
&.chosenMobileTab { |
||||
font-size: 16px; |
||||
font-family: PingFangSC-Medium, PingFang SC; |
||||
font-weight: 500; |
||||
color: $main-blue-color; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,74 @@
@@ -0,0 +1,74 @@
|
||||
<template> |
||||
<div class="mobile-not-login"> |
||||
<i class="el-icon-error" @click="hideClick"></i> |
||||
<img src="~/assets/images/wechat_color.png" alt="" /> |
||||
<p>关注公众号登录,查看更多资讯</p> |
||||
<p |
||||
@click=" |
||||
baiduStat('移动端-底部控件', 'click', '移动端底部登录控件'); |
||||
showLoginDialog(true); |
||||
" |
||||
> |
||||
GO |
||||
</p> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
import { createNamespacedHelpers } from 'vuex'; |
||||
|
||||
const { mapActions } = createNamespacedHelpers('user'); |
||||
export default { |
||||
methods: { |
||||
...mapActions({ |
||||
showLoginDialog: 'showLoginDialog' |
||||
}), |
||||
hideClick() { |
||||
this.$emit('hideClick'); |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
<style lang="scss"> |
||||
.mobile-not-login { |
||||
position: fixed; |
||||
bottom: 0; |
||||
left: 0; |
||||
display: flex; |
||||
padding: 10px 15px; |
||||
padding-bottom: calc(constant(safe-area-inset-bottom) + 10px); |
||||
padding-bottom: calc(env(safe-area-inset-bottom) + 10px); |
||||
width: calc(100% - 30px); |
||||
height: 35px; |
||||
background: $body-color; |
||||
align-items: center; |
||||
z-index: 9; |
||||
i { |
||||
font-size: 14px; |
||||
color: #bac0c2; |
||||
} |
||||
img { |
||||
margin: 0 2px 0 5px; |
||||
width: 26px; |
||||
height: 26px; |
||||
} |
||||
p:nth-child(3) { |
||||
font-size: 15px; |
||||
color: $font-color1; |
||||
line-height: 20px; |
||||
} |
||||
p:last-child { |
||||
position: absolute; |
||||
right: 15px; |
||||
width: 75px; |
||||
height: 35px; |
||||
background: $extra-red; |
||||
border-radius: 4px; |
||||
font-size: 18px; |
||||
font-family: PingFangSC-Medium, PingFang SC; |
||||
font-weight: 500; |
||||
color: $body-color; |
||||
line-height: 35px; |
||||
text-align: center; |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,304 @@
@@ -0,0 +1,304 @@
|
||||
<template> |
||||
<div> |
||||
<div class="top-user-info"> |
||||
<div> |
||||
<div class="left-content"> |
||||
<template v-if="deviceType === 'pc'"> |
||||
<el-avatar :size="100" :src="userImg"></el-avatar> |
||||
<p>{{ userName }}</p> |
||||
<NuxtLink |
||||
to="/user/setting" |
||||
target="_blank" |
||||
@click.native=" |
||||
baiduStat('我的账户页', 'click', '我的账户页-点击设置') |
||||
" |
||||
><i class="el-icon-s-tools"></i>账户设置</NuxtLink |
||||
> |
||||
</template> |
||||
<a |
||||
v-else |
||||
href="/user/setting" |
||||
@click="baiduStat('我的账户页', 'click', '我的账户页-点击设置')" |
||||
> |
||||
<el-avatar :size="100" :src="userImg"></el-avatar> |
||||
<p>{{ userName }}</p> |
||||
<i class="el-icon-s-tools"></i> |
||||
</a> |
||||
</div> |
||||
<div class="right-content"> |
||||
<img src="~/assets/images/beans.png" alt="" /> |
||||
<p>我的金豆</p> |
||||
<h5 |
||||
@click=" |
||||
baiduStat('我的账户页', 'click', '我的账户页-点击金豆余额'); |
||||
dialogVisible = true; |
||||
" |
||||
> |
||||
{{ beanNum }}<i class="el-icon-caret-right"></i> |
||||
</h5> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<div class="user-collect"> |
||||
<h6> |
||||
我的收藏 <span>{{ total }}</span> |
||||
</h6> |
||||
<div class="common-flex"> |
||||
<template v-for="item in articleList"> |
||||
<VideoArticleListItem |
||||
:key="'collect' + item.id" |
||||
:detail="item" |
||||
:column-num="4" |
||||
:device-type="deviceType" |
||||
@addStat=" |
||||
baiduStat('我的账户页', 'click', '我的账户页-点击收藏的文章') |
||||
" |
||||
/> |
||||
</template> |
||||
</div> |
||||
<p v-if="collectLoading" class="load-more"> |
||||
加载更多<i class="el-icon-loading"></i> |
||||
</p> |
||||
</div> |
||||
<el-dialog |
||||
title="" |
||||
:visible.sync="dialogVisible" |
||||
custom-class="beans-popup" |
||||
:show-close="false" |
||||
:width="deviceType === 'pc' ? '795px' : '280px'" |
||||
> |
||||
<div class="popup-content"> |
||||
<img |
||||
v-if="deviceType === 'pc'" |
||||
src="~/assets/images/beans_popup_bg.png" |
||||
alt="" |
||||
/> |
||||
<div> |
||||
<p> |
||||
<img src="~/assets/images/wechat_white.png" alt="" />扫码前往公众号 |
||||
</p> |
||||
<img :src="isPro ? qrcodeUrl : qrcodeUrlTest" alt="" /> |
||||
<h5>公众号内做任务赢金豆<br />海量精美礼品免费兑换</h5> |
||||
</div> |
||||
</div> |
||||
</el-dialog> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
import { createNamespacedHelpers } from 'vuex'; |
||||
const { mapState } = createNamespacedHelpers('user'); |
||||
export default { |
||||
props: { |
||||
beanNum: { |
||||
type: Number, |
||||
default: 0 |
||||
}, |
||||
total: { |
||||
type: Number, |
||||
default: 0 |
||||
}, |
||||
articleList: { |
||||
type: Array, |
||||
default: () => [] |
||||
}, |
||||
hasMore: { |
||||
type: Boolean, |
||||
default: true |
||||
}, |
||||
collectLoading: { |
||||
type: Boolean, |
||||
default: false |
||||
} |
||||
}, |
||||
data() { |
||||
return { |
||||
dialogVisible: false, |
||||
isPro: false, |
||||
qrcodeUrl: require('~/assets/images/follow_qrcode.png'), |
||||
qrcodeUrlTest: require('~/assets/images/follow_qrcode_test.png') |
||||
}; |
||||
}, |
||||
computed: { |
||||
deviceType() { |
||||
return this.$store.state.device.deviceType; |
||||
}, |
||||
...mapState({ |
||||
userInfo: (state) => state.info |
||||
}), |
||||
userName() { |
||||
if ( |
||||
this.userInfo !== null && |
||||
this.userInfo.name !== null && |
||||
this.userInfo.name !== '' |
||||
) { |
||||
return this.userInfo.name; |
||||
} |
||||
return '--'; |
||||
}, |
||||
userImg() { |
||||
if ( |
||||
this.userInfo !== null && |
||||
this.userInfo.headimg !== null && |
||||
this.userInfo.headimg !== '' |
||||
) { |
||||
return this.userInfo.headimg; |
||||
} |
||||
return 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png'; |
||||
} |
||||
}, |
||||
created() { |
||||
this.isPro = process.env.VUE_APP_TITLE === 'production'; |
||||
} |
||||
}; |
||||
</script> |
||||
<style lang="scss"> |
||||
.top-user-info { |
||||
position: absolute; |
||||
top: 86px; |
||||
left: 0; |
||||
width: 100%; |
||||
min-width: $outer-width; |
||||
height: 259px; |
||||
background: $bg-color; |
||||
& > div { |
||||
margin: 0 auto; |
||||
width: $content-width; |
||||
& > div { |
||||
margin-top: 36px; |
||||
height: 183px; |
||||
background: $body-color; |
||||
box-sizing: border-box; |
||||
} |
||||
.left-content { |
||||
position: relative; |
||||
padding: 82px 272px 0 153px; |
||||
& > span { |
||||
position: absolute; |
||||
top: 44px; |
||||
left: 37px; |
||||
} |
||||
& > p { |
||||
font-size: 18px; |
||||
font-family: MicrosoftYaHei-Bold, MicrosoftYaHei; |
||||
font-weight: bold; |
||||
color: $font-color1; |
||||
line-height: 24px; |
||||
@extend .text-ellipsis; |
||||
} |
||||
& > a { |
||||
position: absolute; |
||||
top: 69px; |
||||
right: 44px; |
||||
width: 208px; |
||||
height: 50px; |
||||
background: #3099ea; |
||||
border-radius: 4px; |
||||
text-align: center; |
||||
font-size: 18px; |
||||
font-family: PingFangSC-Regular, PingFang SC; |
||||
font-weight: 400; |
||||
color: $body-color; |
||||
line-height: 50px; |
||||
i { |
||||
margin-right: 5px; |
||||
} |
||||
} |
||||
} |
||||
.right-content { |
||||
position: relative; |
||||
padding: 65px 0 0 159px; |
||||
& > img { |
||||
position: absolute; |
||||
top: 57px; |
||||
left: 69px; |
||||
width: 74px; |
||||
height: 74px; |
||||
} |
||||
p { |
||||
font-size: 15px; |
||||
color: $font-color3; |
||||
line-height: 20px; |
||||
} |
||||
h5 { |
||||
margin-top: 8px; |
||||
font-size: 24px; |
||||
font-family: MicrosoftYaHei-Bold, MicrosoftYaHei; |
||||
font-weight: bold; |
||||
color: $extra-red; |
||||
line-height: 31px; |
||||
cursor: pointer; |
||||
i { |
||||
font-size: 20px; |
||||
color: $extra-blue; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.user-collect { |
||||
padding-top: 50px; |
||||
& > h6 { |
||||
margin-bottom: 10px; |
||||
font-size: 24px; |
||||
font-family: PingFangSC-Medium, PingFang SC; |
||||
font-weight: 500; |
||||
color: $main-blue-color; |
||||
line-height: 33px; |
||||
span { |
||||
color: $extra-red; |
||||
} |
||||
} |
||||
.common-flex { |
||||
justify-content: flex-start; |
||||
.detail-list-item { |
||||
margin: 0 19.3px 20px 0; |
||||
} |
||||
.detail-list-item:nth-child(4n) { |
||||
margin-right: 0; |
||||
} |
||||
} |
||||
} |
||||
.beans-popup { |
||||
background: transparent; |
||||
box-shadow: none; |
||||
.el-dialog__header { |
||||
padding: 0; |
||||
} |
||||
.el-dialog__body { |
||||
padding: 0; |
||||
.popup-content { |
||||
position: relative; |
||||
& > img { |
||||
width: 795px; |
||||
height: 407px; |
||||
} |
||||
& > div { |
||||
position: absolute; |
||||
right: 231px; |
||||
bottom: 29px; |
||||
text-align: center; |
||||
color: $body-color; |
||||
p { |
||||
font-size: 16px; |
||||
line-height: 24px; |
||||
img { |
||||
margin-right: 8px; |
||||
width: 24px; |
||||
} |
||||
} |
||||
& > img { |
||||
margin: 12px 0 9px; |
||||
width: 143px; |
||||
height: 143px; |
||||
} |
||||
h5 { |
||||
font-size: 24px; |
||||
font-family: MicrosoftYaHei-Bold, MicrosoftYaHei; |
||||
font-weight: bold; |
||||
line-height: 36px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,375 @@
@@ -0,0 +1,375 @@
|
||||
<template> |
||||
<div |
||||
v-if="detail.mainModule == 38" |
||||
class="only-img detail-list-item large-width" |
||||
:class=" |
||||
'one-line-columns-' + columnNum + (deviceType !== 'pc' ? ' isMobile' : '') |
||||
" |
||||
@click="goHref(detail.action_url)" |
||||
> |
||||
<img :src="detail.image_url" alt="" /> |
||||
</div> |
||||
<div |
||||
v-else |
||||
class="detail-list-item" |
||||
:class=" |
||||
(detail.showType == 2 ? 'large-width ' : '') + |
||||
('one-line-columns-' + columnNum) + |
||||
(deviceType !== 'pc' ? ' isMobile' : '') + |
||||
(detail.mainModule == 47 ? ' video-item' : ' article-item') + |
||||
(detail.intro && detail.intro !== '' ? ' has-intro' : ' no-intro') |
||||
" |
||||
@click=" |
||||
goHref((detail.mainModule == 47 ? '/video/' : '/article/') + detail.id) |
||||
" |
||||
> |
||||
<div class="top-img-box"> |
||||
<img |
||||
v-if="detail.mainModule !== 47 && !detail.thumb" |
||||
src="~/assets/images/article_cover.png" |
||||
alt="" |
||||
/> |
||||
<img |
||||
v-else |
||||
:src="detail.mainModule == 47 ? detail.video_cover_url : detail.thumb" |
||||
alt="" |
||||
/> |
||||
<p v-if="deviceType !== 'pc' && detail.intro && detail.intro !== ''"> |
||||
{{ detail.intro }} |
||||
</p> |
||||
<template v-if="detail.mainModule == 47"> |
||||
<span |
||||
>{{ |
||||
parseInt(detail.video_time / 60) > 9 |
||||
? parseInt(detail.video_time / 60) |
||||
: '0' + parseInt(detail.video_time / 60) |
||||
}}:{{ |
||||
parseInt(detail.video_time % 60) > 9 |
||||
? parseInt(detail.video_time % 60) |
||||
: '0' + parseInt(detail.video_time % 60) |
||||
}}</span |
||||
> |
||||
<img class="play" src="~/assets/images/video_play_icon.png" alt="" /> |
||||
</template> |
||||
</div> |
||||
<p>{{ detail.title }}</p> |
||||
<div class="bottom"> |
||||
<span |
||||
:style="{ |
||||
display: ( |
||||
detail.mainModule == 47 ? detail.tag_name : detail.labelName |
||||
) |
||||
? '' |
||||
: 'none' |
||||
}" |
||||
>{{ |
||||
detail.mainModule == 47 ? detail.tag_name : detail.labelName |
||||
}}</span |
||||
> |
||||
<span |
||||
>{{ detail.mainModule == 47 ? detail.play_num : detail.hit |
||||
}}<template v-if="deviceType !== 'pc'" |
||||
>{{ detail.mainModule == 47 ? '播放' : '阅读' }} </template |
||||
><i v-else class="el-icon-view" style="margin-right: 8px"></i |
||||
>{{ detail.mainModule == 47 ? detail.like_num : detail.collect |
||||
}}<template v-if="deviceType !== 'pc'" |
||||
>{{ detail.mainModule == 47 ? '喜欢' : '收藏' }} </template |
||||
><template v-else> |
||||
<img |
||||
v-if="detail.mainModule == 47" |
||||
src="~/assets/images/heart_gray.png" |
||||
alt="" |
||||
/><i |
||||
v-else |
||||
class="el-icon-star-on" |
||||
style="margin-left: 2px; font-size: 18px" |
||||
></i> </template |
||||
></span> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
export default { |
||||
props: { |
||||
detail: { |
||||
type: Object, |
||||
default: null |
||||
}, |
||||
columnNum: { |
||||
type: Number, |
||||
default: 1 |
||||
}, |
||||
deviceType: { |
||||
type: String, |
||||
default: 'pc' |
||||
} |
||||
}, |
||||
created() {}, |
||||
methods: { |
||||
goHref(url) { |
||||
this.$emit('addStat'); |
||||
let openNew = false; |
||||
if (this.deviceType === 'pc') { |
||||
openNew = true; |
||||
} |
||||
if (openNew) { |
||||
window.open(url, '_blank'); |
||||
} else { |
||||
window.location.href = url; |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
<style lang="scss"> |
||||
.detail-list-item { |
||||
display: block; |
||||
overflow: hidden; |
||||
position: relative; |
||||
margin-bottom: 18px; |
||||
background: $bg-color; |
||||
border-radius: 4px; |
||||
cursor: pointer; |
||||
.top-img-box { |
||||
position: relative; |
||||
height: 131px; |
||||
& > img:first-child { |
||||
width: 100%; |
||||
height: 100%; |
||||
} |
||||
span { |
||||
position: absolute; |
||||
top: 12px; |
||||
right: 12px; |
||||
padding: 0 9px; |
||||
height: 24px; |
||||
background: rgba(0, 0, 0, 0.4); |
||||
font-size: 14px; |
||||
font-family: PingFangSC-Regular, PingFang SC; |
||||
font-weight: 400; |
||||
color: $body-color; |
||||
line-height: 24px; |
||||
border-radius: 4px; |
||||
} |
||||
& > img.play { |
||||
position: absolute; |
||||
top: 50%; |
||||
left: 50%; |
||||
margin: -34px 0 0 -34px; |
||||
width: 68px; |
||||
height: 67px; |
||||
} |
||||
} |
||||
& > p { |
||||
padding: 12px 10px 0; |
||||
font-size: 16px; |
||||
color: $font-color2; |
||||
line-height: 26px; |
||||
@include textEllipsisMore1Line(2); |
||||
} |
||||
.bottom { |
||||
position: absolute; |
||||
bottom: 0; |
||||
left: 0; |
||||
padding: 0 10px 22px; |
||||
width: 100%; |
||||
height: 46px; |
||||
box-sizing: border-box; |
||||
span:first-child { |
||||
padding: 0 9px; |
||||
height: 24px; |
||||
border-radius: 4px; |
||||
border: 1px solid #bac0c2; |
||||
box-sizing: border-box; |
||||
font-size: 14px; |
||||
font-family: PingFangSC-Regular, PingFang SC; |
||||
font-weight: 400; |
||||
color: $font-color3; |
||||
line-height: 22px; |
||||
} |
||||
span:last-child { |
||||
float: right; |
||||
font-size: 16px; |
||||
font-family: Apis-Regular, Apis; |
||||
color: #bac0c2; |
||||
line-height: 24px; |
||||
i { |
||||
margin-left: 4px; |
||||
} |
||||
img { |
||||
margin: 4px 0 0 4px; |
||||
width: 16px; |
||||
} |
||||
} |
||||
} |
||||
&.one-line-columns-3 { |
||||
width: 230px; |
||||
height: 274px; |
||||
} |
||||
&.one-line-columns-4 { |
||||
width: 255px; |
||||
height: 298px; |
||||
.top-img-box { |
||||
height: 144px; |
||||
} |
||||
& > p { |
||||
padding-top: 18px; |
||||
} |
||||
.bottom { |
||||
padding-bottom: 30px; |
||||
height: 54px; |
||||
} |
||||
&.large-width { |
||||
position: relative; |
||||
width: 529px; |
||||
grid-column-start: span 2; |
||||
.top-img-box { |
||||
height: 100%; |
||||
& > img.play { |
||||
display: none; |
||||
} |
||||
} |
||||
&::after { |
||||
content: ''; |
||||
position: absolute; |
||||
bottom: 0; |
||||
left: 0; |
||||
width: 100%; |
||||
height: 120px; |
||||
background: linear-gradient( |
||||
180deg, |
||||
rgba(0, 0, 0, 0) 0%, |
||||
rgba(0, 0, 0, 0.4) 100% |
||||
); |
||||
} |
||||
& > p { |
||||
position: absolute; |
||||
bottom: 62px; |
||||
left: 12px; |
||||
padding: 0; |
||||
width: calc(100% - 24px); |
||||
@extend .text-ellipsis; |
||||
z-index: 1; |
||||
font-size: 18px; |
||||
color: $body-color; |
||||
} |
||||
.bottom { |
||||
/*padding: 0 12px 14px;*/ |
||||
/*height: 38px;*/ |
||||
z-index: 1; |
||||
span:first-child { |
||||
border-color: rgba(255, 255, 255, 0.6); |
||||
color: $body-color; |
||||
} |
||||
span:last-child { |
||||
color: $body-color; |
||||
} |
||||
} |
||||
&.only-img { |
||||
&::after { |
||||
display: none; |
||||
} |
||||
& > img { |
||||
width: 100%; |
||||
height: 100%; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
&.isMobile { |
||||
position: relative; |
||||
display: flex; |
||||
margin-bottom: 1px !important; |
||||
padding: 15px 15px 43px; |
||||
width: 100% !important; |
||||
height: auto !important; |
||||
flex-direction: column-reverse; |
||||
background: $body-color; |
||||
box-sizing: border-box; |
||||
& > p { |
||||
position: unset !important; |
||||
display: block; |
||||
margin-bottom: 10px; |
||||
padding: 0; |
||||
width: 100% !important; |
||||
font-size: 18px; |
||||
font-family: PingFangSC-Medium, PingFang SC; |
||||
font-weight: 500; |
||||
color: $font-color1 !important; |
||||
line-height: 25px; |
||||
white-space: normal !important; |
||||
} |
||||
.top-img-box { |
||||
height: auto; |
||||
img { |
||||
border-radius: 6px; |
||||
} |
||||
span { |
||||
top: auto; |
||||
bottom: 12px; |
||||
} |
||||
img.play { |
||||
display: block !important; |
||||
} |
||||
} |
||||
.bottom { |
||||
position: absolute; |
||||
bottom: 13px; |
||||
left: 15px; |
||||
padding: 0; |
||||
width: auto; |
||||
height: 20px; |
||||
span:first-child { |
||||
display: none; |
||||
} |
||||
span:last-child { |
||||
font-size: 14px; |
||||
font-family: PingFangSC-Regular, PingFang SC; |
||||
font-weight: 400; |
||||
color: #bac0c2 !important; |
||||
line-height: 20px; |
||||
} |
||||
} |
||||
&.article-item { |
||||
.top-img-box { |
||||
position: relative; |
||||
padding-right: 125px; |
||||
height: 80px; |
||||
img { |
||||
position: absolute; |
||||
top: 0; |
||||
right: 0; |
||||
width: 110px; |
||||
height: 80px; |
||||
border-radius: 6px; |
||||
} |
||||
} |
||||
&.no-intro { |
||||
& > p { |
||||
position: absolute !important; |
||||
top: 15px; |
||||
padding-right: 125px; |
||||
width: calc(100% - 30px) !important; |
||||
box-sizing: border-box; |
||||
@include textEllipsisMore1Line(3); |
||||
} |
||||
} |
||||
&.has-intro { |
||||
.top-img-box { |
||||
p { |
||||
@include textEllipsisMore1Line(3); |
||||
font-size: 16px; |
||||
font-family: PingFangSC-Regular, PingFang SC; |
||||
font-weight: 400; |
||||
color: $font-color2; |
||||
line-height: 24px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
&::after { |
||||
display: none; |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,143 @@
@@ -0,0 +1,143 @@
|
||||
<template> |
||||
<div class="web-footer" :class="{ isMobile: deviceType !== 'pc' }"> |
||||
<template v-if="deviceType !== 'pc'"> |
||||
<p> |
||||
© {{ new Date().getFullYear() }} 糖尿病网 |
||||
<a |
||||
href="https://www.diabetes.com.cn/uploadfile/jpg/medicine_info_service_diabetes.jpg" |
||||
target="_blank" |
||||
@click=" |
||||
baiduStat( |
||||
'药品医疗器械网络信息服务备案', |
||||
'click', |
||||
'药品医疗器械网络信息服务备案' |
||||
) |
||||
" |
||||
>药品医疗器械网络信息服务备案:(京) 网药械信息备字 (2023)第00432号</a |
||||
><br /> |
||||
<a |
||||
href="https://beian.miit.gov.cn/" |
||||
target="_blank" |
||||
@click="baiduStat('icp证书', 'click', 'icp证书')" |
||||
>京ICP备14012503号-4</a |
||||
><br /> |
||||
<a |
||||
href="http://www.beian.gov.cn/" |
||||
target="_blank" |
||||
@click="baiduStat('公安备案', 'click', '公安备案')" |
||||
>京公网安备 11000002002023号</a |
||||
> |
||||
</p> |
||||
</template> |
||||
<template v-else> |
||||
<template v-if="detailCommon"> |
||||
<p> |
||||
© {{ new Date().getFullYear() }} 糖尿病网 <a |
||||
href="https://www.diabetes.com.cn/uploadfile/jpg/medicine_info_service_diabetes.jpg" |
||||
target="_blank" |
||||
@click=" |
||||
baiduStat( |
||||
'药品医疗器械网络信息服务备案', |
||||
'click', |
||||
'药品医疗器械网络信息服务备案' |
||||
) |
||||
" |
||||
>药品医疗器械网络信息服务备案:(京) 网药械信息备字 |
||||
(2023)第00432号</a |
||||
> <a |
||||
href="https://beian.miit.gov.cn/" |
||||
target="_blank" |
||||
@click="baiduStat('icp证书', 'click', 'icp证书')" |
||||
>京ICP备14012503号-4</a |
||||
> <a |
||||
href="http://www.beian.gov.cn/" |
||||
target="_blank" |
||||
@click="baiduStat('公安备案', 'click', '公安备案')" |
||||
>京公网安备 11000002002023号</a |
||||
> |
||||
</p> |
||||
</template> |
||||
<template v-else> |
||||
<p> |
||||
© {{ new Date().getFullYear() }} 糖尿病网 <a |
||||
href="https://www.diabetes.com.cn/uploadfile/jpg/medicine_info_service_diabetes.jpg" |
||||
target="_blank" |
||||
@click=" |
||||
baiduStat( |
||||
'药品医疗器械网络信息服务备案', |
||||
'click', |
||||
'药品医疗器械网络信息服务备案' |
||||
) |
||||
" |
||||
>药品医疗器械网络信息服务备案:(京) 网药械信息备字 |
||||
(2023)第00432号</a |
||||
> <a |
||||
href="https://beian.miit.gov.cn/" |
||||
target="_blank" |
||||
@click="baiduStat('icp证书', 'click', 'icp证书')" |
||||
>京ICP备14012503号-4</a |
||||
> <a |
||||
href="http://www.beian.gov.cn/" |
||||
target="_blank" |
||||
@click="baiduStat('公安备案', 'click', '公安备案')" |
||||
>京公网安备 11000002002023号</a |
||||
> |
||||
</p> |
||||
</template> |
||||
</template> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
export default { |
||||
props: { |
||||
detailCommon: Boolean, |
||||
deviceType: { |
||||
type: String, |
||||
default: 'pc' |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
<style lang="scss"> |
||||
.web-footer { |
||||
margin: 0 auto; |
||||
padding-top: 18px; |
||||
width: $content-width; |
||||
height: 66px; |
||||
text-align: left; |
||||
box-sizing: border-box; |
||||
p { |
||||
font-size: 12px; |
||||
font-family: PingFangSC-Regular, PingFang SC; |
||||
font-weight: 400; |
||||
color: $font-color3; |
||||
line-height: 30px; |
||||
span { |
||||
float: right; |
||||
} |
||||
a { |
||||
color: $font-color3; |
||||
} |
||||
} |
||||
&.isMobile { |
||||
padding-top: 0 !important; |
||||
padding-bottom: constant(safe-area-inset-bottom); |
||||
padding-bottom: env(safe-area-inset-bottom); |
||||
width: 100%; |
||||
height: auto; |
||||
box-sizing: border-box; |
||||
background: $main-blue-color; |
||||
text-align: center; |
||||
p { |
||||
color: $body-color !important; |
||||
a { |
||||
color: $body-color !important; |
||||
} |
||||
} |
||||
p:first-child { |
||||
padding: 15px 0; |
||||
line-height: 16px !important; |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,115 @@
@@ -0,0 +1,115 @@
|
||||
<template> |
||||
<div class="web-header"> |
||||
<NuxtLink |
||||
to="/other/about" |
||||
target="_blank" |
||||
@click.native="baiduStat('关于我们', 'click', '关于我们')" |
||||
>关于我们</NuxtLink |
||||
> |
||||
<NuxtLink |
||||
to="/other/agreement" |
||||
target="_blank" |
||||
@click.native="baiduStat('用户协议', 'click', '用户协议')" |
||||
>用户协议</NuxtLink |
||||
> |
||||
<NuxtLink |
||||
to="/other/privacy" |
||||
target="_blank" |
||||
@click.native="baiduStat('隐私政策', 'click', '隐私政策')" |
||||
>隐私政策</NuxtLink |
||||
> |
||||
<NuxtLink |
||||
to="/other/disclaimer" |
||||
style="display: none" |
||||
target="_blank" |
||||
@click.native="baiduStat('免责声明', 'click', '免责声明')" |
||||
>免责声明</NuxtLink |
||||
> |
||||
<NuxtLink |
||||
to="/other/link" |
||||
style="display: none" |
||||
target="_blank" |
||||
@click.native="baiduStat('友情链接', 'click', '友情链接')" |
||||
>友情链接</NuxtLink |
||||
> |
||||
<NuxtLink |
||||
to="/other/cookies" |
||||
target="_blank" |
||||
@click.native="baiduStat('cookies政策', 'click', 'cookies政策')" |
||||
>cookies政策</NuxtLink |
||||
> |
||||
<NuxtLink |
||||
to="/other/corporate" |
||||
target="_blank" |
||||
@click.native="baiduStat('媒体合作', 'click', '媒体合作')" |
||||
>媒体合作</NuxtLink |
||||
> |
||||
<el-popover |
||||
placement="top-start" |
||||
width="420" |
||||
:visible-arrow="false" |
||||
popper-class="feedback-popover" |
||||
trigger="hover" |
||||
> |
||||
<div class="feedback-box"> |
||||
<h6>意见反馈</h6> |
||||
<p> |
||||
您在使用网站中发现了哪些问题,可以发送邮件至 |
||||
<a |
||||
href="mailto:DHcommunications@novonordisk.com" |
||||
target="_blank" |
||||
@click="baiduStat('意见反馈', 'click', '意见反馈')" |
||||
>DHcommunications@novonordisk.com</a |
||||
> |
||||
向我们反馈~ |
||||
</p> |
||||
</div> |
||||
<p slot="reference">意见反馈</p> |
||||
</el-popover> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
export default {}; |
||||
</script> |
||||
<style lang="scss"> |
||||
.web-header { |
||||
margin: 0 auto; |
||||
width: $content-width; |
||||
height: 30px; |
||||
font-size: 14px; |
||||
color: $body-color; |
||||
line-height: 30px; |
||||
a { |
||||
margin-right: 44px; |
||||
color: $body-color; |
||||
} |
||||
& > span { |
||||
float: right; |
||||
p { |
||||
display: inline-block; |
||||
cursor: pointer; |
||||
} |
||||
} |
||||
} |
||||
.feedback-popover { |
||||
padding: 30px 26px 42px; |
||||
box-sizing: border-box; |
||||
text-align: center; |
||||
.feedback-box { |
||||
h6 { |
||||
font-size: 18px; |
||||
color: $main-blue-color; |
||||
line-height: 24px; |
||||
} |
||||
p { |
||||
margin-top: 16px; |
||||
font-size: 16px; |
||||
color: $font-color1; |
||||
line-height: 24px; |
||||
a { |
||||
color: $font-color1; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,122 @@
@@ -0,0 +1,122 @@
|
||||
<template> |
||||
<div |
||||
class="outer-container" |
||||
:class="{ |
||||
isMobile: deviceType !== 'pc', |
||||
hasLoginBottom: deviceType !== 'pc' && !isLogin && !hasCloseMobileNotLogin |
||||
}" |
||||
> |
||||
<div class="content-container common-page"> |
||||
<CommonHeader |
||||
:device-type="deviceType" |
||||
:scroll-left="scrollLeft" |
||||
:has-sub-menu-color="true" |
||||
:tab-type="1" |
||||
:search-height="searchHeight" |
||||
@func="getMsgFormSon" |
||||
/> |
||||
<MobileHeader v-if="deviceType !== 'pc'" /> |
||||
<Nuxt /> |
||||
<div class="footer-outer" :style="{ left: -scrollLeft + 'px' }"> |
||||
<WebFooter :device-type="deviceType" /> |
||||
</div> |
||||
<BottomRightFixed /> |
||||
<NotLogin |
||||
v-if="deviceType !== 'pc' && !isLogin && !hasCloseMobileNotLogin" |
||||
@hideClick="hasCloseMobileNotLogin = true" |
||||
/> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import { createNamespacedHelpers } from 'vuex'; |
||||
|
||||
const { mapGetters } = createNamespacedHelpers('user'); |
||||
export default { |
||||
data() { |
||||
return { |
||||
scrollLeft: 0, |
||||
searchHeight: 0, |
||||
hasCloseMobileNotLogin: false |
||||
}; |
||||
}, |
||||
computed: { |
||||
...mapGetters({ |
||||
isLogin: 'isLogin' |
||||
}), |
||||
deviceType() { |
||||
return this.$store.state.device.deviceType; |
||||
} |
||||
}, |
||||
mounted() { |
||||
const that = this; |
||||
this.$nextTick(() => { |
||||
const windowHeight = |
||||
document.documentElement.clientHeight || document.body.clientHeight; |
||||
that.searchHeight = windowHeight - 86 - 66; |
||||
window.addEventListener('scroll', function () { |
||||
// 变量scrollTop是滚动条滚动时,距离顶部的距离 |
||||
const scrollLeft = |
||||
document.documentElement.scrollLeft || document.body.scrollLeft; |
||||
that.scrollLeft = scrollLeft; |
||||
}); |
||||
window.addEventListener('resize', function () { |
||||
const windowHeight = |
||||
document.documentElement.clientHeight || document.body.clientHeight; |
||||
that.searchHeight = windowHeight - 86 - 66; |
||||
}); |
||||
}); |
||||
}, |
||||
methods: { |
||||
// 接收 CommonHeader 传递过来的值 |
||||
getMsgFormSon(data) { |
||||
this.msgFormSon = data; |
||||
console.log(this.msgFormSon); |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
<style lang="scss"> |
||||
.common-page { |
||||
padding: 86px 0 76px; |
||||
.common-header { |
||||
.top-menu { |
||||
.el-menu-item.is-active p, |
||||
.el-submenu.is-active .el-submenu__title { |
||||
font-family: MicrosoftYaHei-Bold, MicrosoftYaHei; |
||||
font-weight: bold; |
||||
} |
||||
.el-menu-item.is-active, |
||||
.el-submenu.is-active .el-submenu__title { |
||||
position: relative; |
||||
&::after { |
||||
position: absolute; |
||||
content: ''; |
||||
bottom: 24px; |
||||
left: 50%; |
||||
margin-left: -15px; |
||||
width: 30px; |
||||
height: 4px; |
||||
background: $main-blue-color; |
||||
border-radius: 2px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.isMobile { |
||||
.common-page { |
||||
padding-bottom: 0; |
||||
} |
||||
} |
||||
.active-color { |
||||
.el-menu--popup { |
||||
.el-menu-item.is-active { |
||||
p { |
||||
color: $font-color2 !important; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,245 @@
@@ -0,0 +1,245 @@
|
||||
<template> |
||||
<div |
||||
class="outer-container" |
||||
:class="{ |
||||
isMobile: deviceType !== 'pc', |
||||
hasLoginBottom: deviceType !== 'pc' && !isLogin && !hasCloseMobileNotLogin |
||||
}" |
||||
> |
||||
<div class="content-container detail-page"> |
||||
<CommonHeader |
||||
:device-type="deviceType" |
||||
:scroll-left="scrollLeft" |
||||
:tab-type="tabType" |
||||
:search-height="searchHeight" |
||||
:show-close="headShowClose" |
||||
@func="getMsgFormSon" |
||||
/> |
||||
<Nuxt /> |
||||
<div |
||||
class="bottom-outer" |
||||
:style="{ minWidth: deviceType === 'pc' ? '1258px' : '' }" |
||||
> |
||||
<WebHeader v-if="deviceType === 'pc'" /> |
||||
<WebFooter :device-type="deviceType" :detail-common="true" /> |
||||
<div v-if="deviceType === 'pc'" class="follow-box"> |
||||
<div> |
||||
<div> |
||||
<div> |
||||
<h5> |
||||
<p> |
||||
<img |
||||
src="~/assets/images/wechat_white.png" |
||||
alt="微信扫码" |
||||
/> |
||||
</p> |
||||
微信扫码 |
||||
</h5> |
||||
<p>关注糖尿病网</p> |
||||
<h6>掌上资讯随时看</h6> |
||||
</div> |
||||
<img :src="isPro ? qrcodeUrl : qrcodeUrlTest" /> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<NotLogin |
||||
v-if="deviceType !== 'pc' && !isLogin && !hasCloseMobileNotLogin" |
||||
@hideClick="hasCloseMobileNotLogin = true" |
||||
/> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import { createNamespacedHelpers } from 'vuex'; |
||||
|
||||
const { mapGetters } = createNamespacedHelpers('user'); |
||||
export default { |
||||
data() { |
||||
return { |
||||
scrollLeft: 0, |
||||
tabType: 1, |
||||
searchHeight: 0, |
||||
isPro: false, |
||||
qrcodeUrl: require('~/assets/images/follow_qrcode.png'), |
||||
qrcodeUrlTest: require('~/assets/images/follow_qrcode_test.png'), |
||||
hasCloseMobileNotLogin: false, |
||||
headShowClose: false |
||||
}; |
||||
}, |
||||
computed: { |
||||
...mapGetters({ |
||||
isLogin: 'isLogin' |
||||
}), |
||||
deviceType() { |
||||
return this.$store.state.device.deviceType; |
||||
} |
||||
}, |
||||
created() { |
||||
this.isPro = process.env.VUE_APP_TITLE === 'production'; |
||||
if (this.$route.path.includes('/other')) { |
||||
this.tabType = 2; |
||||
} else { |
||||
this.tabType = 1; |
||||
} |
||||
this.headShowClose = this.$route.name === 'user-setting'; |
||||
}, |
||||
mounted() { |
||||
const that = this; |
||||
this.$nextTick(() => { |
||||
const windowHeight = |
||||
document.documentElement.clientHeight || document.body.clientHeight; |
||||
that.searchHeight = windowHeight - 86; |
||||
window.addEventListener('scroll', function () { |
||||
// 变量scrollTop是滚动条滚动时,距离顶部的距离 |
||||
const scrollLeft = |
||||
document.documentElement.scrollLeft || document.body.scrollLeft; |
||||
that.scrollLeft = scrollLeft; |
||||
}); |
||||
window.addEventListener('resize', function () { |
||||
const windowHeight = |
||||
document.documentElement.clientHeight || document.body.clientHeight; |
||||
that.searchHeight = windowHeight - 86; |
||||
}); |
||||
}); |
||||
}, |
||||
methods: { |
||||
// 接收 CommonHeader 传递过来的值 |
||||
getMsgFormSon(data) { |
||||
this.msgFormSon = data; |
||||
console.log(this.msgFormSon); |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
<style lang="scss"> |
||||
.detail-page { |
||||
padding: 86px 0 122px; |
||||
.common-header-outer { |
||||
border-bottom: 1px solid $bg-color; |
||||
.common-header { |
||||
.top-menu { |
||||
.el-menu-item.is-active p, |
||||
.el-submenu.is-active .el-submenu__title { |
||||
font-family: MicrosoftYaHei-Bold, MicrosoftYaHei; |
||||
font-weight: bold; |
||||
} |
||||
.el-menu-item.is-active, |
||||
.el-submenu.is-active .el-submenu__title { |
||||
position: relative; |
||||
&::after { |
||||
position: absolute; |
||||
content: ''; |
||||
bottom: 24px; |
||||
left: 50%; |
||||
margin-left: -15px; |
||||
width: 30px; |
||||
height: 4px; |
||||
background: $main-blue-color; |
||||
border-radius: 2px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.bottom-outer { |
||||
position: absolute; |
||||
bottom: 0; |
||||
left: 0; |
||||
padding-top: 20px; |
||||
width: 100%; |
||||
height: 122px; |
||||
background: $main-blue-color; |
||||
box-sizing: border-box; |
||||
.web-header { |
||||
position: relative; |
||||
z-index: 1; |
||||
& > span { |
||||
/*display: none;*/ |
||||
float: none; |
||||
} |
||||
} |
||||
.web-footer { |
||||
position: relative; |
||||
padding-top: 15px; |
||||
height: auto; |
||||
z-index: 1; |
||||
p { |
||||
color: rgba(255, 255, 255, 0.4); |
||||
line-height: 17px; |
||||
a { |
||||
color: rgba(255, 255, 255, 0.4); |
||||
} |
||||
} |
||||
} |
||||
.follow-box { |
||||
position: absolute; |
||||
bottom: 20px; |
||||
width: 100%; |
||||
& > div { |
||||
margin: 0 auto; |
||||
width: $content-width; |
||||
& > div { |
||||
display: flex; |
||||
float: right; |
||||
align-items: flex-end; |
||||
& > div { |
||||
color: $body-color; |
||||
h5 { |
||||
height: 24px; |
||||
font-size: 18px; |
||||
font-family: MicrosoftYaHei-Bold, MicrosoftYaHei; |
||||
font-weight: bold; |
||||
line-height: 24px; |
||||
p { |
||||
position: relative; |
||||
top: -4px; |
||||
display: inline-block; |
||||
margin-right: 10px; |
||||
width: 28px; |
||||
height: 28px; |
||||
background: linear-gradient(180deg, #42e32d 0%, #22e034 100%); |
||||
border-radius: 4px; |
||||
img { |
||||
margin: 2px; |
||||
width: 24px; |
||||
} |
||||
} |
||||
} |
||||
& > p { |
||||
font-size: 16px; |
||||
font-family: PingFangSC-Regular, PingFang SC; |
||||
font-weight: 400; |
||||
line-height: 30px; |
||||
letter-spacing: 3px; |
||||
} |
||||
h6 { |
||||
font-size: 16px; |
||||
line-height: 21px; |
||||
} |
||||
} |
||||
& > img { |
||||
margin-left: 10px; |
||||
width: 82px; |
||||
height: 82px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
/*.fixed-box {*/ |
||||
/*bottom: 200px;*/ |
||||
/*}*/ |
||||
} |
||||
.isMobile { |
||||
.detail-page { |
||||
padding-bottom: 0; |
||||
} |
||||
.bottom-outer { |
||||
/*position: unset;*/ |
||||
padding: 0; |
||||
height: auto; |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,113 @@
@@ -0,0 +1,113 @@
|
||||
<template> |
||||
<div class="error"> |
||||
<h4 v-if="code != -1 && code != 0">{{ code }}</h4> |
||||
<h6 v-if="code === 404">NOT FOUND</h6> |
||||
<h6 v-else-if="code === 500">服务器错误</h6> |
||||
<h6 v-else-if="code === 504">网络超时</h6> |
||||
<h6 v-else>错误</h6> |
||||
<p v-if="code === 404">糟糕,网页似乎迷路了<br />请尝试返回重新寻找</p> |
||||
<p v-else-if="code === 500">紧急施工中,请稍后再试</p> |
||||
<p v-else-if="code === 502"> |
||||
哎呀,今天的网络好拥堵<br />等等我,已经在路上 |
||||
</p> |
||||
<p v-else-if="code === 504">加载失败了,请返回重新尝试</p> |
||||
<p v-else-if="code === -1" style="margin-top: 300px">请检查您的网络连接</p> |
||||
<p v-else-if="code === 401">您暂未登录<br />请登录后再操作</p> |
||||
<p v-else style="margin-top: 300px">加载错误,请重新尝试</p> |
||||
<img src="~/assets/images/fail_page_img.png" alt="" /> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
layout: 'detail', |
||||
props: { |
||||
error: { |
||||
type: Object, |
||||
default: null |
||||
} |
||||
}, |
||||
data() { |
||||
return { |
||||
code: 0 |
||||
}; |
||||
}, |
||||
mounted() { |
||||
console.log(this.error); |
||||
if (this.$route.path === '/error') { |
||||
if (this.$route.query && this.$route.query.code) |
||||
this.code = Number(this.$route.query.code); |
||||
} else { |
||||
this.code = Number(this.error.statusCode); |
||||
} |
||||
} // 你可以为错误页面指定自定义的布局 |
||||
}; |
||||
</script> |
||||
<style lang="scss"> |
||||
.error { |
||||
position: relative; |
||||
padding: 30px 0; |
||||
font-family: MicrosoftYaHei-Bold, MicrosoftYaHei; |
||||
font-weight: bold; |
||||
color: #e3e3e3; |
||||
text-align: center; |
||||
box-sizing: border-box; |
||||
h4 { |
||||
font-size: 200px; |
||||
line-height: 264px; |
||||
} |
||||
h6 { |
||||
margin-top: -25px; |
||||
font-size: 60px; |
||||
line-height: 79px; |
||||
} |
||||
p { |
||||
margin-top: 118px; |
||||
font-size: 24px; |
||||
font-family: MicrosoftYaHei; |
||||
color: $font-color2; |
||||
font-weight: normal; |
||||
line-height: 31px; |
||||
} |
||||
img { |
||||
position: absolute; |
||||
bottom: 128px; |
||||
left: 50%; |
||||
margin-left: -92px; |
||||
width: 184px; |
||||
height: 233px; |
||||
} |
||||
} |
||||
.isMobile { |
||||
.error { |
||||
margin-bottom: -110px; |
||||
background: $body-color; |
||||
h4 { |
||||
font-size: 100px; |
||||
line-height: 130px; |
||||
} |
||||
h6 { |
||||
margin-top: -10px; |
||||
font-size: 30px; |
||||
line-height: 40px; |
||||
} |
||||
p { |
||||
margin-top: 56px; |
||||
font-size: 18px; |
||||
line-height: 24px; |
||||
} |
||||
img { |
||||
bottom: 64px; |
||||
margin-left: -60px; |
||||
width: 120px; |
||||
height: auto; |
||||
} |
||||
& ~ .bottom-outer { |
||||
position: absolute; |
||||
} |
||||
& ~ .mobile-not-login { |
||||
display: none; |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
|
||||
export default function ({ store, redirect }) { |
||||
// If the user is not authenticated
|
||||
if (store.state.user.info == null) { |
||||
return redirect('/'); |
||||
} |
||||
} |
@ -0,0 +1,102 @@
@@ -0,0 +1,102 @@
|
||||
/** |
||||
* |
||||
* @param {*} UA ,就是userAgent |
||||
* @returns type: 设备类型 |
||||
* env: 访问环境(微信/微博/qq) |
||||
* masklayer: 就是给外部拿到判断是否显示遮罩层的,一些特殊环境要引导用户到外部去打开访问 |
||||
*/ |
||||
function isWechat(UA) { |
||||
return /MicroMessenger/i.test(UA); |
||||
} |
||||
|
||||
function isWeibo(UA) { |
||||
return /Weibo/i.test(UA); |
||||
} |
||||
|
||||
function isQQ(UA) { |
||||
return /QQ/i.test(UA); |
||||
} |
||||
|
||||
function isMoible(UA) { |
||||
return /(Android|webOS|iPhone|iPod|tablet|BlackBerry|Mobile)/i.test(UA); |
||||
} |
||||
|
||||
function isIOS(UA) { |
||||
return /iPhone|iPad|iPod/i.test(UA); |
||||
} |
||||
|
||||
function isAndroid(UA) { |
||||
return /Android/i.test(UA); |
||||
} |
||||
function deviceType(UA) { |
||||
if (isMoible(UA)) { |
||||
if (isIOS(UA)) { |
||||
if (isWechat(UA)) { |
||||
return { |
||||
type: 'ios', |
||||
env: 'wechat', |
||||
masklayer: true |
||||
}; |
||||
} |
||||
if (isWeibo(UA)) { |
||||
return { |
||||
type: 'ios', |
||||
env: 'weibo', |
||||
masklayer: true |
||||
}; |
||||
} |
||||
if (isQQ(UA)) { |
||||
return { |
||||
type: 'ios', |
||||
env: 'qq', |
||||
masklayer: true |
||||
}; |
||||
} |
||||
return { |
||||
type: 'ios' |
||||
}; |
||||
} |
||||
if (isAndroid(UA)) { |
||||
if (isWechat(UA)) { |
||||
return { |
||||
type: 'android', |
||||
env: 'wechat', |
||||
masklayer: true |
||||
}; |
||||
} |
||||
if (isWeibo(UA)) { |
||||
return { |
||||
type: 'android', |
||||
env: 'weibo', |
||||
masklayer: true |
||||
}; |
||||
} |
||||
if (isQQ(UA)) { |
||||
return { |
||||
type: 'android', |
||||
env: 'qq', |
||||
masklayer: true |
||||
}; |
||||
} |
||||
return { |
||||
type: 'android' |
||||
}; |
||||
} |
||||
return { |
||||
type: 'mobile' |
||||
}; |
||||
} else { |
||||
return { |
||||
type: 'pc' |
||||
}; |
||||
} |
||||
} |
||||
export default function (context) { |
||||
context.userAgent = process.server |
||||
? context.req.headers['user-agent'] |
||||
: navigator.userAgent; |
||||
// 给全局上下文添加一个属性来保存我们返回的匹配信息
|
||||
context.deviceType = deviceType(context.userAgent); |
||||
// 这里注入到store
|
||||
context.store.commit('device/setDeviceType', context.deviceType); |
||||
} |
@ -0,0 +1,945 @@
@@ -0,0 +1,945 @@
|
||||
<!-- eslint-disable vue/no-v-html--> |
||||
<template> |
||||
<div class="article-detail-page" style="padding: 30px 0"> |
||||
<div class="left-content"> |
||||
<div class="top"> |
||||
<img |
||||
v-if="!articleData.thumb" |
||||
src="~/assets/images/article_cover.png" |
||||
alt="" |
||||
style="display: none" |
||||
/> |
||||
<img |
||||
v-else |
||||
:src="articleData.thumb" |
||||
:alt="articleData.title" |
||||
style="display: none" |
||||
/> |
||||
<h4>{{ articleData.title }}</h4> |
||||
</div> |
||||
<p> |
||||
{{ articleData.hit }} <i class="el-icon-view"></i> {{ |
||||
articleData.published_at |
||||
}} |
||||
</p> |
||||
<div v-if="showNovoTeacher" class="chatbot-audio"> |
||||
<img src="~/assets/images/chatbot_audio_feature.png" alt="" /> |
||||
<div> |
||||
<h6>保护双眼,听小诺朗读</h6> |
||||
<div> |
||||
<img |
||||
:style="{ display: audioPause ? '' : 'none' }" |
||||
src="~/assets/images/play_chatbot_audio.png" |
||||
alt="" |
||||
@click="playPauseAudio" |
||||
/> |
||||
<img |
||||
:style="{ display: !audioPause ? '' : 'none' }" |
||||
src="~/assets/images/pause_chatbot_audio.png" |
||||
alt="" |
||||
@click="playPauseAudio" |
||||
/> |
||||
<div> |
||||
<span :style="{ color: playTime != '00:00' ? '#3099EA' : '' }">{{ |
||||
playTime |
||||
}}</span> |
||||
<p><span :style="{ width: playWidth + '%' }"></span></p> |
||||
<span>{{ allTime }}</span> |
||||
</div> |
||||
</div> |
||||
<audio |
||||
ref="chatbotAudio" |
||||
:src="articleData.audio_url" |
||||
@canplay="getDuration" |
||||
@timeupdate="updateTime" |
||||
@ended="audioEnd" |
||||
></audio> |
||||
</div> |
||||
</div> |
||||
<div v-if="articleData.video_url" class="video-box"> |
||||
<video |
||||
x5-video-player-type="h5" |
||||
x5-video-player-fullscreen="true" |
||||
x-webkit-airplay="true" |
||||
x5-playsinline="true" |
||||
webkit-playsinline="true" |
||||
playsinline="true" |
||||
width="100%" |
||||
controls |
||||
style="object-fit: fill" |
||||
:poster="articleData.thumb" |
||||
:src="articleData.video_url" |
||||
></video> |
||||
</div> |
||||
<div class="article-content" v-html="articleData.content"></div> |
||||
<div class="bottom-box"> |
||||
<p |
||||
v-if="!isLogin && deviceType === 'pc'" |
||||
class="go-follow" |
||||
@click=" |
||||
baiduStat('文章详情页', 'click', '文章详情页-未登录按钮'); |
||||
showLoginDialog(true); |
||||
" |
||||
> |
||||
点击关注微信公众号,查看更多专业资讯 |
||||
</p> |
||||
<div class="comment-box"> |
||||
<h6> |
||||
<span>最新看法</span> |
||||
<span @click="getCommentCorpus(1, 1)">发表你的看法</span> |
||||
</h6> |
||||
<div class="comment-content"> |
||||
<Barrage |
||||
ref="barrage" |
||||
class="barrage" |
||||
:barrage-list="barrageList" |
||||
:speed="deviceType === 'pc' ? 4 : 3" |
||||
:loop="true" |
||||
:channels="3" |
||||
:border-color="'#ededed'" |
||||
:background="'#fff'" |
||||
:barrage-height="120" |
||||
:device-type="deviceType" |
||||
/> |
||||
</div> |
||||
<p v-if="!barrageIsShow">还没有人发表看法</p> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<div |
||||
class="right-content" |
||||
:style="{ position: isFixed ? 'fixed' : 'static', right: right + 'px' }" |
||||
> |
||||
<h6 class="common-title"> |
||||
猜你喜欢<img src="~/assets/images/heart.png" alt="" /> |
||||
</h6> |
||||
<div> |
||||
<div |
||||
v-for="item in recommendArticles" |
||||
:key="item.id" |
||||
@click=" |
||||
baiduStat( |
||||
'文章详情页', |
||||
'click', |
||||
'文章点击猜你喜欢-' + item.id + '+' + item.title |
||||
); |
||||
goHref('/article/' + item.id); |
||||
" |
||||
> |
||||
<img |
||||
v-if="!item.thumb" |
||||
src="~/assets/images/article_cover.png" |
||||
alt="" |
||||
/> |
||||
<img v-else :src="item.thumb" :alt="item.title" /> |
||||
<p>{{ item.title }}</p> |
||||
<div class="bottom"> |
||||
<span |
||||
>{{ item.hit |
||||
}}<i class="el-icon-view" style="margin-right: 8px"></i |
||||
>{{ item.collect }}<i class="el-icon-star-on"></i |
||||
></span> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<div v-if="commentModelPopupShow" class="comment-model-popup"> |
||||
<div class="mask" @click="commentModelPopupShow = false"></div> |
||||
<div class="content"> |
||||
<div |
||||
ref="commentCorpus" |
||||
:style="{ maxHeight: commentMaxHeight + 'px' }" |
||||
> |
||||
<div ref="commentCorpusContent"> |
||||
<div> |
||||
<template v-for="(item, index) in commentModelList"> |
||||
<div :key="'comment' + item.id"> |
||||
<p |
||||
:class="item.chosen ? 'chosen' : ''" |
||||
@click="chooseCorpus(item.id, index)" |
||||
> |
||||
{{ item.content }} |
||||
</p> |
||||
</div> |
||||
</template> |
||||
</div> |
||||
<p v-if="commentLoading" class="load-more"> |
||||
加载更多<i class="el-icon-loading"></i> |
||||
</p> |
||||
</div> |
||||
</div> |
||||
<p @click="commentArticle">立即发布</p> |
||||
</div> |
||||
</div> |
||||
<BottomRightFixed |
||||
:show-share="true" |
||||
:show-collect="true" |
||||
:is-login="isLogin" |
||||
:is-collect="articleData.is_collected" |
||||
:show-comment="true" |
||||
@commentClick="getCommentCorpus(1, 2)" |
||||
@collectClick="collectArticle" |
||||
/> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import { createNamespacedHelpers } from 'vuex'; |
||||
|
||||
const { mapActions, mapGetters } = createNamespacedHelpers('user'); |
||||
export default { |
||||
name: 'ArticleDetailPage', |
||||
layout: 'detail', |
||||
|
||||
validate({ params }) { |
||||
return /^\d+$/.test(params.id); |
||||
}, |
||||
|
||||
async asyncData({ $axios, params, req, redirect }) { |
||||
// if (!process.server) return; |
||||
const data = await $axios.$get( |
||||
'/article/detail/' + params.id, |
||||
$axios.genSSROptions(req) |
||||
); |
||||
// data.detail.articleData.audio_url = 'https://app.diabetes.com.cn/uploadfile/article/audio/8160-16395833618215.mp3'; |
||||
// console.log('dafa:', data); |
||||
if (data.success === false) { |
||||
redirect('/error?code=' + 404); |
||||
} |
||||
return { ...data.detail }; |
||||
}, |
||||
|
||||
data() { |
||||
return { |
||||
audioPause: true, |
||||
playTime: '00:00', |
||||
allTime: '00:00', |
||||
canPlayAudio: false, |
||||
playWidth: 0, |
||||
barrageIsShow: false, |
||||
barrageList: [], |
||||
commentModelPopupShow: false, |
||||
commentModelList: [], |
||||
inComment: false, |
||||
commentPage: 1, |
||||
commentLoading: false, |
||||
commentHasMore: true, |
||||
chosenCommentId: 0, |
||||
inCollect: false, |
||||
isFixed: false, |
||||
right: 89, |
||||
commentMaxHeight: 300 |
||||
}; |
||||
}, |
||||
|
||||
head() { |
||||
return { |
||||
title: this.articleData.title, |
||||
meta: [ |
||||
{ |
||||
hid: 'description', |
||||
name: 'description', |
||||
content: 'Home page description' |
||||
} |
||||
] |
||||
}; |
||||
}, |
||||
computed: { |
||||
...mapGetters({ |
||||
isLogin: 'isLogin' |
||||
}), |
||||
deviceType() { |
||||
return this.$store.state.device.deviceType; |
||||
}, |
||||
env() { |
||||
return this.$store.state.device.env; |
||||
} |
||||
}, |
||||
|
||||
mounted() { |
||||
const that = this; |
||||
this.getComment(); |
||||
this.$nextTick(() => { |
||||
if (that.deviceType === 'pc') { |
||||
window.addEventListener('scroll', function () { |
||||
that.isFixed = true; |
||||
const scrollLeft = |
||||
document.documentElement.scrollLeft || document.body.scrollLeft; |
||||
if (document.documentElement.offsetWidth < 1258) { |
||||
that.right = |
||||
89 - (1258 - document.documentElement.offsetWidth) + scrollLeft; |
||||
} else { |
||||
that.right = (document.documentElement.offsetWidth - 1080) / 2; |
||||
} |
||||
}); |
||||
} else { |
||||
that.commentMaxHeight = |
||||
(document.documentElement.clientHeight || |
||||
document.body.clientHeight) * 0.6; |
||||
if (this.deviceType === 'ios') { |
||||
if (that.env === 'wechat') { |
||||
document.addEventListener( |
||||
'WeixinJSBridgeReady', |
||||
function () { |
||||
that.$refs.chatbotAudio.play(); |
||||
that.$refs.chatbotAudio.pause(); |
||||
that.$refs.chatbotAudio.currentTime = 0; |
||||
}, |
||||
false |
||||
); |
||||
} else { |
||||
window.onload = function () { |
||||
that.$refs.chatbotAudio.play(); |
||||
that.$refs.chatbotAudio.pause(); |
||||
that.$refs.chatbotAudio.currentTime = 0; |
||||
if (!isNaN(that.$refs.chatbotAudio.duration)) { |
||||
const duration = that.$refs.chatbotAudio.duration; |
||||
let minutes = parseInt(duration / 60, 10); |
||||
let seconds = parseInt(duration % 60); |
||||
minutes = minutes < 10 ? '0' + minutes : minutes; |
||||
seconds = seconds < 10 ? '0' + seconds : seconds; |
||||
that.allTime = minutes + ':' + seconds; |
||||
that.canPlayAudio = true; |
||||
} else { |
||||
that.canPlayAudio = true; |
||||
} |
||||
}; |
||||
} |
||||
} |
||||
} |
||||
}); |
||||
}, |
||||
methods: { |
||||
...mapActions({ |
||||
showLoginDialog: 'showLoginDialog' |
||||
}), |
||||
getDuration() { |
||||
const duration = this.$refs.chatbotAudio.duration; |
||||
let minutes = parseInt(duration / 60, 10); |
||||
let seconds = parseInt(duration % 60); |
||||
minutes = minutes < 10 ? '0' + minutes : minutes; |
||||
seconds = seconds < 10 ? '0' + seconds : seconds; |
||||
this.allTime = minutes + ':' + seconds; |
||||
this.canPlayAudio = true; |
||||
}, |
||||
playPauseAudio() { |
||||
if (this.canPlayAudio) { |
||||
if (this.audioPause) { |
||||
this.baiduStat('文章详情页', 'click', '小诺老师语音控件'); |
||||
this.$refs.chatbotAudio.play(); |
||||
} else { |
||||
this.$refs.chatbotAudio.pause(); |
||||
} |
||||
this.audioPause = !this.audioPause; |
||||
} |
||||
}, |
||||
updateTime(e) { |
||||
const currentTime = e.target.currentTime; |
||||
const duration = e.target.duration; |
||||
let minutes = parseInt(currentTime / 60, 10); |
||||
let seconds = parseInt(currentTime % 60); |
||||
minutes = minutes < 10 ? '0' + minutes : minutes; |
||||
seconds = seconds < 10 ? '0' + seconds : seconds; |
||||
this.playWidth = (currentTime / duration) * 100; |
||||
this.playTime = minutes + ':' + seconds; |
||||
}, |
||||
audioEnd() { |
||||
this.audioPause = true; |
||||
this.playTime = '00:00'; |
||||
this.playWidth = 0; |
||||
}, |
||||
async getComment() { |
||||
const data = await this.$axios.$get( |
||||
'/article/comment-list?aid=' + this.$route.params.id |
||||
); |
||||
for (const item of data.detail.commentList) { |
||||
item.time = Math.random() * 15 + 9; |
||||
} |
||||
this.barrageIsShow = data.detail.commentList.length > 0; |
||||
const _list = []; |
||||
for (const comment of data.detail.commentList) { |
||||
_list.push({ |
||||
content: comment.comment_content, |
||||
color: '#939AA7', |
||||
icon: comment.headimgurl |
||||
}); |
||||
} |
||||
this.barrageList = _list; |
||||
}, |
||||
async getCommentCorpus(page, type) { |
||||
if (!this.isLogin) { |
||||
this.showLoginDialog(true); |
||||
} else { |
||||
const that = this; |
||||
if (page === 1) { |
||||
this.baiduStat( |
||||
'文章详情页', |
||||
'click', |
||||
type === 1 ? '文章内发表你的想法-点击' : '文章内评论' |
||||
); |
||||
this.chosenCommentId = 0; |
||||
this.commentModelList = []; |
||||
this.commentPage = 1; |
||||
this.commentHasMore = true; |
||||
this.commentModelPopupShow = true; |
||||
setTimeout(function () { |
||||
that.$refs.commentCorpus.addEventListener('scroll', function () { |
||||
// 变量scrollTop是滚动条滚动时,距离顶部的距离 |
||||
const scrollTop = that.$refs.commentCorpus.scrollTop; |
||||
// 变量windowHeight是可视区的高度 |
||||
const contentHeight = that.$refs.commentCorpus.clientHeight; |
||||
// 变量scrollHeight是滚动条的总高度 |
||||
const allHeight = that.$refs.commentCorpusContent.clientHeight; |
||||
// 滚动条到底部的条件 |
||||
if (scrollTop + contentHeight > allHeight - 20) { |
||||
// 写后台加载数据的函数 一定要用that |
||||
that.getCommentCorpus(); |
||||
} |
||||
}); |
||||
}); |
||||
} |
||||
if (this.commentHasMore && !this.commentLoading) { |
||||
this.commentLoading = true; |
||||
const data = await this.$axios.$get( |
||||
'/article/comment-corpus?page=' + this.commentPage |
||||
); |
||||
for (const item of data.detail.list) { |
||||
item.chosen = false; |
||||
} |
||||
this.commentPage = this.commentPage + 1; |
||||
this.commentModelList = this.commentModelList.concat( |
||||
data.detail.list |
||||
); |
||||
this.commentHasMore = data.detail.hasMore; |
||||
this.commentLoading = false; |
||||
} |
||||
} |
||||
}, |
||||
chooseCorpus(id, index) { |
||||
for (const item of this.commentModelList) { |
||||
item.chosen = false; |
||||
} |
||||
this.chosenCommentId = id; |
||||
this.commentModelList[index].chosen = true; |
||||
}, |
||||
async commentArticle() { |
||||
if (this.chosenCommentId === 0) { |
||||
this.$message({ |
||||
message: '请选择看法模版', |
||||
type: 'warning' |
||||
}); |
||||
} else { |
||||
const loading = this.$loading({ |
||||
lock: true, |
||||
text: 'Loading', |
||||
spinner: 'el-icon-loading', |
||||
background: 'rgba(0, 0, 0, 0.7)' |
||||
}); |
||||
const data = await this.$axios.$post('/article/user-comment', { |
||||
aid: this.$route.params.id, |
||||
comment_template_id: this.chosenCommentId |
||||
}); |
||||
if (data && data.success) { |
||||
this.baiduStat('文章详情页', 'click', '文章内发表你的想法-发表成功'); |
||||
} |
||||
console.log(data); |
||||
loading.close(); |
||||
this.commentModelPopupShow = false; |
||||
this.getComment(); |
||||
} |
||||
}, |
||||
async collectArticle() { |
||||
if (!this.isLogin) { |
||||
this.showLoginDialog(true); |
||||
} else if (this.inCollect) { |
||||
this.$message({ |
||||
message: '您的操作太快了', |
||||
type: 'warning' |
||||
}); |
||||
} else { |
||||
this.baiduStat('文章详情页', 'click', '文章内收藏'); |
||||
this.inCollect = true; |
||||
const data = await this.$axios.$post('/article/user-collect', { |
||||
aid: this.$route.params.id |
||||
}); |
||||
console.log(data); |
||||
this.articleData.is_collected = data.detail.curState; |
||||
this.inCollect = false; |
||||
} |
||||
}, |
||||
goHref(url) { |
||||
let openNew = false; |
||||
if (this.deviceType === 'pc') { |
||||
openNew = true; |
||||
} |
||||
url = this.$router.resolve({ |
||||
path: url |
||||
}); |
||||
if (openNew) { |
||||
window.open(url.href, '_blank'); |
||||
} else { |
||||
window.location.href = url.href; |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
<style lang="scss"> |
||||
.article-detail-page { |
||||
position: relative; |
||||
.left-content { |
||||
div.top { |
||||
margin-bottom: 20px; |
||||
border-bottom: 1px solid $bg-color; |
||||
padding-bottom: 30px; |
||||
img { |
||||
width: 100%; |
||||
height: 407px; |
||||
border-radius: 4px; |
||||
} |
||||
h4 { |
||||
/*margin-top: 30px;*/ |
||||
font-size: 32px; |
||||
font-family: MicrosoftYaHei-Bold, MicrosoftYaHei; |
||||
font-weight: bold; |
||||
color: $font-color1; |
||||
line-height: 44px; |
||||
} |
||||
} |
||||
& > p:nth-child(2) { |
||||
margin-bottom: 20px; |
||||
font-size: 16px; |
||||
font-family: Apis-Regular, Apis; |
||||
font-weight: 400; |
||||
color: #bac0c2; |
||||
line-height: 28px; |
||||
} |
||||
.video-box { |
||||
margin-bottom: 20px; |
||||
video { |
||||
width: 100%; |
||||
} |
||||
} |
||||
.chatbot-audio { |
||||
position: relative; |
||||
margin-bottom: 20px; |
||||
padding: 16px 16px 0 85px; |
||||
width: 100%; |
||||
height: 105px; |
||||
background: $bg-color; |
||||
border-radius: 8px; |
||||
box-sizing: border-box; |
||||
& > img { |
||||
position: absolute; |
||||
top: 12px; |
||||
left: 12px; |
||||
width: 57px; |
||||
height: 87px; |
||||
} |
||||
& > div { |
||||
h6 { |
||||
font-size: 18px; |
||||
font-family: PingFangSC-Semibold, PingFang SC; |
||||
font-weight: 600; |
||||
color: #333; |
||||
line-height: 25px; |
||||
} |
||||
& > div { |
||||
position: relative; |
||||
margin-top: 25px; |
||||
padding-left: 48px; |
||||
& > img { |
||||
position: absolute; |
||||
top: -17px; |
||||
left: -10px; |
||||
width: 60px; |
||||
height: 60px; |
||||
cursor: pointer; |
||||
} |
||||
div { |
||||
display: flex; |
||||
& > span { |
||||
width: 38px; |
||||
font-size: 12px; |
||||
font-family: PingFangSC-Regular, PingFang SC; |
||||
font-weight: 400; |
||||
color: $font-color3; |
||||
line-height: 17px; |
||||
} |
||||
p { |
||||
position: relative; |
||||
margin-top: 7px; |
||||
width: calc(100% - 76px); |
||||
height: 3px; |
||||
background: #e3e3e3; |
||||
border-radius: 2px; |
||||
span { |
||||
position: absolute; |
||||
top: 0; |
||||
left: 0; |
||||
height: 3px; |
||||
background: linear-gradient(90deg, #3b97de 0%, #38b0ff 100%); |
||||
border-radius: 2px; |
||||
} |
||||
} |
||||
& > span:last-child { |
||||
text-align: right; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.article-content { |
||||
border-bottom: 1px solid $bg-color; |
||||
padding: 23px 0; |
||||
font-size: 18px; |
||||
color: $font-color1; |
||||
line-height: 30px; |
||||
img { |
||||
max-width: 100%; |
||||
border-radius: 4px; |
||||
} |
||||
} |
||||
.bottom-box { |
||||
padding-top: 20px; |
||||
div.comment-box { |
||||
position: relative; |
||||
h6 { |
||||
height: 50px; |
||||
span:first-child { |
||||
font-size: 24px; |
||||
font-family: PingFangSC-Medium, PingFang SC; |
||||
font-weight: 500; |
||||
color: $main-blue-color; |
||||
line-height: 50px; |
||||
} |
||||
span:last-child { |
||||
float: right; |
||||
width: 208px; |
||||
height: 50px; |
||||
background: #3099ea; |
||||
border-radius: 4px; |
||||
text-align: center; |
||||
font-size: 18px; |
||||
font-family: PingFangSC-Regular, PingFang SC; |
||||
font-weight: 400; |
||||
color: $body-color; |
||||
line-height: 50px; |
||||
cursor: pointer; |
||||
} |
||||
} |
||||
.comment-content { |
||||
position: relative; |
||||
margin-top: 24px; |
||||
height: 365px; |
||||
box-sizing: border-box; |
||||
.baberrage-item { |
||||
padding: 0; |
||||
.barrage-items { |
||||
display: inline-block; |
||||
border: 1px solid #ededed; |
||||
padding: 0 20px 0 10px; |
||||
height: 60px; |
||||
background: $body-color; |
||||
border-radius: 30px; |
||||
box-sizing: border-box; |
||||
img { |
||||
margin: 9px 10px 0 0; |
||||
@include roundFun(40px); |
||||
} |
||||
span { |
||||
font-size: 18px; |
||||
font-family: AppleColorEmoji; |
||||
color: $font-color3; |
||||
line-height: 58px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
& > p { |
||||
position: absolute; |
||||
top: 100px; |
||||
width: 100%; |
||||
font-size: 20px; |
||||
color: $font-color1; |
||||
text-align: center; |
||||
line-height: 100px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.right-content { |
||||
position: fixed; |
||||
top: 116px; |
||||
.common-title { |
||||
padding: 0 0 8px; |
||||
font-size: 18px; |
||||
color: $font-color1; |
||||
line-height: 25px; |
||||
img { |
||||
margin: 3px 0 0 4px; |
||||
width: 20px; |
||||
height: 20px; |
||||
} |
||||
} |
||||
& > div { |
||||
& > div { |
||||
display: block; |
||||
position: relative; |
||||
border-bottom: 1px solid $bg-color; |
||||
padding: 20px 0 0 124px; |
||||
height: 120px; |
||||
box-sizing: border-box; |
||||
img { |
||||
position: absolute; |
||||
left: 0; |
||||
width: 110px; |
||||
height: 80px; |
||||
border-radius: 4px; |
||||
} |
||||
p { |
||||
font-size: 16px; |
||||
color: $font-color1; |
||||
line-height: 24px; |
||||
@include textEllipsisMore1Line(2); |
||||
} |
||||
div.bottom { |
||||
position: absolute; |
||||
right: 0; |
||||
bottom: 19px; |
||||
text-align: right; |
||||
span { |
||||
font-size: 16px; |
||||
font-family: Apis-Regular, Apis; |
||||
font-weight: 400; |
||||
color: #bac0c2; |
||||
line-height: 28px; |
||||
i { |
||||
margin-left: 3px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.comment-model-popup { |
||||
position: fixed; |
||||
top: 0; |
||||
left: 0; |
||||
width: 100%; |
||||
height: 100%; |
||||
z-index: 9; |
||||
.mask { |
||||
position: absolute; |
||||
top: 0; |
||||
left: 0; |
||||
width: 100%; |
||||
height: 100%; |
||||
} |
||||
.content { |
||||
position: absolute; |
||||
bottom: 0; |
||||
left: 0; |
||||
border: 1px solid #e3e3e3; |
||||
padding: 44px 0 42px; |
||||
width: 100%; |
||||
box-shadow: 0 -10px 10px 0 rgba(0, 0, 0, 0.08); |
||||
border-radius: 4px 4px 0 0; |
||||
background: $body-color; |
||||
text-align: center; |
||||
& > div { |
||||
overflow-y: scroll; |
||||
margin: 0 auto 39px; |
||||
max-width: 1044px; |
||||
max-height: 300px; |
||||
& > div { |
||||
& > div { |
||||
display: flex; |
||||
flex-wrap: wrap; |
||||
& > div { |
||||
padding: 0 14px; |
||||
p { |
||||
margin-bottom: 20px; |
||||
border: 1px solid $bg-color; |
||||
padding: 0 20px; |
||||
min-width: 320px; |
||||
height: 60px; |
||||
box-sizing: border-box; |
||||
background: $bg-color; |
||||
font-size: 16px; |
||||
font-family: AppleColorEmoji; |
||||
color: #292b2c; |
||||
line-height: 58px; |
||||
@extend .text-ellipsis; |
||||
border-radius: 30px; |
||||
cursor: pointer; |
||||
} |
||||
p.chosen { |
||||
border-color: #3099ea; |
||||
background: rgba(48, 153, 234, 0.1); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
& > p { |
||||
margin: 0 auto; |
||||
width: 325px; |
||||
height: 50px; |
||||
background: #3099ea; |
||||
border-radius: 4px; |
||||
font-size: 18px; |
||||
font-family: PingFangSC-Regular, PingFang SC; |
||||
font-weight: 400; |
||||
color: $body-color; |
||||
line-height: 50px; |
||||
cursor: pointer; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.isMobile { |
||||
.article-detail-page { |
||||
padding: 11px 15px 400px !important; |
||||
background: $body-color; |
||||
.left-content { |
||||
div.top { |
||||
margin-bottom: 10px; |
||||
padding-bottom: 10px; |
||||
h4 { |
||||
font-size: 24px; |
||||
line-height: 30px; |
||||
} |
||||
} |
||||
& > p:nth-child(2) { |
||||
margin-bottom: 10px; |
||||
font-size: 14px; |
||||
} |
||||
.chatbot-audio { |
||||
margin-top: 20px; |
||||
padding: 25px 15px 10px 70px; |
||||
& > img { |
||||
left: 10px; |
||||
top: -15px; |
||||
} |
||||
& > div { |
||||
& > div { |
||||
margin-left: -55px; |
||||
padding: 0; |
||||
width: calc(100% + 55px); |
||||
& > img { |
||||
top: -62px; |
||||
right: -13px; |
||||
left: auto; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.bottom-box { |
||||
position: absolute; |
||||
bottom: 20px; |
||||
left: 0; |
||||
padding: 0 15px; |
||||
width: 100%; |
||||
box-sizing: border-box; |
||||
div.comment-box { |
||||
h6 { |
||||
height: 40px; |
||||
span:first-child { |
||||
display: none; |
||||
} |
||||
span:last-child { |
||||
width: 150px; |
||||
height: 40px; |
||||
line-height: 40px; |
||||
} |
||||
} |
||||
.comment-content { |
||||
height: 290px; |
||||
.z_barrage { |
||||
left: -15px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.right-content { |
||||
float: none; |
||||
padding-top: 10px; |
||||
width: 100%; |
||||
& > div { |
||||
& > div { |
||||
margin-bottom: 10px; |
||||
border: none; |
||||
padding: 15px 15px 12px; |
||||
height: auto; |
||||
background: #f1f1f1; |
||||
border-radius: 10px; |
||||
box-sizing: border-box; |
||||
img { |
||||
display: none; |
||||
} |
||||
div.bottom { |
||||
position: unset; |
||||
margin-top: 4px; |
||||
text-align: left; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.comment-model-popup { |
||||
z-index: 10; |
||||
.mask { |
||||
background: rgba(0, 0, 0, 0.5); |
||||
} |
||||
.content { |
||||
border: none; |
||||
padding: 62px 15px 15px; |
||||
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.05); |
||||
border-radius: 20px 20px 0 0; |
||||
box-sizing: border-box; |
||||
& > div { |
||||
margin: 0; |
||||
width: 100%; |
||||
max-width: none; |
||||
& > div { |
||||
& > div { |
||||
display: block; |
||||
& > div { |
||||
padding: 0; |
||||
p { |
||||
margin-bottom: 10px; |
||||
border: none; |
||||
padding: 11px 15px; |
||||
height: auto; |
||||
min-width: auto; |
||||
background: #eef5fb; |
||||
border-radius: 10px; |
||||
box-sizing: border-box; |
||||
text-align: left; |
||||
font-size: 16px; |
||||
font-family: AppleColorEmoji; |
||||
color: $font-color1; |
||||
line-height: 26px; |
||||
&.chosen { |
||||
color: #3099ea; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
& > p { |
||||
position: absolute; |
||||
top: 15px; |
||||
right: 15px; |
||||
width: 100px; |
||||
height: 32px; |
||||
line-height: 32px; |
||||
font-size: 16px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,122 @@
@@ -0,0 +1,122 @@
|
||||
<template> |
||||
<div ref="articleList" class="article-list-page"> |
||||
<div |
||||
v-if="articleList.length > 0" |
||||
:style="{ paddingTop: deviceType === 'pc' ? '30px' : '49px' }" |
||||
> |
||||
<div class="common-flex"> |
||||
<template v-for="item in articleList"> |
||||
<VideoArticleListItem |
||||
:key="'videolist' + item.id" |
||||
:detail="item" |
||||
:column-num="4" |
||||
:device-type="deviceType" |
||||
@addStat=" |
||||
baiduStat( |
||||
'文章列表页', |
||||
'click', |
||||
(item.mainModule === 38 ? '广告' : '文章列表点击-') + |
||||
item.id + |
||||
'+' + |
||||
item.title |
||||
) |
||||
" |
||||
/> |
||||
</template> |
||||
</div> |
||||
<p v-if="articleLoading" class="load-more"> |
||||
加载更多<i class="el-icon-loading"></i> |
||||
</p> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: 'ArticleIndexPage', |
||||
layout: 'common', |
||||
async asyncData({ $axios, query }) { |
||||
if (!process.server) return; |
||||
// console.log(query); |
||||
const data = await $axios.$get( |
||||
'/article/list?labelId=' + query.labelId + '&page=1' |
||||
); |
||||
return { ...data.detail }; |
||||
}, |
||||
data() { |
||||
return { |
||||
articlePage: 2, |
||||
articleLoading: false |
||||
}; |
||||
}, |
||||
head: { |
||||
title: '糖尿病网-文章', |
||||
meta: [{ hid: 'description', name: 'description', content: '' }] |
||||
}, |
||||
computed: { |
||||
deviceType() { |
||||
return this.$store.state.device.deviceType; |
||||
} |
||||
}, |
||||
mounted() { |
||||
const that = this; |
||||
let category = '药物'; |
||||
const labelId = Number(this.$route.query.labelId); |
||||
if (labelId === -1) { |
||||
category = '药物'; |
||||
} else if (labelId === 2) { |
||||
category = '饮食'; |
||||
} else if (labelId === 3) { |
||||
category = '运动'; |
||||
} else if (labelId === 17) { |
||||
category = '并发症'; |
||||
} else if (labelId === -2) { |
||||
category = '监测'; |
||||
} else if (labelId === 18) { |
||||
category = '心理'; |
||||
} |
||||
this.baiduStat('文章列表页', 'show', '文章列表-' + category); |
||||
console.log(this.$refs.articleList.offsetHeight); |
||||
const outerHeight = |
||||
document.documentElement.clientHeight || document.body.clientHeight; |
||||
if (this.$refs.articleList.offsetHeight < outerHeight - 86 - 66) { |
||||
this.getArticleListData(); |
||||
} |
||||
this.$nextTick(() => { |
||||
window.addEventListener('scroll', function () { |
||||
// 变量scrollTop是滚动条滚动时,距离顶部的距离 |
||||
const scrollTop = |
||||
document.documentElement.scrollTop || document.body.scrollTop; |
||||
// 变量windowHeight是可视区的高度 |
||||
const windowHeight = |
||||
document.documentElement.clientHeight || document.body.clientHeight; |
||||
// 变量scrollHeight是滚动条的总高度 |
||||
const scrollHeight = |
||||
document.documentElement.scrollHeight || document.body.scrollHeight; |
||||
// 滚动条到底部的条件 |
||||
if (scrollTop + windowHeight > scrollHeight - 50) { |
||||
// 写后台加载数据的函数 一定要用that |
||||
that.getArticleListData(); |
||||
} |
||||
}); |
||||
}); |
||||
}, |
||||
methods: { |
||||
async getArticleListData() { |
||||
if (this.hasMore && !this.articleLoading) { |
||||
this.articleLoading = true; |
||||
const data = await this.$axios.$get( |
||||
'/article/list?labelId=' + |
||||
this.$route.query.labelId + |
||||
'&page=' + |
||||
this.articlePage |
||||
); |
||||
this.hasMore = data.detail.hasMore; |
||||
this.articleList = this.articleList.concat(data.detail.articleList); |
||||
this.articlePage = this.articlePage + 1; |
||||
this.articleLoading = false; |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
</script> |
@ -0,0 +1,406 @@
@@ -0,0 +1,406 @@
|
||||
<template> |
||||
<div class="doctor-detail-page" style="position: relative; padding: 30px 0"> |
||||
<div class="left-content"> |
||||
<template v-if="deviceType === 'pc'"> |
||||
<h4>{{ videoRecord.title }}</h4> |
||||
<p> |
||||
{{ videoRecord.record_num }} <i class="el-icon-view"></i |
||||
> {{ |
||||
(Number(videoRecord.publish_at) * 1000) |
||||
| formatDate('yyyy-MM-dd hh:mm') |
||||
}} |
||||
</p> |
||||
<div class="video-box"> |
||||
<video-player |
||||
:playsinline="true" |
||||
class="video-player-box" |
||||
:options="playerOptions" |
||||
@play="videoPlay" |
||||
> |
||||
</video-player> |
||||
</div> |
||||
<p |
||||
v-if="!isLogin" |
||||
class="go-follow" |
||||
@click=" |
||||
baiduStat('一问医答详情页', 'click', '一问医答详情页-未登录按钮'); |
||||
showLoginDialog(true); |
||||
" |
||||
> |
||||
点击关注微信公众号,查看更多专业资讯 |
||||
</p> |
||||
</template> |
||||
<template v-else> |
||||
<div class="video-box"> |
||||
<video-player |
||||
:playsinline="true" |
||||
class="video-player-box" |
||||
:options="playerOptions" |
||||
@play="videoPlay" |
||||
> |
||||
</video-player> |
||||
</div> |
||||
<h4>{{ videoRecord.title }}</h4> |
||||
<p> |
||||
{{ videoRecord.record_num }} <i class="el-icon-view"></i |
||||
> {{ |
||||
(Number(videoRecord.publish_at) * 1000) |
||||
| formatDate('yyyy-MM-dd hh:mm') |
||||
}} |
||||
</p> |
||||
</template> |
||||
</div> |
||||
<div class="right-content"> |
||||
<div v-if="deviceType === 'pc'" class="doctor-info-box"> |
||||
<img :src="expertColumnInfo.expert_img" alt="" /> |
||||
<div> |
||||
<h6 class="text-ellipsis"> |
||||
{{ expertColumnInfo.username }} {{ expertColumnInfo.title }} |
||||
</h6> |
||||
<p class="text-ellipsis">{{ expertColumnInfo.hospital_name }}</p> |
||||
<p class="text-ellipsis">{{ expertColumnInfo.department }}</p> |
||||
</div> |
||||
</div> |
||||
<div ref="allList" class="doctor-list-box"> |
||||
<div |
||||
v-for="item in expertColumnInfo.video_list" |
||||
:key="item.id" |
||||
@click="goDoctorVideo(item.id)" |
||||
> |
||||
<template v-if="deviceType === 'pc'"> |
||||
<img |
||||
v-if="item.id == videoRecord.id" |
||||
ref="activeListImg" |
||||
src="~/assets/images/doctor_pause_icon.png" |
||||
alt="" |
||||
/> |
||||
<img v-else src="~/assets/images/doctor_play_icon.png" alt="" /> |
||||
</template> |
||||
<span |
||||
:style="{ color: item.id == videoRecord.id ? '#3B97DE' : '' }" |
||||
>{{ item.title }}</span |
||||
> |
||||
<div v-if="deviceType !== 'pc'" class="bottom-box"> |
||||
<span>{{ item.record_num }}次播放</span> |
||||
<span :style="{ opacity: item.id == videoRecord.id ? '0.6' : '' }" |
||||
><img src="~/assets/images/mobile_doctor_play.png" alt="" />{{ |
||||
item.id == videoRecord.id ? '正在' : '点击' |
||||
}}观看</span |
||||
> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<BottomRightFixed :show-share="true" /> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import { createNamespacedHelpers } from 'vuex'; |
||||
|
||||
const { mapGetters, mapActions } = createNamespacedHelpers('user'); |
||||
|
||||
export default { |
||||
name: 'DoctorDetailPage', |
||||
layout: 'detail', |
||||
|
||||
validate({ params }) { |
||||
return /^\d+$/.test(params.id); |
||||
}, |
||||
|
||||
async asyncData({ $axios, params, redirect }) { |
||||
if (!process.server) return; |
||||
const data = await $axios.$get('/expert-video/detail?vid=' + params.id); |
||||
if (data.success === false) { |
||||
redirect('/error?code=' + 404); |
||||
} |
||||
console.log(data.detail.expertColumnInfo.video_list); |
||||
return { |
||||
...data.detail, |
||||
playerOptions: { |
||||
playbackRates: [0.7, 1.0, 1.5, 2.0], // 播放速度 |
||||
autoplay: false, // 如果true,浏览器准备好时开始回放。 |
||||
muted: false, // 默认情况下将会消除任何音频。 |
||||
loop: false, // 导致视频一结束就重新开始。 |
||||
preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持) |
||||
language: 'en', |
||||
fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。 |
||||
sources: [ |
||||
{ |
||||
type: '', // 这里的种类支持很多种:基本视频格式、直播、流媒体等,具体可以参看git网址项目 |
||||
src: data.detail.videoRecord.video_url // url地址 |
||||
} |
||||
], |
||||
aspectRatio: '16:9', |
||||
poster: require('~/assets/images/doctor_default_poster.png'), |
||||
// width: document.documentElement.clientWidth, // 播放器宽度 |
||||
notSupportedMessage: '此视频暂无法播放,请稍后再试', // 允许覆盖Video.js无法播放媒体源时显示的默认信息。 |
||||
controlBar: { |
||||
timeDivider: true, |
||||
durationDisplay: true, |
||||
remainingTimeDisplay: false, |
||||
fullscreenToggle: true // 全屏按钮 |
||||
} |
||||
} |
||||
}; |
||||
}, |
||||
|
||||
data() { |
||||
return { |
||||
playerOptions: {} |
||||
}; |
||||
}, |
||||
|
||||
head() { |
||||
return { |
||||
title: this.videoRecord.title, |
||||
meta: [ |
||||
{ |
||||
hid: 'description', |
||||
name: 'description', |
||||
content: 'Home page description' |
||||
} |
||||
] |
||||
}; |
||||
}, |
||||
computed: { |
||||
...mapGetters({ |
||||
isLogin: 'isLogin' |
||||
}), |
||||
deviceType() { |
||||
return this.$store.state.device.deviceType; |
||||
} |
||||
}, |
||||
|
||||
mounted() { |
||||
if (this.deviceType === 'pc') { |
||||
this.$nextTick(() => { |
||||
this.$refs.allList.scrollTop = |
||||
this.$refs.activeListImg[0].parentNode.offsetTop - |
||||
this.$refs.allList.clientHeight / 2; |
||||
}); |
||||
} |
||||
}, |
||||
methods: { |
||||
...mapActions({ |
||||
showLoginDialog: 'showLoginDialog' |
||||
}), |
||||
async videoPlay(e) { |
||||
if (e.cache_.currentTime === 0 || e.cache_.currentTime === undefined) { |
||||
this.baiduStat('一问医答详情页', 'click', '一问医答详情页-播放视频'); |
||||
await this.$axios.$post('/expert-video/user-play', { |
||||
vid: this.$route.params.id |
||||
}); |
||||
} |
||||
}, |
||||
goDoctorVideo(id) { |
||||
if (Number(this.$route.params.id) !== Number(id)) { |
||||
// this.$router.push('/doctor/'+id); |
||||
this.baiduStat( |
||||
'一问医答详情页', |
||||
'click', |
||||
'一问医答详情页-切换视频列表' |
||||
); |
||||
const { href } = this.$router.resolve({ |
||||
path: '/doctor/' + id |
||||
}); |
||||
window.location.href = href; |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
<style lang="scss"> |
||||
.doctor-detail-page { |
||||
position: relative; |
||||
.left-content { |
||||
& > h4 { |
||||
margin-bottom: 20px; |
||||
border-bottom: 1px solid $bg-color; |
||||
padding-bottom: 30px; |
||||
font-size: 32px; |
||||
font-family: MicrosoftYaHei-Bold, MicrosoftYaHei; |
||||
font-weight: bold; |
||||
color: $font-color1; |
||||
line-height: 44px; |
||||
} |
||||
& > p:nth-child(2), |
||||
& > p:nth-child(3) { |
||||
margin-bottom: 20px; |
||||
font-size: 16px; |
||||
font-family: Apis-Regular, Apis; |
||||
font-weight: 400; |
||||
color: #bac0c2; |
||||
line-height: 28px; |
||||
} |
||||
.video-box { |
||||
margin-bottom: 30px; |
||||
height: 406.69px; |
||||
} |
||||
p.go-follow { |
||||
margin-bottom: 10px; |
||||
} |
||||
} |
||||
.right-content { |
||||
position: absolute; |
||||
right: 0; |
||||
height: calc(100% - 80px); |
||||
.doctor-info-box { |
||||
position: relative; |
||||
margin-bottom: 20px; |
||||
padding: 42px 0 0 127px; |
||||
height: 168px; |
||||
background: $bg-color; |
||||
border-radius: 4px; |
||||
box-sizing: border-box; |
||||
img { |
||||
position: absolute; |
||||
top: 42px; |
||||
left: 27px; |
||||
border: 1px solid #ededed; |
||||
background: $body-color; |
||||
@include roundFun(80px); |
||||
box-sizing: border-box; |
||||
} |
||||
div { |
||||
h6 { |
||||
margin-bottom: 11px; |
||||
font-size: 18px; |
||||
font-family: MicrosoftYaHei-Bold, MicrosoftYaHei; |
||||
font-weight: bold; |
||||
color: $main-blue-color; |
||||
line-height: 24px; |
||||
} |
||||
p { |
||||
font-size: 16px; |
||||
color: $font-color3; |
||||
line-height: 21px; |
||||
} |
||||
} |
||||
} |
||||
.doctor-list-box { |
||||
position: relative; |
||||
overflow-y: scroll; |
||||
padding: 30px; |
||||
height: calc(100% - 188px); |
||||
background: #f5f5f8; |
||||
border-radius: 4px; |
||||
box-sizing: border-box; |
||||
& > div { |
||||
display: flex; |
||||
margin-bottom: 22px; |
||||
align-items: center; |
||||
cursor: pointer; |
||||
img { |
||||
margin-right: 10px; |
||||
width: 30px; |
||||
height: 30px; |
||||
} |
||||
& > span { |
||||
font-size: 16px; |
||||
color: $font-color1; |
||||
line-height: 21px; |
||||
} |
||||
} |
||||
& > div:last-child { |
||||
margin-bottom: 0; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.isMobile { |
||||
.doctor-detail-page { |
||||
padding: 0 !important; |
||||
background: $body-color; |
||||
.left-content { |
||||
.video-box { |
||||
margin: 0; |
||||
padding: 0; |
||||
height: auto; |
||||
box-shadow: none; |
||||
&::after { |
||||
display: none; |
||||
} |
||||
.video-player-box { |
||||
width: 100%; |
||||
& > div { |
||||
padding-top: 56.25%; |
||||
} |
||||
} |
||||
} |
||||
& > h4 { |
||||
margin: 0 15px 4px; |
||||
padding: 20px 5px 16px; |
||||
font-size: 18px; |
||||
line-height: 24px; |
||||
} |
||||
& > p:nth-child(3) { |
||||
margin-bottom: 20px; |
||||
padding: 0 22px; |
||||
font-size: 12px; |
||||
line-height: 17px; |
||||
} |
||||
} |
||||
.right-content { |
||||
position: unset; |
||||
float: none; |
||||
width: 100%; |
||||
height: auto; |
||||
.doctor-list-box { |
||||
padding: 0 15px; |
||||
height: auto; |
||||
background: transparent; |
||||
& > div { |
||||
display: block; |
||||
margin: 0; |
||||
border-bottom: 1px solid $bg-color; |
||||
padding: 20px 0 15px; |
||||
& > span { |
||||
display: block; |
||||
margin: 0 15px 11px; |
||||
font-size: 18px; |
||||
font-family: PingFangSC-Medium, PingFang SC; |
||||
font-weight: 500; |
||||
color: #333; |
||||
line-height: 25px; |
||||
} |
||||
.bottom-box { |
||||
height: 32px; |
||||
span:first-child { |
||||
display: inline-block; |
||||
margin-top: 1px; |
||||
padding: 0 9px 0 14px; |
||||
height: 30px; |
||||
background: #f7f7fa; |
||||
border-radius: 0 15px 15px 0; |
||||
font-size: 14px; |
||||
font-family: PingFangSC-Regular, PingFang SC; |
||||
font-weight: 400; |
||||
color: #7d7d7d; |
||||
line-height: 30px; |
||||
} |
||||
span:last-child { |
||||
float: right; |
||||
width: 134px; |
||||
height: 32px; |
||||
background: linear-gradient(180deg, #fad961 0%, #f76b1c 100%); |
||||
border-radius: 16px; |
||||
font-size: 16px; |
||||
font-family: PingFangSC-Medium, PingFang SC; |
||||
font-weight: 500; |
||||
color: #fafafc; |
||||
line-height: 32px; |
||||
text-align: center; |
||||
img { |
||||
margin: 6px 6px 0 0; |
||||
width: 21px; |
||||
height: 21px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,249 @@
@@ -0,0 +1,249 @@
|
||||
<template> |
||||
<div |
||||
class="doctor-list-page" |
||||
:style="{ paddingTop: deviceType === 'pc' ? '' : '49px' }" |
||||
> |
||||
<template v-if="deviceType === 'pc'"> |
||||
<div class="top-box"></div> |
||||
<div v-if="expertList.length > 0"> |
||||
<div class="common-flex"> |
||||
<template v-for="item in expertList"> |
||||
<DoctorItem |
||||
:key="'expert' + item.expert_id" |
||||
:detail="item" |
||||
:column-num="4" |
||||
:device-type="deviceType" |
||||
/> |
||||
</template> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
<template v-else> |
||||
<div class="mobile-top-box"> |
||||
<img src="~/assets/images/mobile_doctor_title.png" alt="一问医答" /> |
||||
<h5> |
||||
邀请知名专家,以一问一答短视频的形式,对糖友关心的问题予以解答,以期传递简单、清晰的教育信息,帮助糖友提高疾病认知。 |
||||
</h5> |
||||
</div> |
||||
<div v-if="expertList.length > 0" class="mobile-doctor-swipe"> |
||||
<swiper ref="mySwiper" :options="swiperOption"> |
||||
<swiper-slide |
||||
v-for="item in expertList" |
||||
:key="'expertMobile' + item.expert_id" |
||||
> |
||||
<div class="mobile-doctor-item"> |
||||
<div class="expert-intro"> |
||||
<img :src="item.expert_img" :alt="item.username" /> |
||||
<div class="right-font"> |
||||
<h3> |
||||
{{ item.username }}<span>{{ item.title }}</span> |
||||
</h3> |
||||
<h4>{{ item.hospital_name }}</h4> |
||||
<h5>{{ item.department }}</h5> |
||||
</div> |
||||
</div> |
||||
<p v-if="expertList.length > 1"> |
||||
<img |
||||
src="~/assets/images/mobile_doctor_arrow.png" |
||||
alt="" |
||||
/>滑动查看其他专家<img |
||||
src="~/assets/images/mobile_doctor_arrow.png" |
||||
alt="" |
||||
/> |
||||
</p> |
||||
<div v-if="item.video_list.length > 0" class="video-list"> |
||||
<DoctorVideoItem |
||||
v-for="video in item.video_list" |
||||
:key="'mobileExpertVideo' + video.id" |
||||
:video="video" |
||||
@addStat=" |
||||
baiduStat( |
||||
'一问医答列表', |
||||
'click', |
||||
'一问医答列表点击-' + video.id + '+' + video.title |
||||
) |
||||
" |
||||
/> |
||||
</div> |
||||
</div> |
||||
</swiper-slide> |
||||
</swiper> |
||||
</div> |
||||
</template> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: 'VideoIndexPage', |
||||
layout: 'common', |
||||
async asyncData({ $axios }) { |
||||
if (!process.server) return; |
||||
const data = await $axios.$get('/expert-video/list'); |
||||
return { ...data.detail }; |
||||
}, |
||||
data() { |
||||
return { |
||||
swiperOption: { |
||||
loop: true, |
||||
navigation: false, |
||||
pagination: false, |
||||
autoplay: false, |
||||
autoHeight: true |
||||
} |
||||
}; |
||||
}, |
||||
head: { |
||||
title: '糖尿病网-一问医答', |
||||
meta: [{ hid: 'description', name: 'description', content: '' }] |
||||
}, |
||||
computed: { |
||||
deviceType() { |
||||
return this.$store.state.device.deviceType; |
||||
} |
||||
}, |
||||
mounted() { |
||||
this.baiduStat('一问医答列表', 'show', '一问医答列表-访问'); |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss"> |
||||
.doctor-list-page { |
||||
.top-box { |
||||
position: absolute; |
||||
top: 86px; |
||||
left: 0; |
||||
width: 100%; |
||||
min-width: $outer-width; |
||||
height: 334px; |
||||
background: url(~assets/images/doctor_list_top.png) no-repeat center; |
||||
background-size: auto 334px; |
||||
} |
||||
& > div:nth-child(2) { |
||||
position: relative; |
||||
padding-top: 235px; |
||||
.common-flex { |
||||
justify-content: flex-start; |
||||
.doctor-item { |
||||
margin: 0 19.3px 30px 0; |
||||
padding: 20px 22px 0; |
||||
width: 255px; |
||||
} |
||||
.doctor-item:nth-child(4n) { |
||||
margin-right: 0; |
||||
} |
||||
} |
||||
} |
||||
.mobile-top-box { |
||||
padding: 17px 16px 64px; |
||||
background: linear-gradient(180deg, #3b97de 0%, #009fda 100%); |
||||
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.06); |
||||
text-align: center; |
||||
img { |
||||
width: 102px; |
||||
height: 39px; |
||||
} |
||||
h5 { |
||||
margin: 9px 0 0; |
||||
font-size: 14px; |
||||
font-family: PingFangSC-Semibold, PingFang SC; |
||||
font-weight: 600; |
||||
color: $body-color; |
||||
line-height: 20px; |
||||
text-align: left; |
||||
} |
||||
} |
||||
.mobile-doctor-swipe { |
||||
margin-top: -48px; |
||||
padding: 0 !important; |
||||
.mobile-doctor-item { |
||||
.expert-intro { |
||||
display: flex; |
||||
overflow: hidden; |
||||
align-items: center; |
||||
margin: 0 13px; |
||||
padding: 0 24px 0 0; |
||||
height: 119px; |
||||
background: $body-color; |
||||
box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.08); |
||||
border-radius: 10px; |
||||
box-sizing: border-box; |
||||
img { |
||||
margin-top: 7px; |
||||
width: 124px; |
||||
height: 112px; |
||||
} |
||||
.right-font { |
||||
margin-left: 12px; |
||||
width: calc(100% - 136px); |
||||
h3, |
||||
h4, |
||||
h5 { |
||||
@extend .text-ellipsis; |
||||
} |
||||
h3 { |
||||
margin: 0 0 3px; |
||||
font-size: 20px; |
||||
font-family: PingFangSC-Semibold, PingFang SC; |
||||
font-weight: 600; |
||||
color: #323232; |
||||
line-height: 28px; |
||||
span { |
||||
margin-left: 8px; |
||||
font-size: 18px; |
||||
} |
||||
} |
||||
h4 { |
||||
display: inline-block; |
||||
margin: 0 0 11px; |
||||
padding: 0 6px; |
||||
max-width: 100%; |
||||
height: 27px; |
||||
background: linear-gradient(270deg, #3b97de 0%, #009fda 100%); |
||||
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.06); |
||||
border-radius: 4px; |
||||
font-size: 16px; |
||||
font-family: PingFangSC-Medium, PingFang SC; |
||||
font-weight: 500; |
||||
color: $body-color; |
||||
line-height: 27px; |
||||
} |
||||
h5 { |
||||
margin: 0 0 0 3px; |
||||
font-size: 15px; |
||||
font-family: PingFangSC-Medium, PingFang SC; |
||||
font-weight: 500; |
||||
color: #009fda; |
||||
line-height: 22px; |
||||
} |
||||
} |
||||
} |
||||
& > p { |
||||
margin-top: 7px; |
||||
font-size: 14px; |
||||
font-family: PingFangSC-Regular, PingFang SC; |
||||
font-weight: 400; |
||||
color: #003279; |
||||
line-height: 20px; |
||||
text-align: center; |
||||
img { |
||||
position: relative; |
||||
top: 4px; |
||||
display: inline-block; |
||||
margin-left: 3px; |
||||
width: 13px; |
||||
height: 13px; |
||||
} |
||||
img:first-child { |
||||
margin: 0 3px 0 0; |
||||
transform: rotate(180deg); |
||||
} |
||||
} |
||||
.video-list { |
||||
margin-top: 13px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,906 @@
@@ -0,0 +1,906 @@
|
||||
<template> |
||||
<div |
||||
class="outer-container" |
||||
:class="{ |
||||
isMobile: deviceType !== 'pc', |
||||
hasLoginBottom: deviceType !== 'pc' && !isLogin && !hasCloseMobileNotLogin |
||||
}" |
||||
> |
||||
<div |
||||
class="content-container index-page" |
||||
:class="{ isMobile: deviceType !== 'pc' }" |
||||
> |
||||
<div |
||||
v-if="deviceType === 'pc'" |
||||
class="header-outer" |
||||
:style="{ top: -scrollTop + 'px', left: -scrollLeft + 'px' }" |
||||
> |
||||
<WebHeader /> |
||||
</div> |
||||
<CommonHeader |
||||
:device-type="deviceType" |
||||
:has-web-header="true" |
||||
:scroll-top="scrollTop" |
||||
:scroll-left="scrollLeft" |
||||
:search-height="searchHeight" |
||||
:tab-type="1" |
||||
@func="getMsgFormSon" |
||||
/> |
||||
<div v-show="msgFormSon" class="library-page"> |
||||
<div class="left-content"> |
||||
<div v-if="topBanner.length > 0" class="top-banner"> |
||||
<div v-if="popTopBannerShow" class="pop-banner"> |
||||
<span @click="popTopBannerShow = false" |
||||
>跳过广告 {{ popTopBannerTime }}s</span |
||||
> |
||||
<img |
||||
:src="popTopBannerItem.image_url" |
||||
:alt="popTopBannerItem.title" |
||||
@click=" |
||||
goTopBanner( |
||||
'top', |
||||
popTopBannerItem.id, |
||||
popTopBannerItem.title, |
||||
popTopBannerItem.action_url, |
||||
popTopBannerItem.content_type |
||||
) |
||||
" |
||||
/> |
||||
</div> |
||||
<el-carousel :height="topBannerHeight + 'px'" arrow="never"> |
||||
<el-carousel-item v-for="item in topBanner" :key="item.id"> |
||||
<div |
||||
class="top-banner-box" |
||||
@click=" |
||||
goTopBanner( |
||||
'top', |
||||
item.id, |
||||
item.title, |
||||
item.action_url, |
||||
item.content_type |
||||
) |
||||
" |
||||
> |
||||
<img :src="item.image_url" :alt="item.title" /> |
||||
<div class="mask"> |
||||
<p class="text-ellipsis">{{ item.title }}</p> |
||||
</div> |
||||
</div> |
||||
</el-carousel-item> |
||||
</el-carousel> |
||||
</div> |
||||
<template v-if="deviceType === 'pc'"> |
||||
<div v-if="expertList.length > 0" class="doctor-box"> |
||||
<h4 class="common-title"> |
||||
一问医答 |
||||
<NuxtLink |
||||
to="/doctor" |
||||
target="_blank" |
||||
@click.native=" |
||||
baiduStat('糖尿病网-首页', 'click', '一问医答-查看更多') |
||||
" |
||||
>查看更多<i class="el-icon-caret-right"></i |
||||
></NuxtLink> |
||||
</h4> |
||||
<div class="common-flex"> |
||||
<template v-for="item in expertList"> |
||||
<DoctorItem |
||||
:key="'doctor' + item.id" |
||||
:detail="item" |
||||
:column-num="3" |
||||
@addStat=" |
||||
baiduStat( |
||||
'糖尿病网-首页', |
||||
'click', |
||||
'一问医答-' + item.id + '+' + item.title |
||||
) |
||||
" |
||||
/> |
||||
</template> |
||||
</div> |
||||
</div> |
||||
<div v-if="videoList.length > 0" class="hot-videos"> |
||||
<h4 class="common-title"> |
||||
热门视频 |
||||
<NuxtLink |
||||
to="/video" |
||||
target="_blank" |
||||
@click.native=" |
||||
baiduStat('糖尿病网-首页', 'click', '热门视频-查看更多') |
||||
" |
||||
>查看更多<i class="el-icon-caret-right"></i |
||||
></NuxtLink> |
||||
</h4> |
||||
<div class="common-flex"> |
||||
<template v-for="item in videoList"> |
||||
<VideoArticleListItem |
||||
:key="'va' + item.id" |
||||
:detail="item" |
||||
:column-num="3" |
||||
@addStat=" |
||||
baiduStat( |
||||
'糖尿病网-首页', |
||||
'click', |
||||
'热门视频-' + item.id + '+' + item.title |
||||
) |
||||
" |
||||
/> |
||||
</template> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
<MobileHeader |
||||
v-if="deviceType !== 'pc'" |
||||
:is-index="true" |
||||
:need-fixed="mobileTabNeedFixed" |
||||
/> |
||||
<div |
||||
class="recommend-article" |
||||
:style="{ |
||||
paddingTop: |
||||
deviceType !== 'pc' && mobileTabNeedFixed ? '49px' : '' |
||||
}" |
||||
> |
||||
<h4 v-if="deviceType === 'pc'" class="common-title">推荐阅读</h4> |
||||
<div class="common-flex"> |
||||
<template v-for="item in articleList"> |
||||
<VideoArticleListItem |
||||
:key="'rva' + item.id" |
||||
:detail="item" |
||||
:column-num="3" |
||||
:device-type="deviceType" |
||||
@addStat=" |
||||
baiduStat( |
||||
'糖尿病网-首页', |
||||
'click', |
||||
'推荐阅读-' + item.id + '+' + item.title |
||||
) |
||||
" |
||||
/> |
||||
</template> |
||||
</div> |
||||
<p v-if="articleLoading" class="load-more"> |
||||
加载更多<i class="el-icon-loading"></i> |
||||
</p> |
||||
</div> |
||||
</div> |
||||
<div v-if="deviceType === 'pc'" class="right-content"> |
||||
<!-- <div v-if="!isLogin" class="not-login-box"> --> |
||||
<!-- <h6>登录后,内容更精彩</h6> --> |
||||
<!-- <p --> |
||||
<!-- @click=" --> |
||||
<!-- baiduStat('立即登录按钮', 'click', '立即登录按钮'); --> |
||||
<!-- gotoLogin(); --> |
||||
<!-- " --> |
||||
<!-- > --> |
||||
<!-- 立即登录 --> |
||||
<!-- </p> --> |
||||
<!-- </div> --> |
||||
<div |
||||
class="need-fixed" |
||||
:style="{ |
||||
position: needFixed ? 'fixed' : 'unset', |
||||
top: needFixed ? '86px' : '', |
||||
right: needFixed ? right + 'px' : '' |
||||
}" |
||||
> |
||||
<div class="go-wechat"> |
||||
<div> |
||||
<h4>糖尿病网微信版</h4> |
||||
<p>前沿专业的公益科普<br />专属糖友的知识社区</p> |
||||
</div> |
||||
<img :src="isPro ? qrcodeUrl : qrcodeUrlTest" alt="" /> |
||||
</div> |
||||
</div> |
||||
<div v-if="hotArticle.length > 0" class="hot-articles-box"> |
||||
<h6 class="common-title"> |
||||
大家在看<span>HOT</span> |
||||
<NuxtLink |
||||
to="/article?labelId=-1" |
||||
target="_blank" |
||||
@click.native=" |
||||
baiduStat('糖尿病网-首页', 'click', '大家在看-查看更多') |
||||
" |
||||
>查看更多<i class="el-icon-caret-right"></i |
||||
></NuxtLink> |
||||
</h6> |
||||
<div> |
||||
<NuxtLink |
||||
v-for="(item, index) in hotArticle" |
||||
:key="index" |
||||
:to="{ name: 'article', params: { id: item.id } }" |
||||
target="_blank" |
||||
@click.native=" |
||||
baiduStat( |
||||
'糖尿病网-首页', |
||||
'click', |
||||
'大家在看-' + item.id + '+' + item.title |
||||
) |
||||
" |
||||
> |
||||
<img |
||||
v-if="!item.thumb" |
||||
src="~/assets/images/article_cover.png" |
||||
alt="" |
||||
/> |
||||
<img v-else :src="item.thumb" :alt="item.title" /> |
||||
<p> |
||||
<span>{{ index + 1 }}</span |
||||
>{{ item.title }} |
||||
</p> |
||||
</NuxtLink> |
||||
</div> |
||||
</div> |
||||
<span ref="needFixed"></span> |
||||
<div |
||||
class="need-fixed" |
||||
:style="{ |
||||
position: needFixed ? 'fixed' : 'unset', |
||||
top: needFixed ? '86px' : '', |
||||
right: needFixed ? right + 'px' : '' |
||||
}" |
||||
> |
||||
<div class="go-wechat"> |
||||
<div> |
||||
<h4>养成健康好习惯</h4> |
||||
<p>获积分 免费换针头<br />扫码前往诺和关怀</p> |
||||
</div> |
||||
<img src="~/assets/images/novocare_qrcode.png" alt="" /> |
||||
</div> |
||||
<div v-if="rightBottomAd.length > 0" class="right-banner"> |
||||
<img |
||||
:src="rightBottomAd[0].image_url" |
||||
alt="" |
||||
@click=" |
||||
goTopBanner( |
||||
'right', |
||||
rightBottomAd[0].id, |
||||
rightBottomAd[0].title, |
||||
rightBottomAd[0].action_url |
||||
) |
||||
" |
||||
/> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<div |
||||
v-if="deviceType === 'pc' && bottomAd.length > 0" |
||||
class="bottom-ad" |
||||
:style="{ left: -scrollLeft + 'px' }" |
||||
> |
||||
<div> |
||||
<i |
||||
class="el-icon-error" |
||||
@click=" |
||||
baiduStat('底部弹层广告', 'click', '底部弹层广告-关闭'); |
||||
bottomAd = []; |
||||
" |
||||
></i> |
||||
<img |
||||
:src="bottomAd[0].image_url" |
||||
alt="" |
||||
@click=" |
||||
goTopBanner( |
||||
'bottom', |
||||
bottomAd[0].id, |
||||
bottomAd[0].title, |
||||
bottomAd[0].action_url |
||||
) |
||||
" |
||||
/> |
||||
</div> |
||||
</div> |
||||
<div class="footer-outer" :style="{ left: -scrollLeft + 'px' }"> |
||||
<WebFooter :device-type="deviceType" /> |
||||
</div> |
||||
<NotLogin |
||||
v-if="deviceType !== 'pc' && !isLogin && !hasCloseMobileNotLogin" |
||||
@hideClick="hasCloseMobileNotLogin = true" |
||||
/> |
||||
<BottomRightFixed /> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import { createNamespacedHelpers } from 'vuex'; |
||||
|
||||
const { mapActions, mapGetters } = createNamespacedHelpers('user'); |
||||
// test node |
||||
export default { |
||||
name: 'IndexPage', |
||||
// layout: 'common', |
||||
|
||||
async asyncData({ req, $axios, store }) { |
||||
if (store.state.device.deviceType === 'pc') { |
||||
const data = await $axios.$get('/index-data', $axios.genSSROptions(req)); |
||||
return { ...data.detail }; |
||||
} else { |
||||
const [dataA, dataB] = await Promise.all([ |
||||
$axios.$get('/article/list?page=1', $axios.genSSROptions(req)), |
||||
$axios.$get('/index-banner', $axios.genSSROptions(req)) |
||||
]); |
||||
return { |
||||
...dataA.detail, |
||||
...dataB.detail |
||||
}; |
||||
} |
||||
}, |
||||
|
||||
data() { |
||||
return { |
||||
scrollTop: 0, |
||||
scrollLeft: 0, |
||||
articlePage: 1, |
||||
articleList: [], |
||||
articleLoading: false, |
||||
hasMore: true, |
||||
hotArticle: [], |
||||
searchHeight: 0, |
||||
needFixed: false, |
||||
right: 89, |
||||
isPro: false, |
||||
qrcodeUrl: require('~/assets/images/follow_qrcode.png'), |
||||
qrcodeUrlTest: require('~/assets/images/follow_qrcode_test.png'), |
||||
msgFormSon: true, // 页面显隐 |
||||
topBannerHeight: 410, |
||||
popTopBannerShow: false, |
||||
popTopBannerTime: 5, |
||||
popTopBannerItem: {}, |
||||
mobileTabNeedFixed: false, |
||||
hasCloseMobileNotLogin: false |
||||
// isLogin: 0, |
||||
}; |
||||
}, |
||||
|
||||
computed: { |
||||
...mapGetters({ |
||||
isLogin: 'isLogin' |
||||
}), |
||||
deviceType() { |
||||
return this.$store.state.device.deviceType; |
||||
} |
||||
}, |
||||
created() { |
||||
this.isPro = process.env.VUE_APP_TITLE === 'production'; |
||||
if (this.$store.state.device.deviceType !== 'pc') { |
||||
this.topBannerHeight = (410 * (320 - 30)) / 723; |
||||
} |
||||
}, |
||||
mounted() { |
||||
const that = this; |
||||
that.baiduStat('糖尿病网-首页', 'show', '首页访问'); |
||||
if (that.deviceType === 'pc') { |
||||
that.getArticleListData(); |
||||
that.getHotArticleData(); |
||||
} else { |
||||
that.articlePage = 2; |
||||
that.topBannerHeight = |
||||
(410 * |
||||
((document.documentElement.clientWidth || document.body.clientWidth) - |
||||
30)) / |
||||
723; |
||||
} |
||||
this.$nextTick(() => { |
||||
const windowHeight = |
||||
document.documentElement.clientHeight || document.body.clientHeight; |
||||
that.searchHeight = windowHeight - 86 - 66 - 30; |
||||
window.addEventListener('resize', function () { |
||||
const windowHeight = |
||||
document.documentElement.clientHeight || document.body.clientHeight; |
||||
that.searchHeight = windowHeight - 86 - 66 - 30; |
||||
}); |
||||
window.addEventListener('scroll', function () { |
||||
// 变量scrollTop是滚动条滚动时,距离顶部的距离 |
||||
const scrollTop = |
||||
document.documentElement.scrollTop || document.body.scrollTop; |
||||
const scrollLeft = |
||||
document.documentElement.scrollLeft || document.body.scrollLeft; |
||||
that.scrollTop = scrollTop; |
||||
that.scrollLeft = scrollLeft; |
||||
if (that.deviceType === 'pc') { |
||||
if (scrollTop + 86 >= that.$refs.needFixed.offsetTop) { |
||||
that.needFixed = true; |
||||
if (document.documentElement.offsetWidth < 1258) { |
||||
that.right = |
||||
89 - (1258 - document.documentElement.offsetWidth) + scrollLeft; |
||||
} else { |
||||
that.right = (document.documentElement.offsetWidth - 1080) / 2; |
||||
} |
||||
} else { |
||||
that.needFixed = false; |
||||
} |
||||
} else if (scrollTop >= that.topBannerHeight + 56) { |
||||
that.mobileTabNeedFixed = true; |
||||
} else { |
||||
that.mobileTabNeedFixed = false; |
||||
} |
||||
|
||||
// 变量windowHeight是可视区的高度 |
||||
const windowHeight = |
||||
document.documentElement.clientHeight || document.body.clientHeight; |
||||
// 变量scrollHeight是滚动条的总高度 |
||||
const scrollHeight = |
||||
document.documentElement.scrollHeight || document.body.scrollHeight; |
||||
// 滚动条到底部的条件 |
||||
if (scrollTop + windowHeight > scrollHeight - 50) { |
||||
// 写后台加载数据的函数 一定要用that |
||||
that.getArticleListData(); |
||||
} |
||||
}); |
||||
|
||||
const topBanner = []; |
||||
const clickShowBanner = localStorage.getItem('clickShowBanner') |
||||
? JSON.parse(localStorage.getItem('clickShowBanner')) |
||||
: []; |
||||
for (const banner of that.topBanner) { |
||||
if ( |
||||
banner.content_type === 'top_banner' && |
||||
!clickShowBanner.includes(banner.id) |
||||
) { |
||||
topBanner.push(banner); |
||||
} |
||||
} |
||||
if (topBanner.length > 0) { |
||||
that.popTopBannerItem = |
||||
topBanner[Math.floor(Math.random() * topBanner.length)]; |
||||
that.popTopBannerShow = true; |
||||
clickShowBanner.push(that.popTopBannerItem.id); |
||||
localStorage.setItem( |
||||
'clickShowBanner', |
||||
JSON.stringify(clickShowBanner) |
||||
); |
||||
const PopBannerinterval = setInterval(() => { |
||||
that.popTopBannerTime -= 1; |
||||
if (that.popTopBannerTime === 0) { |
||||
that.popTopBannerShow = false; |
||||
clearInterval(PopBannerinterval); |
||||
} |
||||
}, 1000); |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
methods: { |
||||
...mapActions({ |
||||
showLoginDialog: 'showLoginDialog' |
||||
}), |
||||
|
||||
goTopBanner(position, id, title, url, type) { |
||||
let des = ''; |
||||
if (position === 'top') { |
||||
if (type === 'video') { |
||||
const { href } = this.$router.resolve({ |
||||
path: '/video/' + id |
||||
}); |
||||
url = href; |
||||
} else if (type === 'article') { |
||||
const { href } = this.$router.resolve({ |
||||
path: '/article/' + id |
||||
}); |
||||
url = href; |
||||
} |
||||
if (type === 'top_banner') { |
||||
const clickShowBanner = localStorage.getItem('clickShowBanner') |
||||
? JSON.parse(localStorage.getItem('clickShowBanner')) |
||||
: []; |
||||
clickShowBanner.push(id); |
||||
localStorage.setItem( |
||||
'clickShowBanner', |
||||
JSON.stringify(clickShowBanner) |
||||
); |
||||
des = '轮播banner-' + id; |
||||
} else { |
||||
des = '轮播内容-' + id + '+' + title; |
||||
} |
||||
} else if (position === 'right') { |
||||
des = '首页右侧小banner-' + id; |
||||
} else if (position === 'bottom') { |
||||
des = '底部弹层广告-点击'; |
||||
} |
||||
this.baiduStat( |
||||
position === 'bottom' ? '底部弹层广告' : '糖尿病网-首页', |
||||
'click', |
||||
des |
||||
); |
||||
|
||||
if (url) { |
||||
if (this.deviceType === 'pc') { |
||||
window.open(url, '_blank'); |
||||
} else { |
||||
window.location.href = url; |
||||
} |
||||
} |
||||
}, |
||||
async getArticleListData() { |
||||
if (this.hasMore && !this.articleLoading) { |
||||
this.articleLoading = true; |
||||
const data = await this.$axios.$get( |
||||
'/article/list?page=' + this.articlePage |
||||
); |
||||
this.hasMore = data.detail.hasMore; |
||||
this.articleList = this.articleList.concat(data.detail.articleList); |
||||
this.articlePage = this.articlePage + 1; |
||||
this.articleLoading = false; |
||||
} |
||||
}, |
||||
async getHotArticleData() { |
||||
const data = await this.$axios.$get('/article/hot'); |
||||
this.hotArticle = data.detail.articleList; |
||||
}, |
||||
|
||||
gotoLogin() { |
||||
this.showLoginDialog(true); |
||||
}, |
||||
|
||||
// 接收 CommonHeader 传递过来的值 |
||||
getMsgFormSon(data) { |
||||
this.msgFormSon = data; |
||||
console.log(this.msgFormSon); |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
<style lang="scss"> |
||||
.index-page { |
||||
padding: 116px 0 76px; |
||||
|
||||
.header-outer { |
||||
position: fixed; |
||||
top: 0; |
||||
left: 0; |
||||
width: 100%; |
||||
min-width: $outer-width; |
||||
background: $main-blue-color; |
||||
z-index: 9; |
||||
} |
||||
|
||||
.library-page { |
||||
padding-top: 30px; |
||||
|
||||
.top-banner { |
||||
position: relative; |
||||
border-bottom: 1px solid $bg-color; |
||||
padding-bottom: 30px; |
||||
.pop-banner { |
||||
position: absolute; |
||||
top: 0; |
||||
left: 0; |
||||
width: 100%; |
||||
height: calc(100% - 30px); |
||||
z-index: 3; |
||||
span { |
||||
position: absolute; |
||||
top: 12px; |
||||
right: 12px; |
||||
width: 100px; |
||||
height: 25px; |
||||
border-radius: 5px; |
||||
background: rgba(0, 0, 0, 0.4); |
||||
cursor: pointer; |
||||
font-size: 16px; |
||||
color: $body-color; |
||||
line-height: 25px; |
||||
text-align: center; |
||||
} |
||||
img { |
||||
width: 100%; |
||||
height: 100%; |
||||
cursor: pointer; |
||||
} |
||||
} |
||||
|
||||
.top-banner-box { |
||||
overflow: hidden; |
||||
position: relative; |
||||
height: 100%; |
||||
border-radius: 4px; |
||||
|
||||
img { |
||||
width: 100%; |
||||
height: 100%; |
||||
cursor: pointer; |
||||
} |
||||
|
||||
.mask { |
||||
position: absolute; |
||||
bottom: 0; |
||||
left: 0; |
||||
padding: 43px 20px 0; |
||||
width: 100%; |
||||
height: 120px; |
||||
background: linear-gradient( |
||||
180deg, |
||||
rgba(0, 0, 0, 0) 0%, |
||||
rgba(0, 0, 0, 0.4) 100% |
||||
); |
||||
box-sizing: border-box; |
||||
|
||||
p { |
||||
font-size: 24px; |
||||
color: $body-color; |
||||
line-height: 30px; |
||||
} |
||||
} |
||||
} |
||||
|
||||
.el-carousel__indicators--horizontal { |
||||
left: 0; |
||||
padding-left: 20px; |
||||
transform: translateX(0); |
||||
|
||||
.el-carousel__indicator--horizontal { |
||||
margin-right: 8px; |
||||
padding: 0 0 20px; |
||||
|
||||
&:last-child { |
||||
margin-right: 0; |
||||
} |
||||
|
||||
.el-carousel__button { |
||||
@include roundFun(10px); |
||||
opacity: 1; |
||||
} |
||||
|
||||
&.is-active { |
||||
.el-carousel__button { |
||||
width: 34px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
.hot-videos { |
||||
border-bottom: 1px solid $bg-color; |
||||
padding-bottom: 10px; |
||||
} |
||||
|
||||
.doctor-box { |
||||
border-bottom: 1px solid $bg-color; |
||||
padding-bottom: 20px; |
||||
} |
||||
|
||||
.common-flex { |
||||
grid-template-columns: repeat(3, 33.33%); |
||||
} |
||||
|
||||
.not-login-box { |
||||
margin-bottom: 20px; |
||||
padding-top: 55px; |
||||
height: 202px; |
||||
background: $bg-color; |
||||
border-radius: 4px; |
||||
box-sizing: border-box; |
||||
text-align: center; |
||||
|
||||
h6 { |
||||
font-size: 24px; |
||||
color: $main-blue-color; |
||||
line-height: 31px; |
||||
font-weight: normal; |
||||
} |
||||
|
||||
p { |
||||
margin: 17px auto 0; |
||||
width: 208px; |
||||
height: 50px; |
||||
background: $extra-red; |
||||
border-radius: 4px; |
||||
font-size: 18px; |
||||
font-family: PingFangSC-Medium, PingFang SC; |
||||
font-weight: 500; |
||||
color: $body-color; |
||||
line-height: 50px; |
||||
cursor: pointer; |
||||
} |
||||
} |
||||
|
||||
.hot-articles-box { |
||||
margin-bottom: 30px; |
||||
|
||||
.common-title { |
||||
padding: 0; |
||||
font-size: 18px; |
||||
line-height: 25px; |
||||
|
||||
span { |
||||
position: relative; |
||||
top: -1px; |
||||
display: inline-block; |
||||
margin-left: 6px; |
||||
width: 30px; |
||||
height: 15px; |
||||
background: $extra-red; |
||||
text-align: center; |
||||
font-family: PingFangSC-Medium, PingFang SC; |
||||
font-weight: 500; |
||||
color: $body-color; |
||||
font-size: 12px; |
||||
line-height: 15px; |
||||
border-radius: 8px; |
||||
} |
||||
} |
||||
|
||||
div { |
||||
margin-top: 8px; |
||||
|
||||
a { |
||||
display: block; |
||||
position: relative; |
||||
border-bottom: 1px solid $bg-color; |
||||
padding: 10px 0 9px 124px; |
||||
height: 100px; |
||||
box-sizing: border-box; |
||||
|
||||
img { |
||||
position: absolute; |
||||
left: 0; |
||||
width: 110px; |
||||
height: 80px; |
||||
border-radius: 4px; |
||||
} |
||||
|
||||
p { |
||||
@include textEllipsisMore1Line(3); |
||||
font-size: 16px; |
||||
color: $font-color1; |
||||
line-height: 24px; |
||||
|
||||
span { |
||||
display: inline-block; |
||||
margin-right: 4px; |
||||
width: 25px; |
||||
height: 16px; |
||||
background: #ccc5bd; |
||||
border-radius: 4px; |
||||
text-align: center; |
||||
font-size: 14px; |
||||
font-family: Apis-Regular, Apis; |
||||
font-weight: 400; |
||||
color: $body-color; |
||||
line-height: 16px; |
||||
} |
||||
} |
||||
} |
||||
|
||||
a:first-child, |
||||
a:nth-child(2), |
||||
a:nth-child(3) { |
||||
p { |
||||
span { |
||||
background: $extra-yellow; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
.go-wechat { |
||||
display: flex; |
||||
margin-bottom: 30px; |
||||
padding: 20px; |
||||
width: 325px; |
||||
height: 150px; |
||||
background: $bg-color; |
||||
border-radius: 4px; |
||||
box-sizing: border-box; |
||||
align-items: center; |
||||
justify-content: space-between; |
||||
|
||||
div { |
||||
h4 { |
||||
font-size: 24px; |
||||
color: $main-blue-color; |
||||
line-height: 31px; |
||||
} |
||||
|
||||
p { |
||||
margin-top: 17px; |
||||
font-size: 16px; |
||||
font-family: Apis-Regular, Apis; |
||||
font-weight: 400; |
||||
color: $font-color2; |
||||
line-height: 26px; |
||||
} |
||||
} |
||||
|
||||
img { |
||||
width: 110px; |
||||
height: 110px; |
||||
background: $body-color; |
||||
} |
||||
} |
||||
|
||||
.right-banner { |
||||
width: 325px; |
||||
img { |
||||
width: 100%; |
||||
height: 150px; |
||||
border-radius: 4px; |
||||
cursor: pointer; |
||||
} |
||||
} |
||||
} |
||||
.bottom-ad { |
||||
position: fixed; |
||||
bottom: 66px; |
||||
width: 100%; |
||||
min-width: $outer-width; |
||||
height: 160px; |
||||
background: rgba(0, 0, 0, 0.5); |
||||
text-align: center; |
||||
z-index: 4; |
||||
& > div { |
||||
position: relative; |
||||
margin: 0 auto; |
||||
width: $content-width; |
||||
height: 160px; |
||||
cursor: pointer; |
||||
img { |
||||
width: $content-width; |
||||
height: 100%; |
||||
object-fit: inherit; |
||||
} |
||||
i { |
||||
position: absolute; |
||||
top: 0; |
||||
left: 0; |
||||
color: $body-color; |
||||
font-size: 25px; |
||||
} |
||||
} |
||||
} |
||||
&.isMobile { |
||||
padding: 0; |
||||
.library-page { |
||||
padding: 0; |
||||
background: $bg-color; |
||||
.top-banner { |
||||
padding: 15px; |
||||
border-bottom: none; |
||||
margin-bottom: 10px; |
||||
background: $body-color; |
||||
.el-carousel--horizontal { |
||||
padding-bottom: 16px; |
||||
} |
||||
.top-banner-box { |
||||
.mask { |
||||
padding: 7px 11.5px 0; |
||||
height: 62px; |
||||
p { |
||||
@include textEllipsisMore1Line(2); |
||||
font-size: 16px; |
||||
line-height: 24px; |
||||
white-space: inherit; |
||||
} |
||||
} |
||||
} |
||||
.el-carousel__indicators--horizontal { |
||||
bottom: 0; |
||||
left: 50%; |
||||
padding: 0; |
||||
transform: translateX(-50%); |
||||
.el-carousel__indicator--horizontal { |
||||
margin-right: 4px; |
||||
padding: 0; |
||||
.el-carousel__button { |
||||
width: 8px; |
||||
height: 4px; |
||||
background: #e3e3e3; |
||||
border-radius: 2px; |
||||
} |
||||
&.is-active { |
||||
.el-carousel__button { |
||||
width: 16px; |
||||
background: $main-blue-color; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,397 @@
@@ -0,0 +1,397 @@
|
||||
<template> |
||||
<div |
||||
class="outer-container" |
||||
:class="{ |
||||
isMobile: deviceType !== 'pc' |
||||
}" |
||||
> |
||||
<div |
||||
class="content-container more-page" |
||||
:class="{ isMobile: deviceType !== 'pc' }" |
||||
> |
||||
<CommonHeader |
||||
:device-type="deviceType" |
||||
:has-web-header="true" |
||||
:scroll-top="scrollTop" |
||||
:scroll-left="scrollLeft" |
||||
:search-height="searchHeight" |
||||
:tab-type="1" |
||||
:show-close="true" |
||||
@func="getMsgFormSon" |
||||
/> |
||||
<div class="top-entrance-box"> |
||||
<h6>栏目</h6> |
||||
<MobileHeader :is-more="true" /> |
||||
<h6>关于</h6> |
||||
<div class="other-box"> |
||||
<a |
||||
href="/other/about" |
||||
@click="baiduStat('关于我们', 'click', '关于我们')" |
||||
>关于我们</a |
||||
> |
||||
<a |
||||
href="/other/agreement" |
||||
@click="baiduStat('用户协议', 'click', '用户协议')" |
||||
>用户协议</a |
||||
> |
||||
<a |
||||
href="/other/privacy" |
||||
@click="baiduStat('隐私政策', 'click', '隐私政策')" |
||||
>隐私政策</a |
||||
> |
||||
<a |
||||
href="/other/cookies" |
||||
@click="baiduStat('cookies政策', 'click', 'cookies政策')" |
||||
>cookies政策</a |
||||
> |
||||
<a |
||||
href="/other/corporate" |
||||
@click="baiduStat('媒体合作', 'click', '媒体合作')" |
||||
>媒体合作</a |
||||
> |
||||
<a |
||||
style="display: none" |
||||
href="/other/disclaimer" |
||||
@click="baiduStat('免责声明', 'click', '免责声明')" |
||||
>免责声明</a |
||||
> |
||||
<a |
||||
style="display: none" |
||||
href="/other/link" |
||||
@click="baiduStat('友情链接', 'click', '友情链接')" |
||||
>友情链接</a |
||||
> |
||||
</div> |
||||
</div> |
||||
<UserInfoCommon |
||||
v-if="isLogin" |
||||
:bean-num="beanNum" |
||||
:total="total" |
||||
:has-more="hasMore" |
||||
:article-list="articleList" |
||||
:collect-loading="collectLoading" |
||||
/> |
||||
<div v-else class="not-login-box"> |
||||
<div class="top-box"> |
||||
<el-avatar |
||||
src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png" |
||||
style="cursor: pointer" |
||||
:size="50" |
||||
></el-avatar> |
||||
<p>未登录</p> |
||||
<span>更多个性化内容,登录查看</span> |
||||
</div> |
||||
<div class="bottom-box"></div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import { createNamespacedHelpers } from 'vuex'; |
||||
|
||||
const { mapActions, mapGetters, mapState } = createNamespacedHelpers('user'); |
||||
|
||||
export default { |
||||
name: 'MorePage', |
||||
// layout: 'common', |
||||
async asyncData({ req, $axios, store }) { |
||||
if (store.state.user.info && store.state.user.info.isLogin) { |
||||
const [dataA, dataB] = await Promise.all([ |
||||
$axios.$get('/user/collect-list?page=1', $axios.genSSROptions(req)), |
||||
$axios.$get('/user/bean-num', $axios.genSSROptions(req)) |
||||
]); |
||||
return { |
||||
...dataA.detail, |
||||
...dataB.detail |
||||
}; |
||||
} |
||||
}, |
||||
data() { |
||||
return { |
||||
scrollTop: 0, |
||||
scrollLeft: 0, |
||||
searchHeight: 0, |
||||
msgFormSon: true, // 页面显隐 |
||||
// isLogin: 0, |
||||
collectPage: 2, |
||||
collectLoading: false |
||||
}; |
||||
}, |
||||
|
||||
computed: { |
||||
...mapGetters({ |
||||
isLogin: 'isLogin' |
||||
}), |
||||
deviceType() { |
||||
return this.$store.state.device.deviceType; |
||||
}, |
||||
...mapState({ |
||||
loginInfo: (state) => state.loginInfo, |
||||
loginDialogVisible: (state) => state.loginDialogVisible |
||||
}) |
||||
}, |
||||
created() {}, |
||||
mounted() { |
||||
if (!this.isLogin) { |
||||
this.showLoginDialog(true); |
||||
document.getElementsByClassName('el-dialog__wrapper')[0].style.position = |
||||
'absolute'; |
||||
document.getElementsByClassName('el-dialog__wrapper')[0].style.top = |
||||
'auto'; |
||||
document.getElementsByClassName('el-dialog__wrapper')[0].style.bottom = |
||||
'0'; |
||||
document.getElementsByClassName('mobile-login-popup')[0].style.margin = |
||||
'0'; |
||||
document.getElementsByClassName('mobile-login-popup')[0].style.width = |
||||
'100%'; |
||||
} else { |
||||
const that = this; |
||||
this.$nextTick(() => { |
||||
window.addEventListener('scroll', function () { |
||||
// 变量scrollTop是滚动条滚动时,距离顶部的距离 |
||||
const scrollTop = |
||||
document.documentElement.scrollTop || document.body.scrollTop; |
||||
// 变量windowHeight是可视区的高度 |
||||
const windowHeight = |
||||
document.documentElement.clientHeight || document.body.clientHeight; |
||||
// 变量scrollHeight是滚动条的总高度 |
||||
const scrollHeight = |
||||
document.documentElement.scrollHeight || document.body.scrollHeight; |
||||
// 滚动条到底部的条件 |
||||
if (scrollTop + windowHeight > scrollHeight - 50) { |
||||
// 写后台加载数据的函数 一定要用that |
||||
that.getCollectList(); |
||||
} |
||||
}); |
||||
}); |
||||
} |
||||
}, |
||||
|
||||
methods: { |
||||
...mapActions({ |
||||
showLoginDialog: 'showLoginDialog' |
||||
}), |
||||
|
||||
// 接收 CommonHeader 传递过来的值 |
||||
getMsgFormSon(data) { |
||||
this.msgFormSon = data; |
||||
console.log(this.msgFormSon); |
||||
}, |
||||
|
||||
async getCollectList() { |
||||
if (this.hasMore && !this.collectLoading) { |
||||
this.collectLoading = true; |
||||
const data = await this.$axios.$get( |
||||
'/user/collect-list?page=' + this.collectPage |
||||
); |
||||
this.hasMore = data.detail.hasMore; |
||||
this.articleList = this.articleList.concat(data.detail.articleList); |
||||
this.collectPage = this.collectPage + 1; |
||||
this.collectLoading = false; |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
<style lang="scss"> |
||||
.more-page { |
||||
padding: 61px 0 0 !important; |
||||
.common-header-outer { |
||||
border-bottom: 1px solid $bg-color; |
||||
} |
||||
.top-entrance-box { |
||||
border-bottom: 10px solid $bg-color; |
||||
padding: 15px 16px 22px; |
||||
& > h6 { |
||||
margin-bottom: 16px; |
||||
font-size: 16px; |
||||
color: $font-color3; |
||||
line-height: 21px; |
||||
font-weight: normal; |
||||
} |
||||
.mobile-header { |
||||
overflow: hidden; |
||||
position: unset !important; |
||||
display: block; |
||||
margin-bottom: 20px; |
||||
border-bottom: none; |
||||
height: auto; |
||||
white-space: normal; |
||||
} |
||||
.mobile-header > div > div, |
||||
.other-box { |
||||
display: flex; |
||||
padding: 0 9px; |
||||
height: auto; |
||||
flex-wrap: wrap; |
||||
/*justify-content: space-between;*/ |
||||
p, |
||||
a { |
||||
margin-bottom: 20px; |
||||
/*width: 100%;*/ |
||||
font-size: 16px; |
||||
font-family: MicrosoftYaHei; |
||||
color: $font-color1; |
||||
line-height: 21px; |
||||
} |
||||
p:first-child { |
||||
display: none; |
||||
} |
||||
p, |
||||
a { |
||||
width: 25%; |
||||
white-space: nowrap; |
||||
box-sizing: border-box; |
||||
text-align: center; |
||||
} |
||||
a:nth-child(4n + 1), |
||||
p:nth-child(4n + 2) { |
||||
text-align: left; |
||||
} |
||||
p:nth-child(4n + 4) { |
||||
padding-left: 10%; |
||||
} |
||||
@media screen and (min-width: 375px) { |
||||
a:nth-child(4n + 3) { |
||||
/*padding-left: 5%;*/ |
||||
} |
||||
} |
||||
|
||||
a:nth-child(4n + 4), |
||||
p:nth-child(4n + 5) { |
||||
text-align: right; |
||||
} |
||||
} |
||||
} |
||||
.not-login-box { |
||||
margin-top: 12px; |
||||
background: $body-color; |
||||
.top-box { |
||||
border-bottom: 1px solid $bg-color; |
||||
padding: 16px 0 0 73px; |
||||
height: 81px; |
||||
position: relative; |
||||
box-sizing: border-box; |
||||
& > span:first-child { |
||||
position: absolute; |
||||
top: 15px; |
||||
left: 15px; |
||||
} |
||||
p { |
||||
margin-bottom: 5px; |
||||
font-size: 18px; |
||||
color: $font-color1; |
||||
line-height: 24px; |
||||
} |
||||
span:last-child { |
||||
font-size: 14px; |
||||
color: $font-color2; |
||||
line-height: 19px; |
||||
} |
||||
} |
||||
.bottom-box { |
||||
height: 370px; |
||||
} |
||||
} |
||||
.top-user-info { |
||||
position: unset; |
||||
min-width: 100%; |
||||
height: auto; |
||||
background: transparent; |
||||
& > div { |
||||
width: 100%; |
||||
& > div { |
||||
height: auto; |
||||
} |
||||
& > div:first-child { |
||||
margin: 0; |
||||
border-bottom: 1px solid $bg-color; |
||||
padding: 0; |
||||
height: 81px; |
||||
box-sizing: border-box; |
||||
& > a { |
||||
position: relative; |
||||
top: 0; |
||||
right: 0; |
||||
display: block; |
||||
padding: 28px 48px 0 69px; |
||||
width: 100%; |
||||
height: 80px; |
||||
box-sizing: border-box; |
||||
background: transparent; |
||||
line-height: 0; |
||||
text-align: left; |
||||
& > span:first-child { |
||||
position: absolute; |
||||
top: 15px; |
||||
left: 15px; |
||||
width: 50px !important; |
||||
height: 50px !important; |
||||
border-radius: 25px !important; |
||||
} |
||||
& > p { |
||||
font-size: 18px; |
||||
color: $font-color1; |
||||
line-height: 24px; |
||||
@extend .text-ellipsis; |
||||
} |
||||
& > i { |
||||
position: absolute; |
||||
top: 31px; |
||||
right: 15px; |
||||
width: 18px; |
||||
height: 18px; |
||||
color: $main-blue-color; |
||||
} |
||||
} |
||||
} |
||||
& > div:nth-child(2) { |
||||
float: none; |
||||
margin: 0; |
||||
padding: 0 0 0 70px; |
||||
width: 100%; |
||||
height: 80px; |
||||
& > img { |
||||
top: 15px; |
||||
left: 15px; |
||||
width: 50px; |
||||
height: 50px; |
||||
} |
||||
p { |
||||
margin-top: 30px; |
||||
} |
||||
h5 { |
||||
position: absolute; |
||||
top: 25px; |
||||
right: 15px; |
||||
margin: 0; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.user-collect { |
||||
border-top: 44px solid $bg-color; |
||||
padding: 0; |
||||
h6 { |
||||
margin-bottom: 1px; |
||||
padding-left: 15px; |
||||
background: $body-color; |
||||
font-size: 16px; |
||||
font-family: MicrosoftYaHei; |
||||
color: $main-blue-color; |
||||
font-weight: normal; |
||||
line-height: 48px; |
||||
} |
||||
} |
||||
.beans-popup { |
||||
.el-dialog__body { |
||||
.popup-content { |
||||
& > div { |
||||
position: unset; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
<template> |
||||
<div class="common-other-content about-us-page"> |
||||
<h6>关于我们</h6> |
||||
<div class="font-content"> |
||||
<h5>糖尿病网 智慧相伴</h5> |
||||
<p> |
||||
糖尿病网(www.diabetes.com.cn)是一个专注糖尿病领域的知识服务社区,致力于为每一位糖友提供专业的控糖知识及新闻资讯,帮助更多人拥有健康生活,远离糖尿病带来的困扰。 |
||||
</p> |
||||
<p> |
||||
糖尿病网目前在微信公众号\网站等渠道拥有大量用户,其中微信公众号稳居糖尿病垂直领域头部阵营。 |
||||
</p> |
||||
<h5>我们将持续探索和创新,让糖友生活更美好。</h5> |
||||
</div> |
||||
<div class="qrcode-box"> |
||||
<img :src="isPro ? qrcodeUrl : qrcodeUrlTest" alt="" /> |
||||
<p>微信服务号</p> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: 'OtherAboutPage', |
||||
layout: 'detail', |
||||
data() { |
||||
return { |
||||
isPro: false, |
||||
qrcodeUrl: require('~/assets/images/follow_qrcode.png'), |
||||
qrcodeUrlTest: require('~/assets/images/follow_qrcode_test.png') |
||||
}; |
||||
}, |
||||
head: { |
||||
title: '糖尿病网-关于我们', |
||||
meta: [{ hid: 'description', name: 'description', content: '' }] |
||||
}, |
||||
created() { |
||||
console.log('process.env.VUE_APP_TITLE:', process.env.VUE_APP_TITLE); |
||||
this.isPro = process.env.VUE_APP_TITLE === 'production'; |
||||
} |
||||
}; |
||||
</script> |
||||
<style lang="scss"> |
||||
.about-us-page { |
||||
padding-bottom: 246px !important; |
||||
.qrcode-box { |
||||
float: right; |
||||
margin-top: 44px; |
||||
padding-top: 9px; |
||||
width: 139px; |
||||
height: 174px; |
||||
background: $bg-color; |
||||
border-radius: 1px; |
||||
text-align: center; |
||||
box-sizing: border-box; |
||||
img { |
||||
width: 110px; |
||||
height: 110px; |
||||
} |
||||
p { |
||||
font-size: 18px; |
||||
color: $font-color1; |
||||
line-height: 30px; |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,322 @@
@@ -0,0 +1,322 @@
|
||||
<template> |
||||
<div class="common-other-content user-agreement-page"> |
||||
<h6>糖尿病网用户服务协议</h6> |
||||
<div class="font-content"> |
||||
<p style="text-align: right">修订日期:2021年11月8日</p> |
||||
<p style="text-align: right">生效日期:2021年11月8日</p> |
||||
<p> |
||||
糖尿病网是由诺和诺德(中国)制药有限公司(以下称“本公司”)所有及运营的网站/微信公众号/平台。 |
||||
《糖尿病网用户服务协议》(以下简称“本协议”)是您(或称“用户”,指注册、登录、使用、浏览糖尿病网的个人或组织) |
||||
与本公司及其关联公司及其合作单位(包括但不限于糖尿病网授权运营执行第三方)之间关于糖尿病网(域名为【app.diabetes.com.cn】,简称本平台) |
||||
就本平台服务所订立的协议(以下简称“本协议”)。本协议包括服务协议正文及所有本平台发布的各类规则等补充协议。 |
||||
平台发布的各类规则、规范、法律声明、隐私政策、通知、公告、帮助文档、温馨提示等均为本协议的补充协议,为本协议不可分割的一部分, |
||||
与本协议正文具有同等法律效力。 |
||||
</p> |
||||
<b>重要提示</b> |
||||
<p> |
||||
您在点击同意本协议之前,应当认真阅读本协议。请您务必审慎阅读、充分理解各条款内容,特别是免除或者限制责任的条款、法律适用和争议解决条款, |
||||
<b>特别是粗体下划线标识之处,您应重点阅读。</b |
||||
>如您对协议有任何疑问,可向糖尿病网咨询。 |
||||
</p> |
||||
<p> |
||||
<b> |
||||
如我们及关联公司(范围详见定义部分)提供了糖尿病网的服务或产品但未设独立用户协议的,则本协议同样适用于该部分服务或产品。 |
||||
我们及关联公司就其向您提供的产品或服务单独设立用户协议的,则相应产品或服务适用相应的用户协议。 |
||||
</b> |
||||
</p> |
||||
<p> |
||||
<b style="text-decoration: underline"> |
||||
【特别提示】请仔细阅读本协议(尤其是加粗或者下划线内容)并确认充分理解本协议全部规则和要点,一旦您开始使用或在我们更新本协议后 |
||||
(我们会及时提示您更新的情况)继续使用我们的产品和服务,即视为您同意本协议(含更新版本)的全部内容, |
||||
同意我们按本协议收集、使用、保存、共享和处理您的相关信息。 |
||||
</b> |
||||
</p> |
||||
<p> |
||||
<b>【特别提示】如您未满14周岁,请在法定监护人的陪同下阅读本协议。</b> |
||||
</p> |
||||
<p> |
||||
<b |
||||
>【重要提醒】 |
||||
本次更新主要更新了【如何收集使用个人信息】章节中的部分内容,进一步细化明确了我们收集信息的目的、方式、范围;以及增加了撤回同意的方式等。</b |
||||
> |
||||
</p> |
||||
<p> |
||||
如您对本协议或相关事宜有任何疑问,可通过邮件:<a |
||||
href="mailto:china-privacy@novonordisk.com" |
||||
target="_blank" |
||||
style="text-decoration: underline" |
||||
>china-privacy@novonordisk.com</a |
||||
>联系我们。 |
||||
</p> |
||||
<h5>一. 定义</h5> |
||||
<p> |
||||
<b>糖尿病网:</b>指糖尿病网(域名为app.diabetes.com.cn |
||||
)网站及“糖尿病网”微信公众号及小程序(以下称“本网站或客户端”)。 |
||||
</p> |
||||
<p> |
||||
<b>糖尿病网服务提供者:</b |
||||
>指糖尿病网的运营公司诺和诺德(中国)制药有限公司。 |
||||
</p> |
||||
<p> |
||||
<b>关联公司:</b |
||||
>指诺和诺德(中国)制药有限公司、丹麦诺和诺德公司及其附属、关联公司。 |
||||
</p> |
||||
<p> |
||||
<b>个人信息:</b |
||||
>指以电子或者其他方式记录的能够单独或者与其他信息结合识别特定自然人身份或者反映特定自然人活动情况的各种信息。 |
||||
</p> |
||||
<p> |
||||
<b>个人敏感信息:</b |
||||
>指包括身份证件号码、个人生物识别信息、财产信息、行踪轨迹、交易信息、14岁以下(含)儿童信息等的个人信息。 |
||||
</p> |
||||
<p> |
||||
<b>个人信息删除:</b |
||||
>指在实现日常业务功能所涉及的系统中去除个人信息的行为,使其保持不可被检索、访问的状态。 |
||||
</p> |
||||
<p><b>儿童:</b>指不满十四周岁的未成年人。</p> |
||||
<h5>二、 用户注册与使用</h5> |
||||
<p> |
||||
在您使用糖尿病网的部分服务时,可能需要您先完成用户调研,调研完成您即成为注册用户。 |
||||
</p> |
||||
<h6>1. 用户资格</h6> |
||||
<p> |
||||
您确认,在您开始使用糖尿病服务前,您应当具备中华人民共和国法律规定的与您行为相适应的民事行为能力。 |
||||
您知悉,无民事行为能力人、限制民事行为能力人以及无经营或特定经营资格的组织(视情况) |
||||
不当注册为糖尿病网用户或超过其民事权利或行为能力范围从事与糖尿病网进行交易的,其与糖尿病网之间的服务协议自始无效, |
||||
一经发现,糖尿病网有权立即停止与该用户的交易、注销该用户,您及您的监护人应依照法律规定承担因此而导致的一切后果。 |
||||
</p> |
||||
<h6>2. 账户注册</h6> |
||||
<p> |
||||
账户注册是指用户登录糖尿病网,按要求填写相关信息并确认同意履行本协议的过程。糖尿病网只允许每位用户注册及使用一个糖尿病网账户。 |
||||
<b |
||||
>如有证据证明或糖尿病网根据相关规则判断您存在不当注册或不当使用多个糖尿病网账户的情形,糖尿病网可采取冻结或关闭账户、取消订单、拒绝提供服务等措施,如给糖尿病网及相关方造成损失的,您还应承担赔偿责任。</b |
||||
> |
||||
</p> |
||||
<h6>3. 账户安全</h6> |
||||
<p> |
||||
您有权使用您设置或确认的糖尿病网会员名、手机号码(以下简称"账户名称")登录糖尿病网。 |
||||
<b>您的账户为您自行设置并由您保管</b>,建议您务必保管好您的账户。 |
||||
<b |
||||
>账户因您主动泄露或因您遭受他人攻击、诈骗等行为导致的损失及后果,糖尿病网并不承担责任,您应通过司法、行政等救济途径向侵权行为人追偿。</b |
||||
> |
||||
<br /> |
||||
由于您的糖尿病网平台账户关联您的个人信息及糖尿病网平台商业信息, |
||||
<b |
||||
>您的糖尿病网平台账户仅限您本人使用。未经糖尿病网平台同意,您直接或间接授权第三方使用您糖尿病网平台账户或获取您账户项下信息的行为无效。</b |
||||
> |
||||
如糖尿病网根据糖尿病网平台规则中约定的违约认定程序及标准判断您糖尿病网平台账户的使用可能危及您的账户安全及/或糖尿病网平台信息安全的,糖尿病网平台可拒绝提供相应服务或终止本协议。 |
||||
</p> |
||||
<h6>4. 账户转让</h6> |
||||
<p> |
||||
由于用户账户关联用户信用信息,仅当有法律明文规定、司法裁定或经糖尿病网平台同意,并符合糖尿病网平台规则规定的用户账户转让流程的情况下,您可进行账户的转让。 |
||||
您的账户一经转让,该账户项下权利义务一并转移。除此外,<b |
||||
>您的账户不得以任何方式转让,否则糖尿病网平台有权追究您的违约责任,且由此产生的责任及后果均由您自行承担。</b |
||||
> |
||||
</p> |
||||
<h6>5. 实名认证</h6> |
||||
<p> |
||||
作为糖尿病网平台经营者,为使您更好地使用糖尿病网服务,保障您的账户安全,糖尿病网平台可要求您按相关法律法规规定完成实名认证。 |
||||
</p> |
||||
<h6>6. 信息真实</h6> |
||||
<p> |
||||
在使用糖尿病网平台服务时,您应当按糖尿病网平台页面的提示准确完整地提供您的信息(包括您的姓名及电子邮件地址、联系电话、联系地址、收货地址等),以便糖尿病网或其他用户与您联系。 |
||||
<b |
||||
>您了解并同意,您有义务保持您提供信息的真实性及有效性。如您的信息发生变动,您应当在变动发生后10日内及时更新您的信息。</b |
||||
> |
||||
因您未及时更新信息导致未能正常使用糖尿病网服务或发生其他损失的,均由您承担相关责任。 |
||||
</p> |
||||
<h6>7. 税费承担</h6> |
||||
<p> |
||||
您因使用糖尿病网进行交易、获取有偿服务等而发生的所有您应纳的税赋由糖尿病网为您承担。 |
||||
</p> |
||||
<h5>三、商品交易</h5> |
||||
<p><b>您在糖尿病网兑换商品时必须遵守以下条款:</b></p> |
||||
<p> |
||||
1.您在使用糖尿病网服务时应遵守所有适用的中国法律、法规、条例和地方性法律的要求。您还必须确保遵守本协议及纳入本协议的所有其他条款和规则的规定。 |
||||
</p> |
||||
<p> |
||||
2.您决定通过糖尿病网兑换某一商品的,即代表您同意受该商品描述所含的出售条件的约束,只要该等出售条件不违反法律或本协议规定。 |
||||
</p> |
||||
<p> |
||||
3.您理解并认可糖尿病网上的订单生效规则:糖尿病网展示的商品信息(如商品名称、价格、商品描述等)仅构成要约邀请。 |
||||
<b |
||||
>当您通过糖尿病网订购商品,确定兑换并成功提交订单时(订单内容应包含兑换的商品数量、价格及支付方式、收货人、联系方式、收货地址等信息),即视为您向销售方发出了购买订单商品的要约。糖尿病网订单出库时,合同成立。</b |
||||
> |
||||
</p> |
||||
<p> |
||||
4.在您下订单的同时,也同时承认了您已经达到兑换所订商品的法定年龄,并对您在订单中提供的所有信息的真实性负责。由于糖尿病网出售部分产品的特殊性, |
||||
您可能被要求进一步提供与购买、使用、服用订单项下商品相关的信息,方能继续订单流程;该等信息视情况可能包括您或使用、服用商品人的个人信息或其他信息,您应保证提供的信息真实有效。 |
||||
<b |
||||
>糖尿病网有权对该等信息进行审核,并要求您做出进一步说明,并视情况可能拒绝您发出的订单或取消已经生成的订单。</b |
||||
> |
||||
</p> |
||||
<p>5.糖尿病网保留对您产品兑换数量、频次的限制权。</p> |
||||
<p> |
||||
6.您的订单确认后,如发生意外情况的,包括但不限于:糖尿病网上显示的订单内商品和/或订单明显错误或缺货; |
||||
<b |
||||
>糖尿病网将会通过站内信、或电话通知您,与您协商,您应当及时予以回应。</b |
||||
> |
||||
</p> |
||||
<p> |
||||
7.商品价格和可获性都将在糖尿病网上标明,显示的每一项价格。<b |
||||
>运费将另外结算。糖尿病网将在结算页面通知您,您应当仔细阅读。</b |
||||
> |
||||
</p> |
||||
<p> |
||||
8.当您在糖尿病网平台兑换商品及/或服务时,请您务必仔细确认所兑换商品的品名、价格、数量、型号、规格或服务的时间、内容、限制性要求等重要事项, |
||||
并在下单时核实您的联系地址、电话、收货人等信息。如您填写的收货人非您本人,则该收货人的行为和意思表示产生的法律后果均由您承担。 |
||||
<br /> |
||||
您的兑换行为应当基于真实的消费需求,不得存在对商品及/或服务实施恶意兑换、恶意维权等扰乱糖尿病网平台正常交易秩序的行为。 |
||||
<b |
||||
>基于维护糖尿病网平台交易秩序及交易安全的需要,糖尿病网发现上述情形时可主动执行关闭相关交易订单等操作。</b |
||||
> |
||||
</p> |
||||
<h5>四、您的权利和义务</h5> |
||||
<p> |
||||
1.您有权根据本协议的规定以及糖尿病网上发布的相关规则邀请关注好友、参加糖尿病网的有关活动,以及享受糖尿病网提供的其它信息服务。 |
||||
</p> |
||||
<p> |
||||
2.您应当保证在使用糖尿病网兑换商品过程中遵守诚实信用原则,不在购买过程中采取不正当行为,不扰乱网上交易的正常秩序。 |
||||
</p> |
||||
<p>3.您不得在糖尿病网发表包含以下内容的言论:</p> |
||||
<p> |
||||
①煽动、抗拒、破坏宪法和法律、行政法规实施的;<br /> |
||||
②煽动颠覆国家政权,推翻社会主义制度的;<br /> |
||||
③煽动、分裂国家,破坏国家统一的;<br /> |
||||
④煽动民族仇恨、民族歧视,破坏民族团结的;<br /> |
||||
⑤任何包含对种族、性别、宗教、地域内容等歧视的;<br /> |
||||
⑥捏造或者歪曲事实,散布谣言,扰乱社会秩序的;<br /> |
||||
⑦宣扬封建迷信、淫秽、色情、赌博、暴力、凶杀、恐怖、教唆犯罪的;<br /> |
||||
⑧公然侮辱他人或者捏造事实诽谤他人的,或者进行其他恶意攻击的;<br /> |
||||
⑨损害国家机关信誉的;<br /> |
||||
⑩其他违背社会公共利益或公共道德或依据相关糖尿病网平台协议、规则的规定不适合在糖尿病网平台上发布的;<br /> |
||||
⑪其他违反宪法、法律和行政法规的。<br /> |
||||
您在发表使用体验、讨论图片等,除遵守本条款外,还应遵守国家相关法律法规。<br /> |
||||
本公司有权根据国家法律及相关部门的要求对您上传、发布的内容进行审核,有权根据相关证据结合《侵权责任法》、《网络安全法》等法律法规、规章及本协议对侵权信息进行处理。 |
||||
</p> |
||||
<h5>五、糖尿病网的权利和义务</h5> |
||||
<p> |
||||
1.糖尿病网有义务在现有技术上维护整个网上交易平台的正常运行,并努力提升和改进技术,使您得以顺利享受网站服务。 |
||||
</p> |
||||
<p> |
||||
2.对您在注册使用糖尿病网中所遇到的有关的问题及反映的情况,糖尿病网应及时作出回复。 |
||||
</p> |
||||
<p> |
||||
3.<b |
||||
>对于您在糖尿病网上的不当行为,或任何糖尿病网认为应当暂时中止服务的情况,糖尿病网有权即刻作出暂时屏蔽相关信息、中止提供服务等处理,并通知您;</b |
||||
> |
||||
您对糖尿病网的处理措施存在异议的,可以提供相关证据予以说明。若经核实,您的行为确有违法违规或违反本平台用户协议、交易规则的情况,糖尿病网有权终止对您提供服务。 |
||||
</p> |
||||
<p> |
||||
4.糖尿病网将尽最大努力、采取必要合理措施,保障糖尿病网网络安全、稳定运行,糖尿病网将在业务范围内为您提供最大帮助。 |
||||
</p> |
||||
<h5>六、 通知</h5> |
||||
<p> |
||||
1.您在注册成为糖尿病网平台用户,并接受糖尿病网服务时,您在注册糖尿病网平台用户时生成的账户用于登录糖尿病网平台接收站内信和系统消息,作为您的有效联系方式。 |
||||
</p> |
||||
<p> |
||||
2.糖尿病网将向您的您送达各类通知,而此类通知的内容可能对您的权利义务产生重大的有利或不利影响,请您务必及时关注。 |
||||
</p> |
||||
<p> |
||||
3.糖尿病网通过上述联系方式向您发出通知,其中以电子的方式发出的书面通知,包括但不限于在糖尿病网平台公告, |
||||
向您提供的联系电话发送手机短信,向您的账号发送系统消息以及站内信信息,在发送成功后即视为送达。 |
||||
</p> |
||||
<h5>七、知识产权</h5> |
||||
<p>本平台著作权属于本公司所有。</p> |
||||
<p> |
||||
1.您在使用本平台的相关服务时发表上传的文字、图片及视频等应为您原创的信息或已获合法授权,并且确保该内容不会侵犯任何第三方的合法权益, |
||||
<b |
||||
>如果第三方提出关于知识产权的异议,本公司有权根据实际情况删除相关内容,并尽可能在处理之后对您进行通知,由此造成的损失及后果由您自行承担。</b |
||||
> |
||||
</p> |
||||
<p> |
||||
2.本公司单独拥有或与相关内容提供者共同拥有本平台/网站内所有内容(包括但不限于文字、图片、音频、视频资料及页面设计、编排、软件等) |
||||
或通过本平台提供产品或服务所涉及到的版权和/或其他相关知识产权。与本平台相关的标识为本公司的注册商标,受中国法律保护。 |
||||
</p> |
||||
<p> |
||||
3.除非中国法律另有规定,未经本公司书面许可,对于诺和诺德拥有版权和或其他相关知识产权的任何内容, |
||||
任何公司及个人不得复制或以其他任何方式进行使用(包含但不限于抄录、编辑、修改及传播)。对于本平台标识等本公司的注册商标,任何人不得擅自使用。 |
||||
已获得书面授权,可以使用本公司拥有版权和或其他相关知识产权的任何内容及商标标识的公司及个人使用上述内容时必须注明来源。 |
||||
</p> |
||||
<p> |
||||
4.本平台注明来源的稿件、图片及其他作品的内容均属转载,本平台的转载行为是基于信息共享和传播,并未进行权属、真实性等问题的核实,亦并不对其观点持任何立场; |
||||
其他公司或个人若从本平台下载使用所转内容,须保留本平台网站注明的“稿件来源”,并自负版权等法律责任。 |
||||
</p> |
||||
<p> |
||||
5.本平台的内容或转载内容若涉及版权及其他任何侵权问题,请版权人或其他权利人以书面形式向本公司反映,并提供相应身份证明、权属证明及详细的侵权情况证。 |
||||
</p> |
||||
<h5>八、个人信息保护</h5> |
||||
<p> |
||||
本公司将按照《糖尿病网个人信息及隐私保护政策》(填写链接)收集、使用、处理您的个人信息。按照适用法律,对于您的个人信息, |
||||
您享有查询、更正、删除以及注销服务或帐号的权利,请致电【400-810-2299】,具体流程请参见隐私政策。 |
||||
</p> |
||||
<h5>九、责任条款</h5> |
||||
<p> |
||||
本公司将尽合理努力为本平台提供准确的信息,但对所提供信息的准确性、即时性或完整想不作任何陈述、担保或保证。 |
||||
本公司对您由于访问或不能访问本平台或者因依赖本平台所提供的信息而产生的任何损失或损害不承担任何责任。 |
||||
</p> |
||||
<p> |
||||
本公司不对经您本人同意自愿并自行上传本人信息的准确性、及时性及完整性承担责任,请您本人在上传个人信息时仔细核对信息的准确性。 |
||||
如因您所上传数据有误而影响与上传信息相关的服务,本公司不承担由此产生的一切责任。 |
||||
如本人发现上传信息有误或不更新,可通过【<a |
||||
href="tel:400-810-2299" |
||||
style="text-decoration: underline" |
||||
>400-810-2299</a |
||||
>】更新相关信息。 |
||||
</p> |
||||
<p> |
||||
本平台可能含有其他平台的链接或引用或第三方提供的信息或内容,但本公司对其他平台或第三方提供的内容不承担任何责任, |
||||
而且对该内容所导致的损失或损害不承担任何责任。所有其他平台的链接仅为方便本平台用户而提供。 |
||||
</p> |
||||
<p> |
||||
您同意保障和维护本公司及其他您的利益,由于您使用本平台时出现内容违法、不真实、不正当、侵犯第三方合法权益, |
||||
或您违反本协议项下的任何条款而给本公司或任何其他第三人造成损失,您同意承担由此造成的损害赔偿责任。 |
||||
</p> |
||||
<p> |
||||
如您的行为使本公司陷于任何第三人主张权利,本公司可在对第三人承担金钱给付等义务后就全部损失向您追偿。 |
||||
</p> |
||||
<p> |
||||
本公司依法律规定承担相应义务,但无法对由于信息网络设备维护、连接故障,电脑、通讯或其他系统的故障,黑客活动、计算机病毒、电力故障,罢工, |
||||
暴乱,火灾,洪水,风暴,爆炸,战争,政府行为,司法行政机关的命令或因第三方原因而给您造成的损害结果承担责任。 |
||||
</p> |
||||
<h5>十、法律适用及管辖</h5> |
||||
<p> |
||||
本协议之订立、生效、解释、修订、补充、终止、执行与争议解决均适用中华人民共和国大陆地区法律。 |
||||
</p> |
||||
<p> |
||||
您和本公司一致同意有关本协议以及使用本平台的服务产生的争议将优先友好协商解决,经友好协商仍不能解决时,应向本公司住所地有管辖权的人民法院提起诉讼。 |
||||
</p> |
||||
<p>个人信息及隐私保护政策</p> |
||||
<p> |
||||
我们深知个人信息对您的重要性,并会尽全力保护您的个人信息安全可靠。我们致力于维持您对我们的信任,并恪守以下原则,保护您的个人信息: |
||||
权责一致原则、目的明确原则、选择同意原则、最少够用原则、确保安全原则、主体参与原则、公开透明原则等。 |
||||
同时,我们承诺,我们将按业界成熟的安全标准,采取相应的安全保护措施来保护您的个人信息。鉴于此,我们制定了本《隐私权政策》(下称“本政策 |
||||
/本隐私权政策”)并提醒您: |
||||
</p> |
||||
<p> |
||||
本政策适用于糖尿病网所提供的所有产品及服务。如我们及关联公司(范围详见定义部分)的产品或服务中使用了上述提供的产品或服务但未设独立隐私权政策的, |
||||
则本政策同样适用于该部分产品或服务。我们及关联公司就其向您提供的产品或服务单独设立有隐私权政策的,则相应产品或服务适用相应隐私权政策。 |
||||
需要特别说明的是,本政策不适用于其他第三方向您提供的服务,第三方向您提供的服务适用其向您另行说明的隐私权政策。 |
||||
</p> |
||||
<p>本服务的使用人在本政策中称为“用户”,或称为“您”。</p> |
||||
<p> |
||||
请您在使用本服务的各项产品及服务前,仔细阅读并充分理解本隐私保护政策协议。您在点击“确认/同意”按钮或勾选同意后,本政策即构成对双方有约束力的法律文件, |
||||
即表示您同意我们按照本政策收集、使用、处理和存储您的相关个人信息。如果您对本隐私政策有任何疑问、意见或建议,可通过本政策第9条提供的联系方式与我们联系。 |
||||
</p> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: 'OtherAgreementPage', |
||||
layout: 'detail', |
||||
data() { |
||||
return {}; |
||||
}, |
||||
head: { |
||||
title: '糖尿病网-用户协议', |
||||
meta: [{ hid: 'description', name: 'description', content: '' }] |
||||
} |
||||
}; |
||||
</script> |
@ -0,0 +1,127 @@
@@ -0,0 +1,127 @@
|
||||
<template> |
||||
<div class="common-other-content cookies-page"> |
||||
<h6>cookies政策</h6> |
||||
<div class="font-content"> |
||||
<p>cookies政策内容--待定</p> |
||||
<h5>1. 什么是cookies?</h5> |
||||
<p> |
||||
Cookie是网站服务器在您在自己的电脑浏览器或者移动设备上访问网站时放置的文本文件。Cookie包含一个独特的代码,允许糖尿病网在您访问网站时识别您的浏览器(称为对话缓存cookie),或稍后重复访问时识别您的浏览器(称为持久缓存cookie)。每个cookie都是您网页浏览器独有的。Cookies可能由您访问的网站服务器或由和网站合作的合作伙伴放置,即所谓的“第三方Cookies”。 |
||||
</p> |
||||
<p> |
||||
Cookies通常可使使用者与网站可以更容易和快捷地进行互动,并帮助使用者在网站不同部分之间进行切换。Cookies也可用于使网站的内容更符合访问者的需求,并使网站符合访问者的个人喜好和需要。 |
||||
</p> |
||||
<h5>2. [糖尿病网www.diabetes.com.cn ]对Cookies的使用</h5> |
||||
<p> |
||||
2.1 [本网站www.diabetes.com.cn]的拥有者为: 诺和诺德(中国)制药有限公司 |
||||
</p> |
||||
<p> |
||||
2.2诺和诺德利用cookies存储用户的参数设置,从而增强网站的功能。 |
||||
在糖尿病网网页上,使用必须的cookies如下: |
||||
</p> |
||||
<table> |
||||
<tr> |
||||
<td>cookies名称</td> |
||||
<td>cookies说明</td> |
||||
<td>过期时间</td> |
||||
</tr> |
||||
<tr> |
||||
<td>novo2</td> |
||||
<td>用于保存登录信息、包括用户登录状态、登录密码</td> |
||||
<td>15天后自动过期</td> |
||||
</tr> |
||||
<tr> |
||||
<td>xsrf-token</td> |
||||
<td>身份校验,防止非法请求伪造信息</td> |
||||
<td>15天后自动过期</td> |
||||
</tr> |
||||
</table> |
||||
<p> |
||||
2.2.1 |
||||
为了访问并使用某些部分,这些cookies是必须的。如果你拒绝这些cookies,网站的一些功能将不能正常运转。 |
||||
</p> |
||||
<h5>3. Cookie 管理</h5> |
||||
<p> |
||||
3.1 |
||||
您必须指示您是否允许将cookie放置在您的设备上,或者禁止某些类型的cookie。如果您不接受某些cookies的使用,那么网站的某些功能将无法被使用,或者您可能无法使用网站的某些服务。 |
||||
</p> |
||||
<p> |
||||
3.2 |
||||
如果您希望限制或阻止使用cookies,您必须通过网站上显示的cookie设定您的参数。您也可以通过浏览器设置限制cookies的使用。浏览器中的“帮助”功能会告诉您如何操作。 |
||||
</p> |
||||
<p>3.3 请注意:限制cookies可能影响糖尿病网网站的功能</p> |
||||
<h5>4. 数据隐私</h5> |
||||
<p> |
||||
4.1 |
||||
当您访问我们的网站时,我们会自动收集与您的电脑相关的基本信息,其所处位置信息以及您是跳转自哪个网站(如适用)。这些信息不能被用于识别您的个人身份。这些信息只会以聚合的形式使用,以使我们知晓我们的访问者来自哪里,他们都浏览了哪些内容和做了什么,以及他们针对哪些内容所花费时间最多。 |
||||
</p> |
||||
<p> |
||||
4.2 |
||||
当我们要求您提供任何可用于识别您个人身份的个人可识别信息时,我们都始终会征得您的许可并针对我们为何收集、如何收集、如何存储以及我们计划如何处理和使用这些信息做出解释。 |
||||
</p> |
||||
<p> |
||||
4.3 |
||||
我们将仅针对在收集过程中声明的目的收集并存储个人可识别信息。在我们针对已声明目的将您的信息处理完毕后,我们会将该信息删除并销毁,以保护您的隐私。 |
||||
</p> |
||||
<p> |
||||
4.4 有些数据基于我们的正当利益通过cookies进行收集,其目的包括: |
||||
改善我们的网站和您的用户体验、正常使用我们网站的功能、以及使我们能够针对特定目的优化我们的网站。 |
||||
</p> |
||||
<p> |
||||
4.5 |
||||
对于各类因为特定目的收集个人资料的cookie,糖尿病网将只会针对您在cookie |
||||
功能管理中许可的目的收集的个人资料进行处理。 |
||||
</p> |
||||
<p>4.6 您所有的个人资料将会被保密处理,并且只会用于以上所陈述的目的。</p> |
||||
<p> |
||||
4.7糖尿病网可能会聘请第三方服务供应商,他们将根据我们的委托处理您的个人信息。 |
||||
</p> |
||||
<p> |
||||
4.8 根据数据保护规定,您有以下权力。要行使这些权力,请通过<a |
||||
href="mailto:china-privacy@novonordisk.com" |
||||
target="_blank" |
||||
style="text-decoration: underline" |
||||
>china-privacy@novonordisk.com</a |
||||
>联系诺和诺德。 我们会在15日内对您进行回复。<br /> |
||||
您可查阅我们拥有您的何种个人信息;<br /> |
||||
您可获取一份结构化的常用机读格式个人信息副本;<br /> |
||||
您可要求对您的个人信息进行更新或修正;<br /> |
||||
您可要求您的个人信息被删除或销毁;<br /> |
||||
您可要求我们停止或限制对您的个人信息进行处理;<br /> |
||||
如您已许可我们对您的个人信息进行处理,您可在任何时间撤回许可。您撤回许可将不影响在您撤回许可前已进行的数据处理的合法性。<br /> |
||||
针对我们处理您个人信息的方式,您可向数据保护主管部门提出投诉。<br /> |
||||
</p> |
||||
<p> |
||||
依据适用法律,上述权利视数据处理活动具体情况可能会受到限制。如您有与上述权利相关问题或请求,请通过上述所述方式与我们取得联系。 |
||||
</p> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: 'OtherCookiesPage', |
||||
layout: 'detail', |
||||
data() { |
||||
return {}; |
||||
}, |
||||
head: { |
||||
title: '糖尿病网-cookies政策', |
||||
meta: [{ hid: 'description', name: 'description', content: '' }] |
||||
} |
||||
}; |
||||
</script> |
||||
<style lang="scss"> |
||||
.cookies-page { |
||||
table { |
||||
border-spacing: 0; |
||||
border-collapse: collapse; |
||||
td { |
||||
border: 1px solid $font-color3; |
||||
padding: 0 10px; |
||||
font-size: 18px; |
||||
color: $font-color3; |
||||
line-height: 40px; |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
<template> |
||||
<div class="common-other-content media-corporate-page"> |
||||
<h6>媒体合作</h6> |
||||
<div class="font-content"> |
||||
<p> |
||||
商务合作邮箱:<a |
||||
href="mailto:DHcommunications@novonordisk.com" |
||||
target="_blank" |
||||
>DHcommunications@novonordisk.com</a |
||||
> |
||||
</p> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: 'OtherCorporatePage', |
||||
layout: 'detail', |
||||
data() { |
||||
return {}; |
||||
}, |
||||
head: { |
||||
title: '糖尿病网-媒体合作', |
||||
meta: [{ hid: 'description', name: 'description', content: '' }] |
||||
} |
||||
}; |
||||
</script> |
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
<template> |
||||
<div class="common-other-content disclamier-page"> |
||||
<h6>免责声明</h6> |
||||
<div class="font-content"> |
||||
<p> |
||||
最新糖尿病调查结果显示,我国约有4亿人处在糖尿病前期,但90%的人不知道自己处于糖尿病前期。这是因为很多人不测血糖,或只测空腹血糖。殊不知,空腹血糖正常,不代表餐后血糖也正常,仅查空腹血糖,会有70%的糖尿病前期被漏诊。糖尿病前期是糖尿病发展的必经之路。那么什么是糖尿病前期,如何预防疾病进展呢? |
||||
</p> |
||||
<p> |
||||
最新糖尿病调查结果显示,我国约有4亿人处在糖尿病前期,但90%的人不知道自己处于糖尿病前期。这是因为很多人不测血糖,或只测空腹血糖。殊不知,空腹血糖正常,不代表餐后血糖也正常。但90%的人不知道自己处于糖尿病前期。这是因为很多人不测血糖,或只测空腹血糖。殊不知,空腹血糖正常,不代表餐后血糖也正常。 |
||||
</p> |
||||
<p> |
||||
最新糖尿病调查结果显示,我国约有4亿人处在糖尿病前期,但90%的人不知道自己处于糖尿病前期。这是因为很多人不测血糖,或只测空腹血糖。殊不知,空腹血糖正常,不代表餐后血糖也正常,仅查空腹血糖,会有70%的糖尿病前期被漏诊。糖尿病前期是糖尿病发展的必经之路。那么什么是糖尿病前期,如何预防疾病进展呢? |
||||
</p> |
||||
<p> |
||||
最新糖尿病调查结果显示,我国约有4亿人处在糖尿病前期,但90%的人不知道自己处于糖尿病前期。这是因为很多人不测血糖,或只测空腹血糖。殊不知,空腹血糖正常,不代表餐后血糖也正常。但90%的人不知道自己处于糖尿病前期。这是因为很多人不测血糖,或只测空腹血糖。殊不知,空腹血糖正常,不代表餐后血糖也正常。 |
||||
</p> |
||||
<p> |
||||
最新糖尿病调查结果显示,我国约有4亿人处在糖尿病前期,但90%的人不知道自己处于糖尿病前期。这是因为很多人不测血糖,或只测空腹血糖。殊不知,空腹血糖正常,不代表餐后血糖也正常,仅查空腹血糖,会有70%的糖尿病前期被漏诊。糖尿病前期是糖尿病发展的必经之路。那么什么是糖尿病前期,如何预防疾病进展呢? |
||||
</p> |
||||
<p> |
||||
最新糖尿病调查结果显示,我国约有4亿人处在糖尿病前期,但90%的人不知道自己处于糖尿病前期。这是因为很多人不测血糖,或只测空腹血糖。殊不知,空腹血糖正常,不代表餐后血糖也正常。但90%的人不知道自己处于糖尿病前期。这是因为很多人不测血糖,或只测空腹血糖。殊不知,空腹血糖正常,不代表餐后血糖也正常。 |
||||
</p> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: 'OtherDisclaimerPage', |
||||
layout: 'detail', |
||||
data() { |
||||
return {}; |
||||
}, |
||||
head: { |
||||
title: '糖尿病网-免责声明', |
||||
meta: [{ hid: 'description', name: 'description', content: '' }] |
||||
} |
||||
}; |
||||
</script> |
@ -0,0 +1,76 @@
@@ -0,0 +1,76 @@
|
||||
<template> |
||||
<div class="common-other-content other-link-page"> |
||||
<h6>我们的合作伙伴</h6> |
||||
<div class="link-content"> |
||||
<a href="https://www.dnurse.com"> |
||||
<img src="~/assets/images/wechat_color.png" alt="" /> |
||||
</a> |
||||
<a href="https://www.dnurse.com"> |
||||
<img src="~/assets/images/wechat_color.png" alt="" /> |
||||
</a> |
||||
<a href="https://www.dnurse.com"> |
||||
<img src="~/assets/images/wechat_color.png" alt="" /> |
||||
</a> |
||||
<a href="https://www.dnurse.com"> |
||||
<img src="~/assets/images/wechat_color.png" alt="" /> |
||||
</a> |
||||
<a href="https://www.dnurse.com"> |
||||
<img src="~/assets/images/wechat_color.png" alt="" /> |
||||
</a> |
||||
<a href="https://www.dnurse.com"> |
||||
<img src="~/assets/images/wechat_color.png" alt="" /> |
||||
</a> |
||||
</div> |
||||
<p> |
||||
申请加入友情链接,请联系邮箱 |
||||
<a href="mailto:DHcommunications@novonordisk.com" target="_blank" |
||||
>DHcommunications@novonordisk.com</a |
||||
> |
||||
</p> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: 'OtherLinkPage', |
||||
layout: 'detail', |
||||
data() { |
||||
return {}; |
||||
}, |
||||
head: { |
||||
title: '糖尿病网-友情链接', |
||||
meta: [{ hid: 'description', name: 'description', content: '' }] |
||||
} |
||||
}; |
||||
</script> |
||||
<style lang="scss"> |
||||
.other-link-page { |
||||
.link-content { |
||||
a { |
||||
display: inline-block; |
||||
margin: 0 19.33px 28px 0; |
||||
width: 240px; |
||||
height: 92px; |
||||
border-radius: 1px; |
||||
border: 1px solid #ededed; |
||||
box-sizing: border-box; |
||||
text-align: center; |
||||
img { |
||||
width: auto; |
||||
height: 100%; |
||||
} |
||||
} |
||||
a:nth-child(4n) { |
||||
margin-right: 0; |
||||
} |
||||
} |
||||
p { |
||||
font-size: 15px; |
||||
color: $font-color2; |
||||
line-height: 30px; |
||||
a { |
||||
color: $font-color2; |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,196 @@
@@ -0,0 +1,196 @@
|
||||
<template> |
||||
<div class="common-other-content privacy-policy-page"> |
||||
<h6>隐私政策</h6> |
||||
<div class="font-content"> |
||||
<p> |
||||
本网站为诺和诺德(中国)制药有限公司(下称“诺和诺德”)所有,其内容为诺和诺德受版权法保护的财产,并由诺和诺德对网站进行日常管理。 |
||||
</p> |
||||
<h5>1. 我们收集的信息</h5> |
||||
<p> |
||||
1.1 |
||||
我们收集能够帮助我们改善网站的信息。部分信息我们会直接询问您,而另一些则会自动收集。所有自动收集到的信息都会以聚合形式存储,且不能被用于识别具体个人。我们有时会请求您提供在某些情况下可被用于识别个人身份和隐私的信息。 |
||||
</p> |
||||
<p> |
||||
因此,我们所收集的信息可被分为两类:<br /> |
||||
a) 聚合的访问者统计数据 <br /> |
||||
b) 个人可识别信息 <br /> |
||||
我们不会将聚合的访问者统计数据与个人可识别信息进行关联。 |
||||
</p> |
||||
<p> |
||||
<b>聚合的访问者统计数据</b><br /> |
||||
当您访问我们的网站时,我们会自动收集与您的电脑相关的基本信息,其所处位置信息以及您是跳转自哪个网站(如适用)。这些信息不能被用于识别您的个人身份。这些信息只会以聚合的形式使用,以使我们知晓我们的访问者来自哪里,他们都浏览了哪些内容和做了什么,以及他们针对哪些内容所花费时间最多。 |
||||
</p> |
||||
<p> |
||||
<span style="text-decoration: underline">我们自动收集的信息包括:</span |
||||
><br /> |
||||
第一方cookie支持(无论您是否允许我们在您的电脑上放置cookie)<br /> |
||||
访问者ID(在可能时由我们放置在您电脑上的cookie提供)<br /> |
||||
跳转来源(即您来自哪个网站,如google.com)<br /> |
||||
访问日期与时间<br /> |
||||
区域及语言设置(以确定您在哪个国家)<br /> |
||||
操作系统(Windows、OS X、Linux、iOS、安卓等)<br /> |
||||
浏览器及浏览器版本(Chrome、IE、Firefox、Opera、Safari等)<br /> |
||||
屏幕分辨率(1280x1024、1024x768等)<br /> |
||||
JavaScript支持<br /> |
||||
Java支持<br /> |
||||
IP地址(电脑在因特网上的地址)<br /> |
||||
您所浏览网页的标题<br /> |
||||
您所浏览网页的URL<br /> |
||||
</p> |
||||
<p> |
||||
<b>个人可识别信息</b> |
||||
<br />有时,我们需要收集与您相关的更多个人信息。<br /> |
||||
</p> |
||||
<p> |
||||
<i>帮助您成为我们网站的注册用户</i><br /> |
||||
在您点击我们网站上的“注册”之后,我们会弹窗提示您扫描我们的微信公众号二维码以及查看我们的隐私政策,我们需要收集您的[微信Uni |
||||
ID],才能为您完成注册。<br /> |
||||
</p> |
||||
<p> |
||||
<i>为您提供更佳的网页体验及个性化推荐</i><br /> |
||||
在您成为我们的注册用户后,当您继续浏览我们的网站时,我们会收集并整合您在我们网站上以及我们的微信公众号中的[点击、关注、评论、分享、搜索、收藏]等浏览使用行为、浏览时长和设备信息,通过算法预测您的偏好特征,并基于特征标签产出间接人群画像,用于展示、推送您可能感兴趣的信息和内容。<br /> |
||||
若您同时是我们的诺和关怀的注册用户,我们还将这些个人信息与诺和关怀处理的个人信息进行进一步内部数据整合和分析,一同用于前述算法预测以及向您进行个性化内容推荐。 |
||||
</p> |
||||
<p> |
||||
<b |
||||
>我们努力保障您的浏览体验。如果您不想接受我们给您发送的推送内容,您可通过[“设置-开启/关闭个性化内容推荐”],选择关闭。</b |
||||
> |
||||
</p> |
||||
<p> |
||||
若我们要求您提供任何其他可用于识别您个人身份的个人可识别信息时,我们都会另行针对我们为何收集、如何收集、如何存储以及我们计划如何处理和使用这些信息做出解释。 |
||||
</p> |
||||
<h5>2. 我们如何使用信息</h5> |
||||
<p>2.1 我们将仅针对在收集过程中声明的目的使用并存储个人可识别信息。</p> |
||||
<h5>3. 敏感信息的收集</h5> |
||||
<p> |
||||
3.1 |
||||
我们不在本网站上收集或保存与您的健康、民族、宗教信仰或政治信念相关的敏感信息。 |
||||
</p> |
||||
<h5>4. 保护儿童</h5> |
||||
<p> |
||||
4.1 |
||||
保护儿童隐私非常重要。诺和诺德无意在未得到儿童父母或法定监护人许可的情况下收集其个人可识别信息(儿童定义为14岁以下的孩子)。在未征得其父母或法定监护人明确许可的情况下,儿童不应向诺和诺德提交其个人可识别信息。 |
||||
</p> |
||||
<p> |
||||
我们会在适当的地方指示儿童不要提交其个人信息。如您的孩子已提交其个人信息且您希望将其删除,请联系<a |
||||
href="mailto:china-privacy@novonordisk.com" |
||||
target="_blank" |
||||
style="text-decoration: underline" |
||||
>china-privacy@novonordisk.com</a |
||||
>。 |
||||
</p> |
||||
<h5>5. 如何确保信息安全</h5> |
||||
<p> |
||||
5.1 |
||||
本网站会在必要范围内收集个人数据。在任何情况下,所收集数据都不会以任何理由被出售给第三方。 |
||||
</p> |
||||
<h5>6. 数据在哪进行处理?</h5> |
||||
<p> |
||||
6.1 |
||||
我们依照适用的法律法规的规定,将我们所收集的您的个人信息存储于中华人民共和国境内。目前,我们不会将上述信息传输至其他地区,如果我们向其他地区传输,我们将遵循相关国家规定征求您的同意。 |
||||
</p> |
||||
<h5>7. 存储期限</h5> |
||||
<p> |
||||
在您的任何个人信息已连续【两(2)年】未被用于本隐私政策中所列明之目的时(以二者中较早者为准),我们将删除相关个人信息,或者将其进行匿名化,但法律法规另有规定的除外。 |
||||
</p> |
||||
<h5>8. 关于向第三方披露</h5> |
||||
<p> |
||||
8.1 |
||||
我们会聘请服务供应商依照我们的委托协助我们处理个人信息。我们在任何情况下都不会向第三方转让或分享您的个人可识别信息,但以下情况除外:<br /> |
||||
a) 在另行获得您的单独同意后,向经同意的其他个人信息处理者提供;<br /> |
||||
b) |
||||
因合并、分立、解散、被宣告破产等原因需要转移个人信息的,我们会要求新的持有您个人信息的个人信息处理者继续受本隐私政策的约束,否则我们将要求该第三方重新取得您的同意;<br /> |
||||
c) |
||||
我们可能会根据法律法规规定,或按政府主管部门的强制性要求,向有关主管部门提供您的个人信息。 |
||||
</p> |
||||
<h5>9. 访问者权利</h5> |
||||
<p> |
||||
9.1 依据数据保护规定,您拥有如下权利。欲行使这些权利,请通过<a |
||||
href="mailto:china-privacy@novonordisk.com" |
||||
target="_blank" |
||||
style="text-decoration: underline" |
||||
>china-privacy@novonordisk.com</a |
||||
>与诺和诺德联系。我们会在15日内对您进行回复。 |
||||
</p> |
||||
<p> |
||||
您可查阅我们拥有您的何种个人信息;<br /> |
||||
您可获取一份结构化的常用机读格式个人信息副本;<br /> |
||||
您可要求对您的个人信息进行更新或修正;<br /> |
||||
您可要求您的个人信息被删除或销毁;<br /> |
||||
您可要求我们停止或限制对您的个人信息进行处理;<br /> |
||||
如您已许可我们对您的个人信息进行处理,您可在任何时间撤回许可。您撤回许可将不影响在您撤回许可前已进行的信息处理的合法性。<br /> |
||||
针对我们处理您个人信息的方式,您可向数据保护主管部门提出投诉。<br /> |
||||
依据适用法律,上述权利视信息处理活动具体情况可能会受到限制。<br /> |
||||
如您有与上述权利相关问题或请求,请通过上述电子邮箱与我们取得联系。 |
||||
</p> |
||||
<h5>10. 使用cookies</h5> |
||||
<p> |
||||
10.1 您可阅读我们的<a |
||||
href="/other/cookies" |
||||
style="text-decoration: underline" |
||||
>Cookie政策</a |
||||
>了解更多我们如何使用cookies。 |
||||
</p> |
||||
<h5>11. 法律免责声明</h5> |
||||
<p><b>信息目的</b></p> |
||||
<p> |
||||
诺和诺德网站展示的内容是基于信息传播目的。本网站并不向您提供任何类型的意见或建议,也不应被作为任何决策或行动的依据。针对网站内容在任何特定领域是否适用,建议您咨询相关领域的专业顾问。特别是,本网站任何内容均不构成投资或交易诺和诺德股票的要约或邀请。此外,本网站提供一些疾病及其治疗方案的特定信息。此类信息不应被视为医疗建议。此类信息不能替代医疗专业人士的建议。如您有任何健康问题,或怀疑有健康问题,您应咨询全科医师或其他有资质的医疗服务提供者。 |
||||
</p> |
||||
<p><b>信息按“原样”提供</b></p> |
||||
<p> |
||||
本网站信息按“原样”提供,诺和诺德未就其(包括但不限于)适销性、针对某一特定目的的适宜性或非侵权性做出任何明示或默示的陈述或保证。诺和诺德未就其完整性、精确性、及时性、可及性、功能性及是否符合适用法律做出任何陈述或保证。使用本网站即代表您接受其信息可能不完整或不精确或不能满足您的需要或需求的风险。 |
||||
</p> |
||||
<p><b>免除责任</b></p> |
||||
<p> |
||||
对于您因访问或无法访问本网站,或您因依赖本网站任何信息所造成的破坏或伤害,诺和诺德及我们的内容提供者概不负责。诺和诺德无须为直接、间接、偶然性、后果性、惩罚性及特殊或其它破坏、机会丧失、利润丧失或其它任何类型的损失或破坏承担任何及一切责任。这一限制包括任何可能影响您电脑设备的破坏或病毒。 |
||||
</p> |
||||
<p><b>链接至其它网站</b></p> |
||||
<p> |
||||
如本网站包含指向其它非诺和诺德拥有或控制网站的链接,请知晓我们不为这些网站的隐私政策负责,对其也没有控制权。本隐私声明仅适用于在本网站上收集的信息。我们强烈建议您在访问每个收集个人可识别信息的网站时都阅读其隐私声明。 |
||||
</p> |
||||
<p><b>有本网站链接的网站</b></p> |
||||
<p> |
||||
诺和诺德不为任何链接至诺和诺德站点的网站背书。诺和诺德不为这些网站的内容负责,对用户可能选择向这些网站提供的信息也不负责。 |
||||
</p> |
||||
<p><b>变更</b></p> |
||||
<p> |
||||
诺和诺德保留在任何时间由其全权自主变更、修改、替换或删除任何本网站内容,限制访问本网站或中止分发本网站的权利。 |
||||
</p> |
||||
<p><b>内容的版权及使用</b></p> |
||||
<p> |
||||
本网站内容是诺和诺德受版权法保护的财产。本网站内所展示的商标、服务商标、商用名称、标识和产品均在全球范围内受到保护,未提前获得诺和诺德书面同意不得对其进行任何使用。欢迎您下载本网站内容,但仅供您个人进行非商业目的使用。禁止对上述内容进行修改或进一步复制。不得以任何其它方式复制或使用网站内容。 |
||||
</p> |
||||
<p><b>使用提问及评论功能</b></p> |
||||
<p> |
||||
您向本网站或诺和诺德以电子或任何其它手段所传递的任何问题、评论、建议或任何其它沟通手段,包括任何创意、发明、概念、技术或专业技能都不会被视为机密,而且将成为诺和诺德的财产;诺和诺德可不受限制地将其以任何方式用于任何目的,包括产品或服务的研发、制造及营销。 |
||||
</p> |
||||
<p><b>管辖法律</b></p> |
||||
<p> |
||||
您访问和使用本网站及其内容将受中国法律及中国缔结的国际条约管辖并据此解释。 |
||||
</p> |
||||
<h5>12. 联系方式</h5> |
||||
<p> |
||||
如您针对此隐私政策、服务协议、cookies政策及法律免责声明有任何问题,如您希望深入了解网站所拥有的任何与您相关的个人信息,如对诺和诺德使用您的个人信息您有任何担忧,您可通过<a |
||||
href="mailto:china-privacy@novonordisk.com" |
||||
target="_blank" |
||||
style="text-decoration: underline" |
||||
>china-privacy@novonordisk.com</a |
||||
>与我们取得联系。 |
||||
</p> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: 'OtherPrivacyPage', |
||||
layout: 'detail', |
||||
data() { |
||||
return {}; |
||||
}, |
||||
head: { |
||||
title: '糖尿病网-隐私政策', |
||||
meta: [{ hid: 'description', name: 'description', content: '' }] |
||||
} |
||||
}; |
||||
</script> |
@ -0,0 +1,480 @@
@@ -0,0 +1,480 @@
|
||||
<template> |
||||
<div |
||||
class="search-header-outer" |
||||
:class="{ isMobile: deviceType !== 'pc' }" |
||||
:style="{ top: -scrollTop + 'px', left: -scrollLeft + 'px' }" |
||||
> |
||||
<div class="box"> |
||||
<div class="search-header"> |
||||
<a href="/"> |
||||
<img |
||||
v-if="deviceType === 'pc'" |
||||
src="~/assets/images/home_logo.png" |
||||
alt="糖尿病网" |
||||
/> |
||||
<img v-else src="~/assets/images/mobile_logo.png" alt="糖尿病网" /> |
||||
</a> |
||||
<div class="search-user"> |
||||
<el-input |
||||
slot="reference" |
||||
v-model.trim="searchKey" |
||||
maxlength="50" |
||||
class="search-input" |
||||
:placeholder="toSouSuo" |
||||
@keyup.enter.native="enterSearch()" |
||||
@click.native="baiduStat('糖尿病网-搜索', 'click', '点击输入框')" |
||||
> |
||||
</el-input> |
||||
<i class="el-icon-error" @click="shutDown()"></i> |
||||
<i class="el-icon-search" @click="getSearch()"></i> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<div class="search-center"> |
||||
<div v-show="showHid" class="search-center-content"> |
||||
<h3 v-show="showHot" class="search-hot"> |
||||
大家都在看 |
||||
<i class="hot">HOT</i> |
||||
</h3> |
||||
<ul class="search-uls"> |
||||
<li |
||||
v-for="(item, index) in topSearch" |
||||
:key="index" |
||||
class="search-lis" |
||||
@click=" |
||||
baiduStat( |
||||
'移动端-搜索', |
||||
'click', |
||||
'移动端搜索页-大家在看-' + item.id + '+' + item.title |
||||
); |
||||
toTopSearch(item.id); |
||||
" |
||||
> |
||||
<span |
||||
class="search-spa" |
||||
:style="index < 3 ? colorData : colorDatas" |
||||
> |
||||
{{ index + 1 > 9 ? index + 1 : '' + (index + 1) }} |
||||
</span> |
||||
<span class="search-spas"> |
||||
{{ item.title }} |
||||
</span> |
||||
</li> |
||||
</ul> |
||||
</div> |
||||
<div v-show="showHidden" class="common-flex"> |
||||
<h2 v-show="showHidden" class="searchtitle"> |
||||
为您找到{{ numberOf }}条包含“<span class="fontcolor">{{ |
||||
searchKeys |
||||
}}</span |
||||
>”的内容 |
||||
</h2> |
||||
<template v-for="item in searchDataContent"> |
||||
<VideoArticleListItem |
||||
:key="'sea' + item.id" |
||||
:detail="item" |
||||
:column-num="3" |
||||
:device-type="deviceType" |
||||
@addStat=" |
||||
baiduStat( |
||||
'糖尿病网-搜索', |
||||
'click', |
||||
'搜索结果点击-' + item.id + '+' + item.title |
||||
) |
||||
" |
||||
/> |
||||
</template> |
||||
<p v-if="searchLoading" class="load-more"> |
||||
加载更多<i class="el-icon-loading"></i> |
||||
</p> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
data() { |
||||
return { |
||||
searchKey: '', // 搜索输入的内容 |
||||
showHidden: false, // 搜索内容页面显隐 |
||||
topSearch: [], // 热门搜索 |
||||
title: 1, // 热门搜索头部序号 |
||||
colorData: { background: '#EAAB00FF' }, // 热门搜索前三个列表序号悲剧颜色 |
||||
colorDatas: { background: '#CCC5BDFF' }, // 热门搜索前三个列表序号后面的悲剧颜色 |
||||
toSouSuo: '', // 输入框默认搜索内容 |
||||
searchHasMore: true, |
||||
searchPages: 1, |
||||
searchLoading: false, // 搜索加载loading显隐 |
||||
searchDataContent: [], // 搜索数据内容 |
||||
showHid: true, // 热门搜索显隐 |
||||
scrollTop: 0, |
||||
scrollLeft: 0, |
||||
showHot: false, // 大家都在看显隐 |
||||
numberOf: '', // 默认搜索提示 |
||||
searchKeys: '' |
||||
}; |
||||
}, |
||||
|
||||
computed: { |
||||
deviceType() { |
||||
return this.$store.state.device.deviceType; |
||||
} |
||||
}, |
||||
|
||||
mounted() { |
||||
const that = this; |
||||
that.baiduStat('糖尿病网-搜索', 'show', '搜索页面'); |
||||
// 热门搜索 |
||||
that.getHotSearchKey(); |
||||
|
||||
that.$nextTick(() => { |
||||
if (that.deviceType !== 'pc') { |
||||
window.addEventListener('scroll', function () { |
||||
// 变量scrollTop是滚动条滚动时,距离顶部的距离 |
||||
const scrollTop = |
||||
document.documentElement.scrollTop || document.body.scrollTop; |
||||
// 变量windowHeight是可视区的高度 |
||||
const windowHeight = |
||||
document.documentElement.clientHeight || document.body.clientHeight; |
||||
// 变量scrollHeight是滚动条的总高度 |
||||
const scrollHeight = |
||||
document.documentElement.scrollHeight || document.body.scrollHeight; |
||||
// 滚动条到底部的条件 |
||||
if ( |
||||
scrollTop + windowHeight > scrollHeight - 50 && |
||||
that.searchKey !== '' |
||||
) { |
||||
// 写后台加载数据的函数 一定要用that |
||||
that.searchData(); |
||||
} |
||||
}); |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
methods: { |
||||
// 请求大家都在看提示数据 |
||||
async getHotSearchKey() { |
||||
const data = await this.$axios.$get('/article/hot'); |
||||
this.topSearch = data.detail.articleList; |
||||
this.toSouSuo = '大家都在搜'; |
||||
if (data.detail.articleList.length > 0) { |
||||
this.showHot = true; |
||||
} |
||||
}, |
||||
|
||||
// 搜索内容页面数据 |
||||
async searchData() { |
||||
if (!this.searchLoading && this.searchHasMore) { |
||||
if (this.searchPages === 1) { |
||||
this.baiduStat('糖尿病网-搜索', 'click', '搜索控件-开始搜索'); |
||||
} |
||||
this.searchLoading = true; |
||||
const data = await this.$axios.$get( |
||||
'/search-article?keyword=' + |
||||
this.searchKey + |
||||
'&page=' + |
||||
this.searchPages |
||||
); |
||||
this.searchDataContent = this.searchDataContent.concat( |
||||
data.detail.dataList |
||||
); |
||||
this.searchHasMore = data.detail.hasMore; |
||||
this.searchPages = this.searchPages + 1; |
||||
this.searchLoading = false; |
||||
this.numberOf = data.detail.total; |
||||
this.searchKeys = this.searchKey; |
||||
} |
||||
}, |
||||
|
||||
// 点击大家都在看列表跳转文章详情页 |
||||
toTopSearch(id) { |
||||
const event = this.$router.resolve({ |
||||
path: `/article/` + id |
||||
}); |
||||
window.location.href = event.href; |
||||
}, |
||||
|
||||
// 关闭搜索页 |
||||
shutDown() { |
||||
window.history.go(-1); |
||||
}, |
||||
|
||||
// 点击搜索事件 |
||||
getSearch() { |
||||
if (this.searchKey === '') { |
||||
return false; |
||||
} |
||||
this.searchHasMore = true; |
||||
this.searchPages = 1; |
||||
this.searchDataContent = []; |
||||
this.searchData(); |
||||
// 显示搜索内容板块 |
||||
this.showHidden = true; |
||||
// 隐藏热门搜索板块 |
||||
this.showHid = false; |
||||
}, |
||||
|
||||
// 回车搜索事件 |
||||
enterSearch() { |
||||
if (this.searchKey === '') { |
||||
return false; |
||||
} |
||||
this.searchHasMore = true; |
||||
this.searchPages = 1; |
||||
this.searchDataContent = []; |
||||
this.searchData(); |
||||
// 显示搜索内容板块 |
||||
this.showHidden = true; |
||||
// 隐藏热门搜索板块 |
||||
this.showHid = false; |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss"> |
||||
.search-header-outer { |
||||
width: 100%; |
||||
height: 100%; |
||||
border-bottom: 1px solid $bg-color; |
||||
min-width: $outer-width; |
||||
background: $body-color; |
||||
z-index: 9; |
||||
|
||||
.box { |
||||
width: 100%; |
||||
height: 60px; |
||||
} |
||||
|
||||
.search-center { |
||||
width: 100%; |
||||
height: 100%; |
||||
position: relative; |
||||
padding-top: 14px; |
||||
|
||||
.common-flex { |
||||
width: 100%; |
||||
position: absolute; |
||||
top: 0; |
||||
left: 0; |
||||
.bottom { |
||||
display: none; |
||||
} |
||||
.searchtitle { |
||||
width: 100%; |
||||
height: 60px; |
||||
line-height: 60px; |
||||
font-size: 16px; |
||||
padding-left: 14px; |
||||
box-sizing: border-box; |
||||
} |
||||
} |
||||
|
||||
.search-tocenter { |
||||
width: 100%; |
||||
height: 100%; |
||||
background: red; |
||||
position: absolute; |
||||
top: 0; |
||||
left: 0; |
||||
|
||||
.searchdl { |
||||
width: 100%; |
||||
height: 30px; |
||||
background: #ccc; |
||||
} |
||||
} |
||||
|
||||
.search-center-content { |
||||
margin: auto 15px; |
||||
|
||||
.search-history { |
||||
font-size: 16px; |
||||
color: $font-color3; |
||||
|
||||
.el-icon-delete { |
||||
margin-left: 8px; |
||||
color: $font-color3; |
||||
} |
||||
} |
||||
|
||||
.search-ul { |
||||
margin-top: 18px; |
||||
width: 100%; |
||||
height: 100%; |
||||
float: left; |
||||
|
||||
.search-li { |
||||
font-size: 16px; |
||||
line-height: 48px; |
||||
border-radius: 26px; |
||||
margin-bottom: 21px; |
||||
margin-right: 10px; |
||||
padding-left: 26px; |
||||
padding-right: 26px; |
||||
border: 1px solid #ededed; |
||||
list-style: none; |
||||
float: left; |
||||
color: $font-color1; |
||||
} |
||||
} |
||||
|
||||
.search-hot { |
||||
width: 100%; |
||||
font-size: 16px; |
||||
float: left; |
||||
color: $font-color3; |
||||
|
||||
.hot { |
||||
width: 36px; |
||||
font-size: 12px; |
||||
border-radius: 25px; |
||||
text-align: center; |
||||
display: inline-block; |
||||
color: $body-color; |
||||
background: $extra-red; |
||||
} |
||||
} |
||||
|
||||
.search-uls { |
||||
width: 100%; |
||||
float: left; |
||||
margin-top: 30px; |
||||
|
||||
.search-lis { |
||||
font-size: 16px; |
||||
list-style: none; |
||||
margin-bottom: 10px; |
||||
width: 100%; |
||||
height: auto; |
||||
white-space: normal; |
||||
|
||||
.search-spa { |
||||
width: 27px; |
||||
height: 16px; |
||||
font-size: 14px; |
||||
border-radius: 4px; |
||||
line-height: 16px; |
||||
color: $body-color; |
||||
background: #ccc5bdff; |
||||
display: inline-block; |
||||
text-align: center; |
||||
margin-right: 5px; |
||||
float: left; |
||||
margin-top: 8px; |
||||
} |
||||
|
||||
.search-spas { |
||||
color: $font-color1; |
||||
padding-left: 13px; |
||||
padding-right: 15px; |
||||
@include textEllipsisMore1Line(2); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
.search-header { |
||||
margin: 0 auto; |
||||
display: flex; |
||||
width: $content-width; |
||||
height: 86px; |
||||
align-items: center; |
||||
|
||||
& > a:first-child { |
||||
width: 155px; |
||||
height: 46px; |
||||
|
||||
img { |
||||
width: 100%; |
||||
} |
||||
} |
||||
|
||||
.search-user { |
||||
display: flex; |
||||
width: 335px; |
||||
position: relative; |
||||
|
||||
.el-icon-search { |
||||
font-size: 20px; |
||||
position: absolute; |
||||
top: 10px; |
||||
right: 56px; |
||||
} |
||||
|
||||
.el-icon-error { |
||||
font-size: 24px; |
||||
margin-top: 6px; |
||||
color: $font-color3; |
||||
} |
||||
} |
||||
} |
||||
|
||||
&.isMobile { |
||||
top: 0 !important; |
||||
min-width: auto; |
||||
height: 60px; |
||||
|
||||
.search-header { |
||||
position: fixed; |
||||
padding: 0 15px; |
||||
width: 100%; |
||||
height: 60px; |
||||
box-sizing: border-box; |
||||
justify-content: space-between; |
||||
z-index: 999; |
||||
background: $body-color; |
||||
|
||||
& > a:first-child { |
||||
flex: none; |
||||
width: 36px; |
||||
height: 36px; |
||||
} |
||||
|
||||
.search-user { |
||||
width: 80%; |
||||
min-width: 233px; |
||||
.search-input { |
||||
margin-right: 20px; |
||||
width: calc(100% - 40px) !important; |
||||
|
||||
.el-input__inner { |
||||
border: none; |
||||
padding: 0 50px 0 12px; |
||||
width: 100% !important; |
||||
height: 40px; |
||||
background: $bg-color; |
||||
border-radius: 20px; |
||||
box-sizing: border-box; |
||||
color: $font-color1; |
||||
font-size: 16px; |
||||
} |
||||
|
||||
.el-input__suffix { |
||||
right: 16px; |
||||
|
||||
.el-input__icon { |
||||
width: 24px; |
||||
font-size: 24px; |
||||
color: $main-blue-color; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
.common-flex { |
||||
display: block !important; |
||||
|
||||
.load-more { |
||||
width: 100%; |
||||
} |
||||
.detail-list-item.isMobile { |
||||
padding: 15px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,82 @@
@@ -0,0 +1,82 @@
|
||||
<template> |
||||
<div class="user-page"> |
||||
<UserInfoCommon |
||||
:bean-num="beanNum" |
||||
:total="total" |
||||
:has-more="hasMore" |
||||
:article-list="articleList" |
||||
:collect-loading="collectLoading" |
||||
/> |
||||
<BottomRightFixed /> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: 'UserIndexPage', |
||||
layout: 'detail', |
||||
middleware: 'authenticated', |
||||
async asyncData({ req, $axios }) { |
||||
const [dataA, dataB] = await Promise.all([ |
||||
$axios.$get('/user/collect-list?page=1', $axios.genSSROptions(req)), |
||||
$axios.$get('/user/bean-num', $axios.genSSROptions(req)) |
||||
]); |
||||
return { |
||||
...dataA.detail, |
||||
...dataB.detail |
||||
}; |
||||
}, |
||||
data() { |
||||
return { |
||||
collectPage: 2, |
||||
collectLoading: false |
||||
}; |
||||
}, |
||||
head: { |
||||
title: '糖尿病网-个人中心', |
||||
meta: [{ hid: 'description', name: 'description', content: '' }] |
||||
}, |
||||
mounted() { |
||||
const that = this; |
||||
this.baiduStat('我的账户页', 'show', '我的账户页-访问'); |
||||
this.$nextTick(() => { |
||||
window.addEventListener('scroll', function () { |
||||
// 变量scrollTop是滚动条滚动时,距离顶部的距离 |
||||
const scrollTop = |
||||
document.documentElement.scrollTop || document.body.scrollTop; |
||||
// 变量windowHeight是可视区的高度 |
||||
const windowHeight = |
||||
document.documentElement.clientHeight || document.body.clientHeight; |
||||
// 变量scrollHeight是滚动条的总高度 |
||||
const scrollHeight = |
||||
document.documentElement.scrollHeight || document.body.scrollHeight; |
||||
// 滚动条到底部的条件 |
||||
if (scrollTop + windowHeight > scrollHeight - 50) { |
||||
// 写后台加载数据的函数 一定要用that |
||||
that.getCollectList(); |
||||
} |
||||
}); |
||||
}); |
||||
}, |
||||
|
||||
methods: { |
||||
async getCollectList() { |
||||
if (this.hasMore && !this.collectLoading) { |
||||
this.collectLoading = true; |
||||
const data = await this.$axios.$get( |
||||
'/user/collect-list?page=' + this.collectPage |
||||
); |
||||
this.hasMore = data.detail.hasMore; |
||||
this.articleList = this.articleList.concat(data.detail.articleList); |
||||
this.collectPage = this.collectPage + 1; |
||||
this.collectLoading = false; |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
<style lang="scss"> |
||||
.user-page { |
||||
padding-top: 259px; |
||||
} |
||||
</style> |