6 changed files with 595 additions and 8 deletions
-
7src/components/Debug.vue
-
290src/components/Publish.vue
-
2src/components/Task.vue
-
213src/components/User.vue
-
90src/pages/index.vue
-
1src/service/request.js
@ -0,0 +1,7 @@ |
|||
<template> |
|||
<div>debug</div> |
|||
</template> |
|||
|
|||
<script setup></script> |
|||
|
|||
<style lang="scss" scoped></style> |
@ -0,0 +1,290 @@ |
|||
<template> |
|||
<!-- scrollToFirstError="smooth" --> |
|||
<t-form |
|||
:data="formData" |
|||
:rules="rules" |
|||
ref="form" |
|||
@reset="onReset" |
|||
@submit="onSubmit" |
|||
> |
|||
<t-form-item label="用户名" help="这里可以展示一段说明文字" name="account"> |
|||
<t-input v-model="formData.account" placeholder="请输入用户名"></t-input> |
|||
</t-form-item> |
|||
<t-form-item label="年龄" name="age"> |
|||
<t-input-number v-model="formData.age" placeholder="年龄" /> |
|||
</t-form-item> |
|||
<t-form-item label="籍贯" name="region"> |
|||
<t-cascader |
|||
v-model="formData.region" |
|||
placeholder="请选择籍贯" |
|||
:options="regionOptions" |
|||
clearable |
|||
filterable |
|||
/> |
|||
</t-form-item> |
|||
<t-form-item label="密码" name="password"> |
|||
<t-input |
|||
type="password" |
|||
v-model="formData.password" |
|||
placeholder="请输入密码" |
|||
></t-input> |
|||
</t-form-item> |
|||
<t-form-item label="邮箱" name="email"> |
|||
<t-input v-model="formData.email" placeholder="请输入邮箱"></t-input> |
|||
</t-form-item> |
|||
<t-form-item label="性别" name="gender"> |
|||
<t-radio-group v-model="formData.gender"> |
|||
<t-radio value="male">男</t-radio> |
|||
<t-radio value="female">女</t-radio> |
|||
</t-radio-group> |
|||
</t-form-item> |
|||
<t-form-item label="课程" name="course"> |
|||
<t-checkbox-group |
|||
v-model="formData.course" |
|||
:options="courseOptions" |
|||
></t-checkbox-group> |
|||
</t-form-item> |
|||
<t-form-item label="学院" name="college"> |
|||
<t-select |
|||
v-model="formData.college" |
|||
class="demo-select-base" |
|||
clearable |
|||
filterable |
|||
placeholder="请选择所在学院" |
|||
> |
|||
<t-option |
|||
v-for="(item, index) in options" |
|||
:value="item.value" |
|||
:label="item.label" |
|||
:key="index" |
|||
> |
|||
{{ item.label }} |
|||
</t-option> |
|||
</t-select> |
|||
</t-form-item> |
|||
<t-form-item |
|||
label="入学时间" |
|||
name="date" |
|||
:rules="[ |
|||
{ required: true, message: '此项必填' }, |
|||
{ date: { delimiters: ['/', '-', '.'] }, message: '日期格式有误' }, |
|||
]" |
|||
> |
|||
<t-date-picker v-model="formData.date"></t-date-picker> |
|||
</t-form-item> |
|||
<t-form-item label="个人网站" name="content.url"> |
|||
<t-input |
|||
v-model="formData.content.url" |
|||
placeholder="请输入个人网站地址" |
|||
></t-input> |
|||
</t-form-item> |
|||
<t-form-item label="个人简介" help="请用一句话介绍自己" name="description"> |
|||
<t-textarea |
|||
v-model="formData.description" |
|||
placeholder="请用一句话介绍自己" |
|||
></t-textarea> |
|||
</t-form-item> |
|||
<t-form-item label="兴趣爱好" name="hobby"> |
|||
<t-tree-select |
|||
v-model="formData.hobby" |
|||
filterable |
|||
:data="hobbyOptions" |
|||
placeholder="请选择你的兴趣爱好" |
|||
></t-tree-select> |
|||
</t-form-item> |
|||
|
|||
<t-form-item> |
|||
<t-space size="10px"> |
|||
<t-button theme="primary" type="submit">提交</t-button> |
|||
<t-button theme="default" variant="base" type="reset">重置</t-button> |
|||
</t-space> |
|||
</t-form-item> |
|||
</t-form> |
|||
</template> |
|||
<script> |
|||
const INITIAL_DATA = { |
|||
account: '', |
|||
password: '', |
|||
// description: '', |
|||
age: undefined, |
|||
region: '', |
|||
email: '', |
|||
gender: '', |
|||
college: '', |
|||
date: '', |
|||
content: { |
|||
url: '', |
|||
}, |
|||
hobby: [], |
|||
course: [], |
|||
} |
|||
export default { |
|||
data() { |
|||
return { |
|||
formData: { ...INITIAL_DATA }, |
|||
hobbyOptions: [ |
|||
{ |
|||
label: '运动', |
|||
value: 'sports', |
|||
children: [ |
|||
{ |
|||
label: '足球', |
|||
value: 'soccer', |
|||
}, |
|||
{ |
|||
label: '篮球', |
|||
value: 'basketball', |
|||
}, |
|||
], |
|||
}, |
|||
{ |
|||
label: '娱乐', |
|||
value: 'entertainment', |
|||
children: [ |
|||
{ |
|||
label: '电影', |
|||
value: 'movie', |
|||
}, |
|||
{ |
|||
label: '旅游', |
|||
value: 'trip', |
|||
}, |
|||
], |
|||
}, |
|||
], |
|||
regionOptions: [ |
|||
{ |
|||
label: '广东', |
|||
value: '1', |
|||
children: [ |
|||
{ |
|||
label: '深圳', |
|||
value: '1.1', |
|||
}, |
|||
{ |
|||
label: '广州', |
|||
value: '1.2', |
|||
}, |
|||
], |
|||
}, |
|||
{ |
|||
label: '湖南', |
|||
value: '2', |
|||
children: [ |
|||
{ |
|||
label: '长沙', |
|||
value: '2.1', |
|||
}, |
|||
], |
|||
}, |
|||
], |
|||
courseOptions: [ |
|||
{ label: '语文', value: '1' }, |
|||
{ label: '数学', value: '2' }, |
|||
{ label: '英语', value: '3' }, |
|||
{ label: '体育', value: '4' }, |
|||
], |
|||
options: [ |
|||
{ label: '计算机学院', value: '1' }, |
|||
{ label: '软件学院', value: '2' }, |
|||
{ label: '物联网学院', value: '3' }, |
|||
], |
|||
// FormItem.rules 优先级大于 Form.rules |
|||
rules: { |
|||
account: [ |
|||
{ |
|||
required: true, |
|||
message: '姓名必填', |
|||
type: 'error', |
|||
trigger: 'blur', |
|||
}, |
|||
// trigger 默认为 'change' |
|||
{ required: true, message: '姓名必填', type: 'error' }, |
|||
{ whitespace: true, message: '姓名不能为空' }, |
|||
{ |
|||
min: 2, |
|||
message: '至少需要两个字符,一个中文等于两个字符', |
|||
type: 'warning', |
|||
trigger: 'blur', |
|||
}, |
|||
{ |
|||
max: 10, |
|||
message: '姓名字符长度超出', |
|||
type: 'warning', |
|||
trigger: 'blur', |
|||
}, |
|||
], |
|||
description: [ |
|||
{ |
|||
validator: val => val.length >= 5, |
|||
message: '至少 5 个字,中文长度等于英文长度', |
|||
type: 'warning', |
|||
}, |
|||
{ |
|||
validator: val => val.length < 20, |
|||
message: '不能超过 20 个字,中文长度等于英文长度', |
|||
type: 'warning', |
|||
}, |
|||
], |
|||
age: [{ required: true, message: '年龄必填', type: 'error' }], |
|||
region: [{ required: true, message: '籍贯必填', type: 'error' }], |
|||
|
|||
password: [ |
|||
{ required: true, message: '密码必填', type: 'error' }, |
|||
{ len: 8, message: '请输入 8 位密码', type: 'warning' }, |
|||
{ |
|||
pattern: /[A-Z]+/, |
|||
message: '密码必须包含大写字母', |
|||
type: 'warning', |
|||
}, |
|||
], |
|||
college: [{ required: true, message: '此项必填' }], |
|||
email: [ |
|||
{ required: true, message: '邮箱必填' }, |
|||
{ |
|||
email: { ignore_max_length: true }, |
|||
message: '请输入正确的邮箱地址', |
|||
}, |
|||
], |
|||
gender: [{ required: true, message: '性别必填' }], |
|||
course: [ |
|||
{ required: true, message: '课程必填' }, |
|||
{ |
|||
validator: val => val.length <= 2, |
|||
message: '最多选择 2 门课程', |
|||
type: 'warning', |
|||
}, |
|||
], |
|||
hobby: [{ required: true, message: '爱好必填', type: 'error' }], |
|||
'content.url': [ |
|||
{ required: true, message: '个人网站必填' }, |
|||
{ |
|||
url: { |
|||
protocols: ['http', 'https', 'ftp'], |
|||
require_protocol: true, |
|||
}, |
|||
message: '请输入正确的个人主页', |
|||
}, |
|||
], |
|||
}, |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
onReset() { |
|||
this.$message.success('重置成功') |
|||
console.log('formData', this.formData) |
|||
}, |
|||
onSubmit({ validateResult, firstError }) { |
|||
if (validateResult === true) { |
|||
this.$message.success('提交成功') |
|||
} else { |
|||
console.log('Errors: ', validateResult) |
|||
this.$message.warning(firstError) |
|||
} |
|||
}, |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style scoped></style> |
@ -0,0 +1,213 @@ |
|||
<template> |
|||
<div class="user_component"> |
|||
<t-card> |
|||
<template #title> |
|||
<t-space direction="vertical"> |
|||
<t-breadcrumb> |
|||
<t-breadcrumbItem>首页</t-breadcrumbItem> |
|||
<t-breadcrumbItem>用户管理中心</t-breadcrumbItem> |
|||
</t-breadcrumb> |
|||
</t-space> |
|||
</template> |
|||
<t-table |
|||
bordered |
|||
hover |
|||
tableLayout="auto" |
|||
row-key="id" |
|||
:data="data" |
|||
:columns="columns" |
|||
resizable |
|||
/> |
|||
<t-pagination class="page" :total="30" /> |
|||
</t-card> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="jsx"> |
|||
import { MessagePlugin } from 'tdesign-vue-next' |
|||
import { |
|||
FileCopyIcon, |
|||
ErrorCircleFilledIcon, |
|||
CheckCircleFilledIcon, |
|||
CloseCircleFilledIcon, |
|||
} from 'tdesign-icons-vue-next' |
|||
function copyToClipboard(text) { |
|||
if (navigator.clipboard) { |
|||
navigator.clipboard.writeText(text) |
|||
} else { |
|||
const textarea = document.createElement('textarea') |
|||
document.body.appendChild(textarea) |
|||
textarea.style.position = 'fixed' |
|||
textarea.style.clip = 'rect(0 0 0 0)' |
|||
textarea.style.top = '10px' |
|||
textarea.value = text |
|||
textarea.select() |
|||
document.execCommand('copy', true) |
|||
document.body.removeChild(textarea) |
|||
} |
|||
MessagePlugin.success('文本复制成功') |
|||
} |
|||
|
|||
const data = [] |
|||
const total = 5 |
|||
for (let i = 0; i < total; i++) { |
|||
data.push({ |
|||
id: i + 1, |
|||
applicant: ['贾明(kyrieJia)', '张三(threeZhang)', '王芳(fangWang)'][ |
|||
i % 3 |
|||
], |
|||
status: i % 3, |
|||
channel: ['电子签署', '纸质签署', '纸质签署'][i % 3], |
|||
desc: ['单元格文本超出省略设置', '这是普通文本的超出省略'][i % 2], |
|||
link: '点击查看审批详情', |
|||
something: '仅标题省略', |
|||
// 透传 Tooltip Props 到浮层组件 |
|||
ellipsisProps: [ |
|||
'w.cezkdudy@lhll.au', |
|||
'r.nmgw@peurezgn.sl', |
|||
'p.cumx@rampblpa.ru', |
|||
][i % 3], |
|||
// 完全自定义超出省略的 Tips 内容 |
|||
ellipsisContent: [ |
|||
'宣传物料制作费用', |
|||
'algolia 服务报销', |
|||
'相关周边制作费', |
|||
'激励奖品快递费', |
|||
][i % 4], |
|||
propsAndContent1: [ |
|||
'2021-11-01', |
|||
'2021-12-01', |
|||
'2022-01-01', |
|||
'2022-02-01', |
|||
'2022-03-01', |
|||
][i % 4], |
|||
propsAndContent2: [2, 3, 1, 4][i % 4], |
|||
}) |
|||
} |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
data, |
|||
columns: [ |
|||
{ |
|||
colKey: 'applicant', |
|||
title: '申请人', |
|||
ellipsis: true, |
|||
}, |
|||
{ |
|||
colKey: 'status', |
|||
title: '审批状态', |
|||
width: 120, |
|||
cell: (h, { row }) => { |
|||
const statusNameListMap = { |
|||
0: { |
|||
label: '审批通过', |
|||
theme: 'success', |
|||
icon: <CheckCircleFilledIcon />, |
|||
}, |
|||
1: { |
|||
label: '审批失败', |
|||
theme: 'danger', |
|||
icon: <CloseCircleFilledIcon />, |
|||
}, |
|||
2: { |
|||
label: '审批过期', |
|||
theme: 'warning', |
|||
icon: <ErrorCircleFilledIcon />, |
|||
}, |
|||
} |
|||
return ( |
|||
<t-tag |
|||
shape="round" |
|||
theme={statusNameListMap[row.status].theme} |
|||
variant="light-outline" |
|||
> |
|||
{statusNameListMap[row.status].icon} |
|||
{statusNameListMap[row.status].label} |
|||
</t-tag> |
|||
) |
|||
}, |
|||
}, |
|||
{ |
|||
title: '签署方式(超长标题示例)', |
|||
colKey: 'channel', |
|||
width: 120, |
|||
ellipsisTitle: true, |
|||
}, |
|||
{ |
|||
title: '邮箱地址', |
|||
colKey: 'ellipsisProps', |
|||
// 浮层浅色背景,方向默认朝下出现 |
|||
ellipsis: { |
|||
theme: 'light', |
|||
placement: 'bottom', |
|||
}, |
|||
}, |
|||
{ |
|||
title: '申请事项', |
|||
colKey: 'ellipsisContent', |
|||
// ellipsis 定义超出省略的浮层内容,cell 定义单元格内容 |
|||
ellipsis: (h, { row }) => ( |
|||
<div> |
|||
{row.ellipsisContent} |
|||
<FileCopyIcon |
|||
style={{ cursor: 'pointer', marginLeft: '4px' }} |
|||
onClick={() => copyToClipboard(row.ellipsisContent)} |
|||
/> |
|||
</div> |
|||
), |
|||
}, |
|||
{ |
|||
title: '审核时间', |
|||
colKey: 'propsAndContent1', |
|||
// 支持同时设置 tooltipProps 和 浮层内容, |
|||
width: 100, |
|||
ellipsis: { |
|||
props: { |
|||
theme: 'light', |
|||
placement: 'bottom-right', |
|||
}, |
|||
content: (h, { row }) => ( |
|||
<div> |
|||
<p> |
|||
<b>创建日期:</b> {row.propsAndContent1} |
|||
</p> |
|||
<p> |
|||
<b>审核时长(天):</b> {row.propsAndContent2} |
|||
</p> |
|||
</div> |
|||
), |
|||
}, |
|||
}, |
|||
{ |
|||
title: '操作', |
|||
colKey: 'link', |
|||
// 超出省略的内容显示纯文本,不带任何样式和元素 |
|||
ellipsis: (h, { row }) => row.link, |
|||
// 注意这种 JSX 写法需设置 <script lang="jsx" setup> |
|||
cell: (h, { row }) => ( |
|||
<a href="/vue-next/components/table" target="_blank"> |
|||
{row.link} |
|||
</a> |
|||
), |
|||
}, |
|||
], |
|||
} |
|||
}, |
|||
|
|||
// methods: { |
|||
// getAttach() { |
|||
// return document.body; |
|||
// }, |
|||
// }, |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.user_component { |
|||
.page { |
|||
margin-top: 30px; |
|||
} |
|||
} |
|||
</style> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue