添加用户API功能

This commit is contained in:
yangjian 2020-03-29 20:48:02 +08:00
parent 91d5e56dc3
commit 46a7249a4a
37 changed files with 400 additions and 70 deletions

View File

@ -1,6 +1,11 @@
## 版本更新记录
### v0.3.3
### v0.3.4
- 添加基于用户的API模块支持通过用户Token获取文集、新建文档和上传图片
- 优化文档编辑页面布局;
### v0.3.3 2020-03-21
- 修复后台管理无法删除文档的错误;
- 修复后台新建无法新建文集的错误;

View File

@ -25,7 +25,7 @@ SECRET_KEY = '5&71mt9@^58zdg*_!t(x6g14q*@84d%ptr%%s6e0l50zs0we3d'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
VERSIONS = '0.3.3'
VERSIONS = '0.3.4'
ALLOWED_HOSTS = ['*']
@ -41,6 +41,7 @@ INSTALLED_APPS = [
'django.contrib.staticfiles',
'app_admin',
'app_doc',
'app_api',
'django.contrib.sitemaps',
]

View File

@ -23,12 +23,13 @@ from app_doc.sitemaps import SitemapAll
sitemaps = SitemapAll()
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('app_doc.urls')),
path('user/',include('app_admin.urls'),),
path('admin/', admin.site.urls), # Django自带admin
path('',include('app_doc.urls')), # doc应用
path('user/',include('app_admin.urls'),), # admin应用
path('api/',include('app_api.urls')), # API应用
re_path('^static/(?P<path>.*)$',serve,{'document_root':settings.STATIC_ROOT}),# 静态文件
re_path('^media/(?P<path>.*)$',serve,{'document_root':settings.MEDIA_ROOT}),# 媒体文件
path('sitemap.xml', views.index, {'sitemaps': sitemaps,'template_name':'sitemap/sitemap-index.xml'},name='sitemap',), # 站点地图索引
path('sitemap-<section>.xml', views.sitemap, {'sitemaps': sitemaps,'template_name':'sitemap/sitemap.xml'}, # 站点地图
name='django.contrib.sitemaps.views.sitemap')
path('sitemap-<section>.xml', views.sitemap, {'sitemaps': sitemaps,'template_name':'sitemap/sitemap.xml'},
name='django.contrib.sitemaps.views.sitemap') # 站点地图
]

View File

@ -1,16 +1,14 @@
# MrDoc - 记录文档,汇聚思想,一个简单的文档记录和管理应用
**PC端文档阅读界面**
# MrDoc - 记录文档,汇聚思想
![Mrdoc首页](./docs/mrdoc_2019080101.gif)
## 介绍
州的先生 - https://zmister.com - 自用并完全开源、基于Python编写的文档写作系统。
基于Python编写的文档写作系统,适合作为文档、知识和笔记管理工具
使用MarkDown快速记录你所思所想仿GitBook两栏式阅读界面,清晰高效浏览。
MarkDown快速书写两栏式阅读布局,清晰高效浏览。
当前版本为:**v0.3.3**,版本发布时间为**2020-03-21**,此版本主要更新了如下内容:
当前版本为:**v0.3.4**,版本发布时间为**2020-03-29**,此版本主要更新了如下内容:
- 修复后台管理无法删除文档的错误;
- 修复后台新建无法新建文集的错误;
@ -25,14 +23,14 @@
MrDoc拥有以下特点
- 站点与用户系统简洁
- 简洁的站点与用户系统
- 基于Django自带的用户模型实现简单高效的用户管理支持用户注册、用户登录、管理员等控制等功能
- 支持全站关闭注册;
- 支持注册邀请码配置;
- 支持广告位自定义配置;
- 支持统计代码自定义配置;
- 文档系统清晰
- 结构清晰地文档系统
- 基于文集的文档撰写和阅读;
- 基于Editormd的Markdown编辑器支持Markdown语法的文档写作支持图片粘贴上传支持从本地MD文件中插入内容
- 提供文档模板功能,支持文档模板的创建、修改;
@ -41,15 +39,15 @@ MrDoc拥有以下特点
- 支持文集后台导出为markdown文本格式.md文件、前台导出为EPUB电子书
- 基于文集进行权限控制提供公开、私密、指定用户可见、访问码可见4种权限模式
在开发过程中参考和借鉴了GitBook、ShowDoc、Wordbook等应用和网站的功能与样式并使用了众多开源组件、插件。
## 应用核心依赖环境
- 编程语言Python 3+
- Django框架2.0+
MrDoc基于Python语言的Django Web框架配合前端的LayUI、JQuery等库进行开发。
## 安装教程
后端环境推荐使用Python3.4+、Django2.1+的版本。
## 安装简明教程
### 1、安装依赖库
```
@ -57,7 +55,9 @@ pip install -r requirements.txt
```
### 2、配置数据库信息
默认情况下MrDoc使用Django的SQLite数据库在旧版本MrDoc附带了一个Sqlit数据库如果你使用的是MrDoc源码附带的Sqlite数据库或使用Sqlite数据库则无需另外配置数据库。
默认情况下MrDoc使用Django的SQLite数据库如果你使用Sqlite数据库则无需另外配置数据库。
如果有配置其他数据库的需求,请在/MrDoc/MrDoc目录下打开settings.py文件在约80行的位置将如下代码
```
DATABASES = {
@ -81,6 +81,7 @@ DATABASES = {
}
```
### 3、初始化数据库
在安装完所需的第三方库并配置好数据库信息之后,我们需要对数据库进行初始化。
在项目路径下打开命令行界面,运行如下命令生成数据库迁移:
@ -107,13 +108,10 @@ python manage.py createsuperuser
python manage.py runserver
```
## 使用说明
## 使用说明文档
详见MrDoc使用文档:http://mrdoc.zmister.com
## 二次开发说明
详见MrDoc使用文档:http://mrdoc.zmister.com
## 问题提交和反馈
@ -123,32 +121,31 @@ python manage.py runserver
### 2、加入MrDoc交流群
加入MrDoc交流QQ群群号为735507293入群密码mrdoc
加入MrDoc交流QQ群群号为**735507293**,入群密码:**mrdoc**
## 版本更新
## 更多应用截图
关注州的先生微信公众号IDzmister2016、博客 https://zmister.com 及时获取MrDoc版本更新信息。
### 首页
![MrDoc首页](./docs/mrdoc_index.jpg)
## 更多截图
### 文集页
![](./docs/mrdoc_project.jpg)
### 文档界面
![MrDoc文档页](./docs/mrdoc_docdetail.png)
![MrDoc文档页](./docs/mrdoc_doc.jpg)
### 文档编写界面
![](./docs/mrdoc_doc_write.jpg)
### 普通用户后台界面
![MrDoc普通用户后台](./docs/mrdoc_user.jpg)
### 管理员后台界面
![MrDoc管理员后台](./docs/mrdoc_admin.jpg)
### 登录界面
![MrDoc登录页](./docs/mrdoc_login.png)
### 注册界面
![MrDoc注册页](./docs/mrdoc_register.png)
### 文档写作界面
![MrDoc写作页](./docs/mrdoc_write.png)
### 文档模板界面
![MrDoc文档模板页](./docs/mrdoc_doctemp.png)
### 管理员后台界面
![MrDoc管理员后台](./docs/mrdoc_admin.png)
### 普通用户后台界面
![MrDoc普通用户后台](./docs/mrdoc_user.png)

View File

@ -1,6 +1,8 @@
from django.core.exceptions import PermissionDenied # 权限拒绝异常
from django.http import Http404
from django.http import Http404,JsonResponse
from app_admin.models import SysSetting
from app_api.models import UserToken
from django import VERSION as django_version
# 超级管理员用户需求
def superuser_only(function):
@ -55,4 +57,24 @@ def allow_report_file(function):
return function(request, *args, **kwargs)
else:
raise Http404
return _inner
return _inner
# Token头验证
# def check_token(function):
# def _inner(request,*args,**kwargs):
# if django_version[0] == 2 and django_version[1] >= 2:
# headers = request.headers
# print(headers)
# if 'Mrdoc-Token' not in headers:
# return JsonResponse({'data':'非法请求'})
# else:
# token = headers['Mrdoc-Token']
# is_vail = UserToken.objects.filter(token=token)
# if is_vail.exists():
# return function(request,*args,**kwargs)
# else:
# return JsonResponse({'data':'无效Token'})
# else:
# metas = request.META
# return _inner

0
app_api/__init__.py Normal file
View File

3
app_api/admin.py Normal file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

5
app_api/apps.py Normal file
View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class AppApiConfig(AppConfig):
name = 'app_api'

View File

@ -0,0 +1,29 @@
# Generated by Django 2.2.11 on 2020-03-22 09:28
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='UserToken',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('token', models.CharField(max_length=250, verbose_name='token值')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': '用户Token',
'verbose_name_plural': '用户Token',
},
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 2.2.11 on 2020-03-22 09:29
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app_api', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='usertoken',
name='token',
field=models.CharField(max_length=250, unique=True, verbose_name='token值'),
),
]

View File

14
app_api/models.py Normal file
View File

@ -0,0 +1,14 @@
from django.db import models
from django.contrib.auth.models import User
# Token模型
class UserToken(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
token = models.CharField(verbose_name="token值",max_length=250,unique=True)
def __str__(self):
return self.user
class Meta:
verbose_name = '用户Token'
verbose_name_plural = verbose_name

3
app_api/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

14
app_api/urls.py Normal file
View File

@ -0,0 +1,14 @@
# coding:utf-8
# @文件: urls.py
# @创建者:州的先生
# #日期2020/3/22
# 博客地址zmister.com
from django.urls import path,re_path
from app_api import views
urlpatterns = [
path('manage_token/',views.manage_token,name='manage_token'),# 用户Token管理
path('get_projects/',views.get_projects,name="api_get_projects"), # 获取文集列表
path('create_doc/',views.create_doc,name="api_create_doc"), # 新建文档
path('upload_img/',views.upload_img,name="api_upload_img"), # 粘贴上传文件
]

116
app_api/views.py Normal file
View File

@ -0,0 +1,116 @@
from django.shortcuts import render
from django.http.response import JsonResponse,HttpResponse
from django.views.decorators.csrf import csrf_exempt # CSRF装饰器
from django.views.decorators.http import require_http_methods,require_safe,require_GET
from django.contrib.auth.decorators import login_required # 登录需求装饰器
from django.core.exceptions import PermissionDenied,ObjectDoesNotExist
from app_api.models import UserToken
from app_doc.models import Project,Doc,Image
import time,hashlib
import traceback,json
from django.conf import settings
from app_doc.util_upload_img import upload_generation_dir,base_img_upload
# MrDoc 基于用户的Token访问API模块
# Token管理页面
@require_http_methods(['POST','GET'])
@login_required()
def manage_token(request):
if request.method == 'GET':
try:
token = UserToken.objects.get(user=request.user).token # 查询用户Token
except ObjectDoesNotExist:
token = '你还没有生成过Token'
return render(request,'app_api/manage_token.html',locals())
elif request.method == 'POST':
try:
user = request.user
now_time =str(time.time())
string = 'user_{}_time_{}'.format(user,now_time).encode('utf-8')
token_str = hashlib.sha224(string).hexdigest()
user_token = UserToken.objects.filter(user=user)
if user_token.exists():
UserToken.objects.get(user=user).delete()
UserToken.objects.create(
user=user,
token=token_str
)
return JsonResponse({'status':True,'data':token_str})
except:
if settings.DEBUG:
print(traceback.print_exc())
return JsonResponse({'status':False,'data':'生成出错,请重试!'})
# 获取文集
@require_GET
def get_projects(request):
token = request.GET.get('token','')
try:
token = UserToken.objects.get(token=token)
projects = Project.objects.filter(create_user=token.user) # 查询文集
project_list = []
for project in projects:
item = {
'id':project.id, # 文集ID
'name':project.name, # 文集名称
'type':project.role # 文集状态
}
project_list.append(item)
return JsonResponse({'status':True,'data':project_list})
except ObjectDoesNotExist:
return JsonResponse({'status':False,'data':'token无效'})
# 新建文档
@require_http_methods(['GET','POST'])
@csrf_exempt
def create_doc(request):
token = request.GET.get('token', '')
project_id = request.POST.get('pid','')
doc_title = request.POST.get('title','')
doc_content = request.POST.get('doc','')
try:
# 验证Token
token = UserToken.objects.get(token=token)
# 文集是否属于用户
is_project = Project.objects.filter(create_user=token.user,id=project_id)
# 新建文档
if is_project.exists():
Doc.objects.create(
name = doc_title, # 文档内容
pre_content = doc_content, # 文档的编辑内容,意即编辑框输入的内容
top_doc = project_id, # 所属文集
create_user = token.user # 创建的用户
)
return JsonResponse({'status': True, 'data': 'ok'})
else:
return JsonResponse({'status':False,'data':'非法请求'})
except ObjectDoesNotExist:
return JsonResponse({'status': False, 'data': 'token无效'})
# 上传图片
@csrf_exempt
@require_http_methods(['GET','POST'])
def upload_img(request):
##################
# {"success": 0, "message": "出错信息"}
# {"success": 1, "url": "图片地址"}
##################
token = request.GET.get('token', '')
base64_img = request.POST.get('data','')
try:
# 验证Token
token = UserToken.objects.get(token=token)
# 上传图片
result = base_img_upload(base64_img, '', token.user)
return JsonResponse(result)
# return HttpResponse(json.dumps(result), content_type="application/json")
except ObjectDoesNotExist:
return JsonResponse({'success': 0, 'data': 'token无效'})
except:
if settings.DEBUG:
print(traceback.print_exc())
return JsonResponse({'success':0,'data':'上传出错'})

View File

@ -0,0 +1,23 @@
# Generated by Django 2.2.11 on 2020-03-22 14:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app_doc', '0013_image_file_name'),
]
operations = [
migrations.AlterField(
model_name='doc',
name='content',
field=models.TextField(blank=True, null=True, verbose_name='文档内容'),
),
migrations.AlterField(
model_name='doc',
name='pre_content',
field=models.TextField(blank=True, null=True, verbose_name='编辑内容'),
),
]

View File

@ -26,11 +26,27 @@ class Project(models.Model):
"pro_id":self.pk}
)
# # 文集协作模型
# class ProjectCollaborator(models.Model):
# project = models.ForeignKey(Project,on_delete=models.CASCADE)
# user = models.ForeignKey(User,on_delete=models.CASCADE)
# # 用户的协作模式0表示可新建文档可修改删除自己新建的文档1表示可新建文档可修改删除所有文档
# role = models.IntegerField(choices=((0,0),(1,1)),default=0,verbose_name='协作模式')
# create_time = models.DateTimeField(auto_now=True,verbose_name='添加时间')
# modify_time = models.DateTimeField(auto_now_add=True,verbose_name='修改时间')
#
# def __str__(self):
# return self.project
#
# class Meta:
# verbose_name = '文集协作'
# verbose_name_plural = verbose_name
# 文档模型
class Doc(models.Model):
name = models.CharField(verbose_name="文档标题",max_length=50)
pre_content = models.TextField(verbose_name="编辑内容")
content = models.TextField(verbose_name="文档内容")
pre_content = models.TextField(verbose_name="编辑内容",null=True,blank=True)
content = models.TextField(verbose_name="文档内容",null=True,blank=True)
parent_doc = models.IntegerField(default=0,verbose_name="上级文档")
top_doc = models.IntegerField(default=0,verbose_name="所属项目")
sort = models.IntegerField(verbose_name='排序',default=99)
@ -65,7 +81,7 @@ class DocTemp(models.Model):
modify_time = models.DateTimeField(auto_now=True)
def __str__(self):
self.name
return self.name
class Meta:
verbose_name = '文档模板'
@ -78,7 +94,7 @@ class ProjectReport(models.Model):
allow_epub = models.IntegerField(default=0,verbose_name="前台导出EPUB")
def __str__(self):
self.project.name
return self.project.name
class Meta:
verbose_name = '文集导出'

View File

@ -5,7 +5,6 @@
# 博客地址zmister.com
# MrDoc文集文档导出相关功能代码
from django.conf import settings
import subprocess
import datetime,time
import re

View File

@ -50,9 +50,9 @@ def img_upload(files, dir_name, user):
file_name = files.name.replace(file_suffix,'').replace('.','') + '_' +str(int(time.time())) + '.' + file_suffix
path_file=os.path.join(relative_path, file_name)
path_file = settings.MEDIA_ROOT + path_file
print('文件路径:',path_file)
# print('文件路径:',path_file)
file_url = settings.MEDIA_URL + relative_path + file_name
print("文件URL",file_url)
# print("文件URL",file_url)
with open(path_file, 'wb') as f:
for chunk in files.chunks():
f.write(chunk) # 保存文件
@ -72,9 +72,9 @@ def base_img_upload(files,dir_name, user):
file_name = str(datetime.datetime.today()).replace(':', '').replace(' ', '_').split('.')[0] + '.png' # 日期时间
path_file = os.path.join(relative_path, file_name)
path_file = settings.MEDIA_ROOT + path_file
print('文件路径:', path_file)
# print('文件路径:', path_file)
file_url = settings.MEDIA_URL + relative_path + file_name
print("文件URL", file_url)
# print("文件URL", file_url)
with open(path_file, 'wb') as f:
f.write(files_base) # 保存文件
Image.objects.create(

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

BIN
docs/mrdoc_admin.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

BIN
docs/mrdoc_doc.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

BIN
docs/mrdoc_doc_write.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

BIN
docs/mrdoc_project.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

BIN
docs/mrdoc_user.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

View File

@ -0,0 +1,67 @@
{% extends 'app_doc/manage_base.html' %}
{% load staticfiles %}
{% block title %}用户Token管理{% endblock %}
{% block content %}
<div class="layui-card-header" style="margin-bottom: 10px;">
<div class="layui-row">
<span style="font-size:18px;">用户Token管理
</span>
</div>
</div>
<div class="layui-row">
<form>
<div class="layui-form-item">
<label class="layui-form-label">Token值</label>
<div class="layui-input-inline" style="width:450px;">
<input type="text" name="token" id="token" value="{{token}}" autocomplete="off" class="layui-input" readonly>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">操作</label>
<button class="layui-btn layui-btn-normal" type="button" id="copy-token" onclick="copyToken()">复制</button>
<button class="layui-btn layui-btn-normal" type="button" onclick="generaToken()">重新生成Token</button>
</div>
</form>
</div><hr>
<div class="layui-row">
*借助Token你可以无需打开MrDoc网站直接通过更加自动化的方式进行文档编写配合MrDoc浏览器剪藏扩展还能将MrDoc化身为便捷的网页内容摘录工具
</div>
{% endblock %}
{% block custom_script %}
<script>
//复制Token
copyToken = function(){
var token_val = document.getElementById("token");
token_val.select();
document.execCommand("Copy");
layer.msg("已复制!")
};
//生成Token
generaToken = function(){
layer.open({
type:1,
title:'重置Token',
area:'300px;',
id:'delPro',//配置ID
content:'<div style="margin:10px;">警告此操作将重新为你的账户生成Token旧Token将失效</div>',
btn:['确定','取消'], //添加按钮
btnAlign:'c', //按钮居中
yes:function (index,layero) {
$.post("{% url 'manage_token' %}",function(r){
if(r.status){
//生成成功
//window.location.reload();
$('#token').val(r.data);
layer.close(index)
}else{
//生成失败,提示
//console.log(r)
layer.close(index)
layer.msg(r.data)
}
})
},
});
};
</script>
{% endblock %}

View File

@ -8,18 +8,18 @@
<div class="layui-form" style="">
<!-- 标题 -->
<div style="padding-bottom:10px;">
<label class="layui-form-label" style="padding-left:0px;padding-right:0px;"><i class="fa fa-header"></i> 文档标题</label>
<div class="layui-input-block" style="margin-left:95px;">
<!--<label class="layui-form-label" style="padding-left:0px;padding-right:0px;"><i class="fa fa-header"></i> 文档标题</label>-->
<div class="layui-input-block" style="margin-left:0px;">
<input type="text" name="doc-name" id="doc-name" required lay-verify="required" placeholder="请输入文档标题" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-row">
<div class="layui-col-md4 layui-col-sm6 " style="padding-bottom:10px;">
<label class="doc-form-label">所属文集</label>
<div class="layui-col-md3 layui-col-sm6 " style="padding-bottom:10px;">
<!--<label class="doc-form-label">所属文集</label>-->
<div class="layui-input-inline">
<select name="pro_id" lay-verify="required" lay-filter="project" id="project">
<option value=""></option>
<option value="">请选择一个文集</option>
<option value="-1">新建文集</option>
{% for p in project_list %}
{% if p.role == 1 %}
@ -37,10 +37,10 @@
</div>
<div class="layui-col-md3 layui-col-sm6" style="padding-bottom:10px;">
<label class="doc-form-label">所属上级</label>
<!--<label class="doc-form-label">所属上级</label>-->
<div class="layui-input-inline">
<select name="parent_id" lay-verify="required" id="parent-doc">
<option value=""></option>
<option value="">请选择所属上级</option>
</select>
</div>
</div>

View File

@ -64,6 +64,9 @@
<li class="layui-nav-item layui-nav-itemed">
<a href="{% url 'manage_image' %}"><i class="layui-icon layui-icon-picture"></i> 图片素材管理</a>
</li>
<li class="layui-nav-item layui-nav-itemed">
<a href="{% url 'manage_token' %}"><i class="layui-icon layui-icon-key"></i> 用户Token管理</a>
</li>
</ul>
</div>
</div>

View File

@ -23,18 +23,12 @@
<!-- 标题 -->
<div>
<label class="layui-form-label" style="padding-left:0px;padding-right:0px;"><i class="layui-icon layui-icon-edit"></i> 文档标题</label>
<div class="layui-input-block" style="margin-left:95px;">
<!--<label class="layui-form-label" style="padding-left:0px;padding-right:0px;"><i class="layui-icon layui-icon-edit"></i> 文档标题</label>-->
<div class="layui-input-block" style="margin-left:0;">
<input type="text" name="doc-name" id="doc-name" required lay-verify="required" placeholder="请输入文档标题" value="{{ doc.name }}" class="layui-input">
</div>
</div><br>
<!--<label class="doc-form-label">标题</label>-->
<!--<div class="layui-input-inline">-->
<!--<input type="text" name="doc-name" id="doc-name" required lay-verify="required" placeholder="请输入文档标题" value="{{ doc.name }}" class="layui-input" >-->
<!--</div>-->
<label class="doc-form-label">文集</label>
<div class="layui-input-inline">
<select name="pro_id" lay-verify="required" lay-filter="project" id="project" disabled>
@ -42,10 +36,10 @@
</select>
</div>
<label class="doc-form-label">上级文档</label>
<!--<label class="doc-form-label">上级文档</label>-->
<div class="layui-input-inline">
<select name="parent_id" lay-verify="required" id="parent-doc">
<option value="0"></option>
<option value="0">选择上级文档</option>
</select>
</div>

View File

@ -42,7 +42,7 @@
</div>
<div class="layui-card-body">
<p>作者:{{p.create_user}}</p>
<p>最新:<u>{{p.id | get_new_doc}}</u></p>
<p style="overflow: hidden;white-space: nowrap;text-overflow: ellipsis;">最新:<u title="{{p.id | get_new_doc}}">{{p.id | get_new_doc}}</u></p>
<p class="tooltip">简介:
{% if p.intro == "" %}
<span class="">此文集没有填写简介</span>