Compare commits
16 Commits
Author | SHA1 | Date |
---|---|---|
|
6a658bc18d | 3 months ago |
|
8899a13906 | 3 months ago |
|
f05f1bf448 | 3 months ago |
|
8ee6180906 | 3 months ago |
|
884c890b08 | 3 months ago |
|
84e0330d7a | 3 months ago |
|
48961be22b | 3 months ago |
|
4dff64e8b1 | 3 months ago |
|
5744b428a1 | 3 months ago |
|
491cf1edc3 | 3 months ago |
|
edf3b3d8ef | 3 months ago |
|
6155de708a | 3 months ago |
|
eebbef6e78 | 3 months ago |
|
d140297d4a | 3 months ago |
|
931aa577d3 | 3 months ago |
|
8f9f05b4ed | 3 months ago |
@ -0,0 +1,21 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"courseselected"
|
||||
]
|
||||
}
|
@ -0,0 +1,574 @@
|
||||
|
||||
|
||||
<Card
|
||||
><table ><tbody>
|
||||
|
||||
{ taolonglist.map((value,index)=>(
|
||||
<React.Fragment >
|
||||
<tr><td style={{width:"550px"}}>
|
||||
<React.Fragment >
|
||||
{value.lx==="wb"?<h4 style={{width:"550px"}}> {value.wb}</h4>:null}
|
||||
{value.lx==="pic"? <img
|
||||
src={!value.show?value.pic:value.xiugaipic}
|
||||
width="550px" height="auto"/> : null}
|
||||
{value.lx==="video"?<video src={!value.show? value.sp:value.xiugaisp} width="550px" height="auto" controls={true}></video>:null}
|
||||
{value.lx==="download"?<a href={value.url} style={{width:"550px"}} >{value.title}</a>:null}
|
||||
|
||||
</React.Fragment></td>
|
||||
|
||||
<td ><Button onClick={e=>{
|
||||
let temp=[...taolonglist]
|
||||
temp[index].show=!temp[index].show;
|
||||
settaolonglist(temp);
|
||||
}}>修改</Button><Popconfirm
|
||||
title="确认要删除此项吗"
|
||||
onConfirm={event => {
|
||||
let temp=[...taolonglist]
|
||||
temp.splice(index,1)
|
||||
settaolonglist(temp);
|
||||
}}
|
||||
onCancel={event => alert("no")}
|
||||
okText="确认"
|
||||
cancelText="不"
|
||||
>
|
||||
<Button onClick={e=>{
|
||||
|
||||
}} href="#">删除</Button>
|
||||
</Popconfirm>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
{value.show ?
|
||||
<tr>
|
||||
<td colSpan={3}>
|
||||
<React.Fragment>
|
||||
<h3>编辑</h3>
|
||||
<Tabs activeKey={value.leixing} onChange={e => {
|
||||
let temp = [...taolonglist]
|
||||
temp[index].leixing = e;
|
||||
settaolonglist(temp);
|
||||
}} tabBarStyle={{}} style={{width:"720px"}}>
|
||||
<Tabs.TabPane tab="视频" key="video">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<video src={value.xiugaisp} width="600px"
|
||||
height="auto"
|
||||
style={{display: "none"}}/>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
视频路径
|
||||
<Input value={value.xiugailujing}
|
||||
onChange={event => {
|
||||
let temp = [...taolonglist];
|
||||
temp[index].xiugailujing = event.target.value;
|
||||
settaolonglist(temp);
|
||||
|
||||
}} width="550px"
|
||||
style={{width:"550px"}}
|
||||
></Input>
|
||||
</td>
|
||||
|
||||
<td><Button onClick={e => {
|
||||
let temp = [...taolonglist];
|
||||
temp[index].xiugaisp = temp[index].xiugailujing;
|
||||
|
||||
settaolonglist(temp);
|
||||
}}>打开</Button></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Upload
|
||||
name='file'
|
||||
action={HOUDUAN+'api/uploadtm'}
|
||||
headers={{
|
||||
th: value.uuid,
|
||||
xx: fujianuuid,
|
||||
lx: "kaoshi"
|
||||
}}
|
||||
onChange={
|
||||
(info) => {
|
||||
if (info.file.status !== 'uploading') {
|
||||
console.log(info.file, info.fileList);
|
||||
}
|
||||
if (info.file.status === 'done') {
|
||||
//setTms(uuid.v4())
|
||||
message.success(`${info.file.name} file uploaded successfully`);
|
||||
|
||||
_.delay(() => {
|
||||
console.log('Done after 1 second');
|
||||
const temp = [...taolonglist];
|
||||
temp[index].xiugaisp = ZHIYUE+ value.uuid + "/" + fujianuuid + path.extname(info.file.name);
|
||||
settaolonglist(temp);
|
||||
setFujianuuid(uuid.v4())
|
||||
//settaolonglist(uuid.v4())
|
||||
}, 200);
|
||||
} else if (info.file.status === 'error') {
|
||||
message.error(`${info.file.name} file upload failed.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
showUploadList={false}><Button>
|
||||
<Icon type="upload"/>上传附件
|
||||
|
||||
</Button>
|
||||
</Upload>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Button onClick={e => {
|
||||
let temp = [...taolonglist];
|
||||
temp[index].sp = temp[index].xiugaisp;
|
||||
temp[index].lx = temp[index].leixing
|
||||
settaolonglist(temp);
|
||||
}}>确认</Button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="图片" key="pic">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<img src={value.xiugaipic} width="600px"
|
||||
height="auto"
|
||||
style={{display: "none"}}/>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span>图片路径
|
||||
|
||||
<Input value={value.xiugailujing} onChange={event => {
|
||||
let temp = [...taolonglist];
|
||||
temp[index].xiugailujing = event.target.value;
|
||||
settaolonglist(temp);
|
||||
}}
|
||||
width="550px"
|
||||
style={{width:"550px"}}
|
||||
></Input></span>
|
||||
</td>
|
||||
|
||||
<td><Button onClick={e => {
|
||||
let temp = [...taolonglist];
|
||||
temp[index].xiugaipic = temp[index].xiugailujing;
|
||||
settaolonglist(temp);
|
||||
//settaolonglist(uuid.v4())
|
||||
}}>打开</Button></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Upload
|
||||
name='file'
|
||||
action={HOUDUAN+'api/uploadtm'}
|
||||
headers={{
|
||||
th: value.uuid,
|
||||
xx: fujianuuid,
|
||||
lx: "kaoshi"
|
||||
}}
|
||||
onChange={
|
||||
(info) => {
|
||||
if (info.file.status !== 'uploading') {
|
||||
console.log(info.file, info.fileList);
|
||||
}
|
||||
if (info.file.status === 'done') {
|
||||
//setTms(uuid.v4())
|
||||
message.success(`${info.file.name} file uploaded successfully`);
|
||||
|
||||
_.delay(() => {
|
||||
console.log('Done after 1 second');
|
||||
const temp = [...taolonglist];
|
||||
temp[index].xiugaipic = ZHIYUE+value.uuid + "/" + fujianuuid + path.extname(info.file.name);
|
||||
settaolonglist(temp);
|
||||
setFujianuuid(uuid.v4());
|
||||
|
||||
}, 200);
|
||||
} else if (info.file.status === 'error') {
|
||||
message.error(`${info.file.name} file upload failed.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
showUploadList={false}><Button>
|
||||
<Icon type="upload"/>上传附件
|
||||
|
||||
</Button>
|
||||
</Upload>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><Button onClick={e => {
|
||||
let temp = [...taolonglist];
|
||||
temp[index].pic = temp[index].xiugaipic;
|
||||
temp[index].lx = temp[index].leixing
|
||||
settaolonglist(temp);
|
||||
}}>保存</Button></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="附件" key="download">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>文件标题</td>
|
||||
<td style={{width: "400px"}}>
|
||||
<Input value={value.xiugai} onChange={e => {
|
||||
let temp = [...taolonglist];
|
||||
temp[index].xiugai = e.target.value;
|
||||
settaolonglist(temp);
|
||||
}}
|
||||
width="550px"
|
||||
style={{width:"550px"}}
|
||||
></Input>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
文件路径
|
||||
</td>
|
||||
<td>
|
||||
<Input value={value.xiugaiwj}
|
||||
onChange={event => {
|
||||
let temp = [...taolonglist];
|
||||
temp[index].xiugaiwj = event.target.value;
|
||||
temp[index].lx = temp[index].leixing
|
||||
settaolonglist(temp);
|
||||
|
||||
}}
|
||||
width="550px"
|
||||
style={{width:"550px"}}
|
||||
></Input></td>
|
||||
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Upload
|
||||
name='file'
|
||||
action={HOUDUAN+'api/uploadtm'}
|
||||
headers={{
|
||||
th: value.uuid,
|
||||
xx: fujianuuid,
|
||||
lx: "kaoshi"
|
||||
}}
|
||||
onChange={
|
||||
(info) => {
|
||||
if (info.file.status !== 'uploading') {
|
||||
console.log(info.file, info.fileList);
|
||||
}
|
||||
if (info.file.status === 'done') {
|
||||
//setTms(uuid.v4())
|
||||
message.success(`${info.file.name} file uploaded successfully`);
|
||||
|
||||
_.delay(() => {
|
||||
console.log('Done after 1 second');
|
||||
const temp = [...taolonglist];
|
||||
temp[index].xiugaiwj = ZHIYUE+value.uuid + "/" + fujianuuid + path.extname(info.file.name);
|
||||
temp[index].xiugai = info.file.name;
|
||||
settaolonglist(temp);
|
||||
setFujianuuid(uuid.v4())
|
||||
}, 200);
|
||||
} else if (info.file.status === 'error') {
|
||||
message.error(`${info.file.name} file upload failed.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
showUploadList={false}><Button>
|
||||
<Icon type="upload"/>上传附件
|
||||
|
||||
</Button>
|
||||
</Upload>
|
||||
<Button onClick={e => {
|
||||
let temp = [...taolonglist];
|
||||
temp[index].url = temp[index].xiugaiwj;
|
||||
temp[index].title = temp[index].xiugai;
|
||||
temp[index].lx = temp[index].leixing
|
||||
settaolonglist(temp);
|
||||
}}>保存</Button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="文字" key="wb">
|
||||
|
||||
<Input.TextArea value={value.xiugaiwb}
|
||||
onChange={event => {
|
||||
let temp = [...taolonglist];
|
||||
temp[index].xiugaiwb = event.target.value;
|
||||
temp[index].lx = temp[index].leixing
|
||||
settaolonglist(temp);
|
||||
}} width="550px"
|
||||
style={{width:"550px"}}
|
||||
></Input.TextArea>
|
||||
<Button onClick={e => {
|
||||
let temp = [...taolonglist]
|
||||
temp[index].wb = temp[index].xiugaiwb;
|
||||
settaolonglist(temp);
|
||||
}}>修改</Button>
|
||||
</Tabs.TabPane>
|
||||
</Tabs>
|
||||
</React.Fragment>
|
||||
</td>
|
||||
</tr>
|
||||
:null}
|
||||
|
||||
</React.Fragment>
|
||||
))}
|
||||
|
||||
</tbody></table></Card>
|
||||
<Card>
|
||||
<Tabs activeKey={add.leixing} onChange={e=>{
|
||||
let temp={...add};
|
||||
|
||||
temp.leixing=e;
|
||||
|
||||
setAdd(temp)
|
||||
}}>
|
||||
<Tabs.TabPane tab="视频" key="video">
|
||||
<table><tbody>
|
||||
<tr ><td >
|
||||
<video src={add.xiugaisp} width="600px" height="auto" controls={true}/>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr><td>
|
||||
<Upload
|
||||
name='file'
|
||||
action={HOUDUAN+'api/uploadtm'}
|
||||
headers={{
|
||||
th: add.uuid ,
|
||||
xx: fujianuuid,
|
||||
lx: "kaoshi"
|
||||
}}
|
||||
onChange={
|
||||
(info) => {
|
||||
if (info.file.status !== 'uploading') {
|
||||
console.log(info.file, info.fileList);
|
||||
}
|
||||
if (info.file.status === 'done') {
|
||||
//setTms(uuid.v4())
|
||||
message.success(`${info.file.name} file uploaded successfully`);
|
||||
|
||||
_.delay(() => {
|
||||
console.log('Done after 1 second');
|
||||
const temp={...add};
|
||||
temp.xiugaisp=ZHIYUE+add.uuid+"/"+fujianuuid + path.extname(info.file.name);
|
||||
setAdd(temp);
|
||||
setFujianuuid(uuid.v4())
|
||||
}, 200);
|
||||
} else if (info.file.status === 'error') {
|
||||
message.error(`${info.file.name} file upload failed.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
showUploadList={false}><Button>
|
||||
<Icon type="upload"/>上传附件
|
||||
|
||||
</Button>
|
||||
</Upload>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td>文件路径
|
||||
<Input value={add.url} width="400px" onChange={event => {
|
||||
let temp={...add};
|
||||
temp.url=event.target.value;
|
||||
setAdd(temp);
|
||||
}}></Input>
|
||||
<Button onClick={e=>{
|
||||
let temp={...add};
|
||||
temp.xiugaisp=temp.url;
|
||||
setAdd(temp);
|
||||
}
|
||||
}>应用</Button>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="图片" key="pic">
|
||||
<tr>
|
||||
<td>
|
||||
<img src={add.xiugaipic} width="600px" height="auto"/>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<Upload
|
||||
name='file'
|
||||
action={HOUDUAN+'api/uploadtm'}
|
||||
headers={{
|
||||
th: add.uuid,
|
||||
xx: fujianuuid,
|
||||
lx: "kaoshi"
|
||||
}}
|
||||
onChange={
|
||||
(info) => {
|
||||
if (info.file.status !== 'uploading') {
|
||||
console.log(info.file, info.fileList);
|
||||
}
|
||||
if (info.file.status === 'done') {
|
||||
//setTms(uuid.v4())
|
||||
message.success(`${info.file.name} file uploaded successfully`);
|
||||
|
||||
_.delay(() => {
|
||||
console.log('Done after 1 second');
|
||||
const temp = {...add};
|
||||
temp.xiugaipic =ZHIYUE+ add.uuid + "/" + fujianuuid + path.extname(info.file.name);
|
||||
setAdd(temp);
|
||||
setFujianuuid(uuid.v4())
|
||||
}, 200);
|
||||
} else if (info.file.status === 'error') {
|
||||
message.error(`${info.file.name} file upload failed.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
showUploadList={false}><Button>
|
||||
<Icon type="upload"/>上传附件
|
||||
|
||||
</Button>
|
||||
</Upload>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>文件路径
|
||||
<Input value={add.url} width="400px" onChange={event => {
|
||||
let temp = {...add};
|
||||
temp.url = event.target.value;
|
||||
setAdd(temp);
|
||||
}}></Input>
|
||||
<Button onClick={e => {
|
||||
let temp = {...add};
|
||||
temp.xiugaipic = temp.url;
|
||||
setAdd(temp);
|
||||
}
|
||||
}>应用</Button>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="附件" key="download">
|
||||
<tr>
|
||||
<td><a href={add.xiugailujing}>{add.xiugai}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>文件标题</td>
|
||||
<td >
|
||||
<Input value={add.xiugai} onChange={event => {
|
||||
let temp={...add}
|
||||
temp.xiugai=event.target.value;
|
||||
setAdd(temp);
|
||||
}}></Input>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
<tr>
|
||||
<td>文件路径</td>
|
||||
<td style={{width:"350px"}}>
|
||||
<Input value={add.xiugailujing} onChange={event => {
|
||||
let temp={...add};
|
||||
temp.xiugailujing=event.target.value;
|
||||
setAdd(temp);
|
||||
}}></Input></td>
|
||||
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Upload
|
||||
name='file'
|
||||
action={HOUDUAN+'api/uploadtm'}
|
||||
headers={{
|
||||
th: add.uuid ,
|
||||
xx: fujianuuid,
|
||||
lx: "kaoshi"
|
||||
}}
|
||||
onChange={
|
||||
(info) => {
|
||||
if (info.file.status !== 'uploading') {
|
||||
console.log(info.file, info.fileList);
|
||||
}
|
||||
if (info.file.status === 'done') {
|
||||
//setTms(uuid.v4())
|
||||
message.success(`${info.file.name} file uploaded successfully`);
|
||||
|
||||
_.delay(() => {
|
||||
|
||||
console.log('Done after 1 second');
|
||||
const temp = {...add};
|
||||
temp.xiugai=info.file.name;
|
||||
temp.xiugailujing = ZHIYUE+ add.uuid + "/" + fujianuuid + path.extname(info.file.name)
|
||||
setAdd(temp)
|
||||
setFujianuuid(uuid.v4());
|
||||
|
||||
}, 200);
|
||||
} else if (info.file.status === 'error') {
|
||||
message.error(`${info.file.name} file upload failed.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
showUploadList={false}><Button>
|
||||
<Icon type="upload"/>上传附件
|
||||
|
||||
</Button>
|
||||
</Upload>
|
||||
</td></tr>
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="文字" key="wb">
|
||||
<Input.TextArea value={add.xiugaiwb} onChange={event => {
|
||||
let temp={...add};
|
||||
temp.xiugaiwb=event.target.value;
|
||||
setAdd(temp);
|
||||
}} style={{height:"250px"}}></Input.TextArea>
|
||||
</Tabs.TabPane>
|
||||
|
||||
</Tabs>
|
||||
<Button onClick={
|
||||
// {value.lx==="wb"?<h4>{value.wb}</h4>:null}
|
||||
// {value.lx==="pic"? <img
|
||||
// src={value.pic}
|
||||
// width="600px" height="auto"/> : null}
|
||||
// {value.lx==="video"?<video src={value.sp} width="600px" height="auto" controls={true}></video>:null}
|
||||
// {value.lx==="download"?<a href={value.url}>{value.title}</a>:null}
|
||||
e=>{
|
||||
const xiang={
|
||||
lx:add.leixing,
|
||||
leixing:add.leixing,
|
||||
wb:add.xiugaiwb,
|
||||
xiugaiwb:add.xiugaiwb,
|
||||
pic:add.xiugaipic,
|
||||
xiugaiwj:add.xiugailujing,//修改附件路径
|
||||
xiugaipic:add.xiugaipic,
|
||||
sp:add.xiugaisp,
|
||||
xiugaisp:add.xiugaisp,
|
||||
|
||||
xiugailujing:add.xiugailujing,
|
||||
url:add.xiugailujing,
|
||||
xiugai:add.xiugai,
|
||||
title:add.xiugai,
|
||||
show:false
|
||||
|
||||
}
|
||||
let temp=[...taolonglist]
|
||||
temp.push(xiang);
|
||||
settaolonglist(temp);
|
||||
const addtemp={leixing:add.leixing,uuid:uuid.v4()}
|
||||
setAdd(addtemp);
|
||||
}
|
||||
}>
|
||||
添加
|
||||
</Button>
|
||||
</Card>
|
@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<script>
|
||||
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
||||
CSS.supports('top: constant(a)'))
|
||||
document.write(
|
||||
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
||||
</script>
|
||||
<title></title>
|
||||
<!--preload-links-->
|
||||
<!--app-context-->
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"><!--app-html--></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,80 @@
|
||||
{
|
||||
"name": "uni-preset-vue",
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"dev:custom": "uni -p",
|
||||
"dev:h5": "uni",
|
||||
"dev:h5:ssr": "uni --ssr",
|
||||
"dev:mp-alipay": "uni -p mp-alipay",
|
||||
"dev:mp-baidu": "uni -p mp-baidu",
|
||||
"dev:mp-jd": "uni -p mp-jd",
|
||||
"dev:mp-kuaishou": "uni -p mp-kuaishou",
|
||||
"dev:mp-lark": "uni -p mp-lark",
|
||||
"dev:mp-qq": "uni -p mp-qq",
|
||||
"dev:mp-toutiao": "uni -p mp-toutiao",
|
||||
"dev:mp-weixin": "uni -p mp-weixin",
|
||||
"dev:mp-xhs": "uni -p mp-xhs",
|
||||
"dev:quickapp-webview": "uni -p quickapp-webview",
|
||||
"dev:quickapp-webview-huawei": "uni -p quickapp-webview-huawei",
|
||||
"dev:quickapp-webview-union": "uni -p quickapp-webview-union",
|
||||
"build:custom": "uni build -p",
|
||||
"build:h5": "uni build",
|
||||
"build:h5:ssr": "uni build --ssr",
|
||||
"build:mp-alipay": "uni build -p mp-alipay",
|
||||
"build:mp-baidu": "uni build -p mp-baidu",
|
||||
"build:mp-jd": "uni build -p mp-jd",
|
||||
"build:mp-kuaishou": "uni build -p mp-kuaishou",
|
||||
"build:mp-lark": "uni build -p mp-lark",
|
||||
"build:mp-qq": "uni build -p mp-qq",
|
||||
"build:mp-toutiao": "uni build -p mp-toutiao",
|
||||
"build:mp-weixin": "uni build -p mp-weixin",
|
||||
"build:mp-xhs": "uni build -p mp-xhs",
|
||||
"build:quickapp-webview": "uni build -p quickapp-webview",
|
||||
"build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei",
|
||||
"build:quickapp-webview-union": "uni build -p quickapp-webview-union",
|
||||
"type-check": "vue-tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@dcloudio/uni-app": "3.0.0-4030620241128001",
|
||||
"@dcloudio/uni-app-harmony": "3.0.0-4030620241128001",
|
||||
"@dcloudio/uni-app-plus": "3.0.0-4030620241128001",
|
||||
"@dcloudio/uni-components": "3.0.0-4030620241128001",
|
||||
"@dcloudio/uni-h5": "3.0.0-4030620241128001",
|
||||
"@dcloudio/uni-mp-alipay": "3.0.0-4030620241128001",
|
||||
"@dcloudio/uni-mp-baidu": "3.0.0-4030620241128001",
|
||||
"@dcloudio/uni-mp-jd": "3.0.0-4030620241128001",
|
||||
"@dcloudio/uni-mp-kuaishou": "3.0.0-4030620241128001",
|
||||
"@dcloudio/uni-mp-lark": "3.0.0-4030620241128001",
|
||||
"@dcloudio/uni-mp-qq": "3.0.0-4030620241128001",
|
||||
"@dcloudio/uni-mp-toutiao": "3.0.0-4030620241128001",
|
||||
"@dcloudio/uni-mp-weixin": "3.0.0-4030620241128001",
|
||||
"@dcloudio/uni-mp-xhs": "3.0.0-4030620241128001",
|
||||
"@dcloudio/uni-quickapp-webview": "3.0.0-4030620241128001",
|
||||
"@dcloudio/uni-ui": "^1.5.7",
|
||||
"@hyoga/uni-socket.io": "^3.0.4",
|
||||
"axios": "^1.9.0",
|
||||
"axios-adapter-uniapp": "^0.1.4",
|
||||
"dayjs": "^1.11.13",
|
||||
"moment": "^2.30.1",
|
||||
"pinia": "^3.0.2",
|
||||
"uuid": "^11.1.0",
|
||||
"vue": "^3.4.21",
|
||||
"vue-i18n": "^9.1.9",
|
||||
"vue-router": "^4.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@dcloudio/types": "^3.4.8",
|
||||
"@dcloudio/uni-automator": "3.0.0-4030620241128001",
|
||||
"@dcloudio/uni-cli-shared": "3.0.0-4030620241128001",
|
||||
"@dcloudio/uni-stacktracey": "3.0.0-4030620241128001",
|
||||
"@dcloudio/vite-plugin-uni": "3.0.0-4030620241128001",
|
||||
"@vue/runtime-core": "^3.4.21",
|
||||
"@vue/tsconfig": "^0.1.3",
|
||||
"rollup-plugin-visualizer": "^6.0.1",
|
||||
"sass": "^1.69.0",
|
||||
"sass-loader": "^10.1.1",
|
||||
"typescript": "^4.9.4",
|
||||
"vite": "5.2.8",
|
||||
"vue-tsc": "^1.0.24"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"pages": [
|
||||
// ... existing code ...
|
||||
|
||||
// ... existing code ...
|
||||
]
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
import fs from "fs";
|
||||
import child_process from "node:child_process";
|
||||
|
||||
app.post("/apistu/pppta",async (req,res)=>{
|
||||
const sqlread="SELECT * FROM tmj_ex WHERE id=?"
|
||||
const resultptainfor=await new Promise((resolve, reject) => {
|
||||
connection.query(sqlread,[req.body.uuid],(error,results,fields)=>{
|
||||
resolve(results[0]);
|
||||
})
|
||||
})
|
||||
let information=JSON.parse(resultptainfor.tmlist)[parseInt(req.body.th)]
|
||||
res.send(JSON.parse(information.information))
|
||||
let tmlist=JSON.parse(information.information).testprint
|
||||
let uuid1=uuidv4.v4()
|
||||
let worktemp="C:\\Users\\l\\Music\\reat\\src\\MarkdownEditor\\test\\"+uuid1
|
||||
fs.mkdirSync(worktemp)
|
||||
if(req.body.pl==="java") {
|
||||
fs.writeFileSync(worktemp + "\\Main.java", req.body.code)
|
||||
|
||||
fs.writeFileSync(worktemp + "\\inputby.txt", "work")
|
||||
tmlist.map((tmone, index) => {
|
||||
fs.writeFileSync(worktemp + "\\input" + (index + 1) + ".txt", tmone)
|
||||
})
|
||||
child_process.execFileSync(`python`, ["C:\\Users\\l\\PycharmProjects\\PythonProject7\\py2.py", worktemp, "java", 1])
|
||||
let json_wb = fs.readFileSync(worktemp + "\\zt.json").toString()
|
||||
let json_zt = JSON.parse(json_wb)
|
||||
let zt_1 = [...json_zt.test]
|
||||
if (json_zt.by === 0) {
|
||||
let work_result = [...tmlist]
|
||||
tmlist.map((tmresult, indexresult) => {
|
||||
zt_1[index].by = 0
|
||||
zt_1[index].sc = fs.readFileSync(worktemp + "\\output1.txt", {encoding: "utf8"})
|
||||
zt_1[index].err = fs.readFileSync(worktemp + "\\err1.txt", {encoding: "utf8"})
|
||||
zt_1[index] = {...zt_1[index], ...tmresult}
|
||||
})
|
||||
//zt_1.by=0
|
||||
//zt_1.sc=fs.readFileSync(worktemp+"\\output1.txt",{encoding:"utf8"})
|
||||
//zt_1.err=fs.readFileSync(worktemp+"\\err1.txt",{encoding:"utf8"})
|
||||
}else {
|
||||
let by_err={}
|
||||
by_err.by=json_zt.by
|
||||
by_err.err=fs.readFileSync(worktemp+"\\err_by.txt",{encoding:"utf8"})
|
||||
}
|
||||
|
||||
}
|
||||
})
|
@ -0,0 +1 @@
|
||||
[{"lx":"单选题","uuid":"e6d957c8-7d7b-4df1-999f-7959e776317a","xuexiang":[{"lx":"wb","wb":"选项A 正确","pic":"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2Fddd83bc0-4c41-482a-8888-083d09096ae9%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1739691239&t=f2f6f3c92693182304a737e6faf0e97d"},{"lx":"wb","wb":"选项B","pic":"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2Fddd83bc0-4c41-482a-8888-083d09096ae9%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1739691239&t=f2f6f3c92693182304a737e6faf0e97d"}],"tm":{"lx":"pic","pic":"http://localhost:89/e6d957c8-7d7b-4df1-999f-7959e776317a/askforteakcb.png","wb":"test"},"daan":"A"},{"lx":"多选题","uuid":"9bc5fe7b-9d41-42ff-8e3d-a37154e2fad1","xuexiang":[{"lx":"wb","wb":"选项A 正确","pic":"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2Fddd83bc0-4c41-482a-8888-083d09096ae9%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1739691239&t=f2f6f3c92693182304a737e6faf0e97d"},{"lx":"wb","wb":"选项B 正确","pic":"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2Fddd83bc0-4c41-482a-8888-083d09096ae9%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1739691239&t=f2f6f3c92693182304a737e6faf0e97d"},{"lx":"wb","wb":"选项C","pic":"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2Fddd83bc0-4c41-482a-8888-083d09096ae9%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1739691239&t=f2f6f3c92693182304a737e6faf0e97d"}],"tm":{"lx":"pic","pic":"http://localhost:89/9bc5fe7b-9d41-42ff-8e3d-a37154e2fad1/askforteakcb.png","wb":""},"daan":["A","B"]},{"lx":"填空题","uuid":"1b100b1b-ebaa-469c-bd2d-3227760cb32f","xuexiang":[],"tm":{"lx":"wb","pic":"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2Fddd83bc0-4c41-482a-8888-083d09096ae9%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1739691239&t=f2f6f3c92693182304a737e6faf0e97d","wb":"填空题 答案为TEST"},"sr":"TEST"},{"lx":"填空题","uuid":"91e4ffa9-21e2-47f0-9480-6c0d6ffc41dc","xuexiang":[],"tm":{"lx":"wb","pic":"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2Fddd83bc0-4c41-482a-8888-083d09096ae9%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1739691239&t=f2f6f3c92693182304a737e6faf0e97d","wb":"填空题 由老师判"},"sr":"pick up me 满分"},{"lx":"简答题","uuid":"8f577885-a8a4-43cf-94d4-b3a50828275a","xuexiang":[],"tm":{"lx":"wb","pic":"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2Fddd83bc0-4c41-482a-8888-083d09096ae9%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1739691239&t=f2f6f3c92693182304a737e6faf0e97d","wb":"简答题 老师判"},"filelist":[{"url":"8f577885-a8a4-43cf-94d4-b3a50828275a202413501062/0ab5b8c5-1cdb-4531-b178-cc6ba74737e1.png","file":"a8.png"}]}]
|
@ -0,0 +1,124 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const uuidv4 = require('uuid');
|
||||
var q = require('qiao-zip');
|
||||
const os = require("os");
|
||||
/*
|
||||
name:biao[j][nameid],
|
||||
xuehao:biao[j][xuehaoid],
|
||||
sex:biao[j][sex],
|
||||
classid:biao[j][classid],
|
||||
xueyuan:biao[j][xueyaunid],
|
||||
idcard:biao[j][idcardid],
|
||||
ruxuetime:ruxue,
|
||||
iphone:biao[j][iphone],
|
||||
parentphone:biao[j][parentphone],
|
||||
parentname:biao[j][parentname],
|
||||
*/
|
||||
function nametop(){
|
||||
|
||||
}
|
||||
async function makeExcel(exceljson) {
|
||||
|
||||
let wblist=[]//excel文本列表
|
||||
wblist.push("姓名");
|
||||
wblist.push("学号")
|
||||
wblist.push("性别")
|
||||
wblist.push("专业");
|
||||
wblist.push("学院")
|
||||
wblist.push("身份证号")
|
||||
wblist.push("入学时间")
|
||||
wblist.push("手机号")
|
||||
wblist.push("默认密码")
|
||||
let listexcel=""
|
||||
//console.log(exceljson);
|
||||
exceljson.map((value,index) => {
|
||||
let nameindex = wblist.indexOf(value.name);
|
||||
|
||||
if (nameindex == -1) {
|
||||
wblist.push(value.name);
|
||||
nameindex = wblist.indexOf(value.name);
|
||||
}
|
||||
let namexml = `<c r="A${index + 2}" t="s"><v>${nameindex}</v></c> `;
|
||||
let xuehaoindex
|
||||
= wblist.indexOf(value.xuehao);
|
||||
if (xuehaoindex === -1) {
|
||||
wblist.push(value.xuehao);
|
||||
xuehaoindex = wblist.indexOf(value.xuehao);
|
||||
}
|
||||
let xuehaoxml = `<c r="B${index + 2}" t="s"><v>${xuehaoindex}</v></c> `
|
||||
let sexindex = wblist.indexOf(value.sex);
|
||||
if (sexindex === -1) {
|
||||
wblist.push(value.sex)
|
||||
sexindex = wblist.indexOf(value.sex)
|
||||
}
|
||||
let sexxml = `<c r="C${index + 2}" t="s"><v>${sexindex}</v></c>`
|
||||
let classindex = wblist.indexOf(value.classid);
|
||||
if (classindex === -1) {
|
||||
wblist.push(value.classid);
|
||||
classindex = wblist.indexOf(value.classid);
|
||||
}
|
||||
let classxml = `<c r="D${index + 2}" t="s"><v>${classindex}</v></c>`
|
||||
let xueyuanindex = wblist.indexOf(value.xueyuan);
|
||||
if (xueyuanindex === -1) {
|
||||
wblist.push(value.xueyuan);
|
||||
xueyuanindex = wblist.indexOf(value.xueyuan);
|
||||
}
|
||||
let xueyuanxml = `<c r="E${index + 2}" t="s"><v>${xueyuanindex}</v></c>`
|
||||
let idcardindex = wblist.indexOf(value.idcard);
|
||||
if (idcardindex === -1) {
|
||||
wblist.push(value.idcard);
|
||||
idcardindex = wblist.indexOf(value.idcard);
|
||||
}
|
||||
let idcardxml = `<c r="F${index + 2}" t="s"><v>${idcardindex}</v></c>`
|
||||
let ruxuetimeindex = wblist.indexOf(value.ruxuetime);
|
||||
if (ruxuetimeindex === -1) {
|
||||
wblist.push(value.ruxuetime);
|
||||
ruxuetimeindex = wblist.indexOf(value.ruxuetime);
|
||||
}
|
||||
let ruxuetimexml = `<c r="G${index + 2}" t="s"><v>${ruxuetimeindex}</v></c>`
|
||||
let iphoneindex = wblist.indexOf(value.iphone);
|
||||
if (iphoneindex === -1) {
|
||||
wblist.push(value.iphone);
|
||||
iphoneindex = wblist.indexOf(value.iphone);
|
||||
}
|
||||
let iphonexml = `<c r="H${index + 2}" t="s"><v>${iphoneindex}</v></c>`
|
||||
let passwordindex = wblist.indexOf(value.password);
|
||||
console.log(value.password)
|
||||
if (passwordindex === -1) {
|
||||
wblist.push(value.password);
|
||||
passwordindex = wblist.indexOf(value.password);
|
||||
}
|
||||
let passwordxml = `<c r="I${index + 2}" t="s"><v>${passwordindex}</v></c>`
|
||||
const xmlall=namexml+xuehaoxml+sexxml+classxml+xueyuanxml+idcardxml+ruxuetimexml+iphonexml+passwordxml;
|
||||
const row=`<row r = "${index+2}" spans = "1:9" >${xmlall}</row> `
|
||||
listexcel+=row;
|
||||
})
|
||||
let moban=fs.readFileSync("sheet2.xml","utf8")
|
||||
let shuzu= moban.split("shuliang");
|
||||
moban=shuzu[0]+`I${exceljson.length+1}`+shuzu[1];
|
||||
shuzu=moban.split("charuwengjian");
|
||||
moban=shuzu[0]+listexcel+shuzu[1];
|
||||
let stringlist="";
|
||||
wblist.map((value,index)=>{
|
||||
const wbxml=`<si><t>${value}</t></si>`
|
||||
stringlist+=wbxml;
|
||||
})
|
||||
let wbxml=fs.readFileSync("sharedStrings.xml","utf8")
|
||||
let wbshuzu=wbxml.split("wblist");
|
||||
wbxml=wbshuzu[0]+stringlist+wbshuzu[1];
|
||||
const cacheDir = path.join(os.homedir(), '.cache');
|
||||
const filedir=cacheDir+'\\learn\\'+uuidv4.v4();
|
||||
console.log(filedir)
|
||||
fs.mkdirSync(filedir);
|
||||
await q.unzip("scexcelstu.zip", filedir)
|
||||
fs.writeFileSync(`${filedir}\\xl\\sharedStrings.xml`,wbxml)
|
||||
fs.writeFileSync(`${filedir}\\xl\\worksheets\\sheet1.xml`,moban)
|
||||
const uuidv41=uuidv4.v4();
|
||||
const dir=`C:\\Users\\l\\WebstormProjects\\examp\\serve\\nginx\\html\\stuexcel\\${uuidv41}.zip`;
|
||||
|
||||
await q.zip(filedir, dir,false)
|
||||
fs.copyFileSync(dir,`C:\\Users\\l\\WebstormProjects\\examp\\serve\\nginx\\html\\stuexcel\\${uuidv41}.xlsx`)
|
||||
return(`http://localhost:89/stuexcel/${uuidv41}.xlsx`);
|
||||
}
|
||||
exports.makeExcel=makeExcel;
|
@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "serve",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@napi-rs/canvas": "^0.1.70",
|
||||
"archiver": "^7.0.1",
|
||||
"axios": "^1.7.9",
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.21.1",
|
||||
"http": "^0.0.1-security",
|
||||
"lz-string": "^1.5.0",
|
||||
"moment": "^2.30.1",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
"mysql": "^2.18.1",
|
||||
"node-xlsx": "^0.24.0",
|
||||
"nodemon": "^3.1.9",
|
||||
"pdfjs-dist": "^3.10.111",
|
||||
"qiao-zip": "^4.7.4",
|
||||
"qrcode": "^1.5.4",
|
||||
"socket.io": "^4.8.1",
|
||||
"speakeasy": "^2.0.0",
|
||||
"tar": "^7.4.3",
|
||||
"uuid": "^11.0.3",
|
||||
"xlsx": "^0.18.5",
|
||||
"xml2js": "^0.6.2"
|
||||
}
|
||||
}
|
@ -0,0 +1,140 @@
|
||||
async function panduanyuejuan(){
|
||||
const sqlstd="SELECT * FROM kaoshipaper WHERE uuid=?";
|
||||
const resultstd=await new Promise((resolve, reject) => {
|
||||
connection.query(sqlstd,[req.query.ksh],(error, results, fields) => {
|
||||
if(error)throw error;
|
||||
resolve(results[0]);
|
||||
})
|
||||
})
|
||||
if(JSON.parse(resultstd.xx).pan_jue_finsih===false) {
|
||||
const sql = "SELECT * FROM kaoshiend WHERE ks=?";
|
||||
const resultksdaan = await new Promise((resolve, reject) => {
|
||||
connection.query(sql, [parseInt(req.query.ksh)], (error, results, fields) => {
|
||||
if (error) throw error;
|
||||
resolve(results);
|
||||
})
|
||||
})
|
||||
|
||||
let finish = true;
|
||||
for (let i = 0; i < resultksdaan.length; i++) {
|
||||
const ksdaan = JSON.parse(resultksdaan[i].ksdaan);
|
||||
|
||||
ksdaan.map((value, index) => {
|
||||
if (value.lx === "填空题") {
|
||||
console.log(resultstd)
|
||||
const stddaan = JSON.parse(resultstd.std);
|
||||
if (stddaan[i].panjaun === "teacher") {
|
||||
if (value.teacherid === undefined) {
|
||||
finish = false
|
||||
}
|
||||
}
|
||||
}
|
||||
if (value.lx === "简答题") {
|
||||
if (value.teacherid === undefined) {
|
||||
finish = false
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
if(finish===true){
|
||||
let jsonxx=JSON.parse(resultstd.xx);
|
||||
jsonxx.pan_jue_finsih=true
|
||||
const sqlupdate = 'UPDATE kaoshipaper SET xx=? WHERE `uuid`=?';
|
||||
const up = await new Promise((resolve, reject) => {
|
||||
connection.query(sqlupdate, [JSON.stringify(jsonxx, null, 4), req.query.ksh], (error, results, fields) => {
|
||||
if (error) throw error;
|
||||
resolve(results);
|
||||
})
|
||||
})
|
||||
}
|
||||
let infor=[]
|
||||
let allprint=[]
|
||||
if(finish===true){
|
||||
|
||||
for (let i = 0; i < resultksdaan.length; i++) {
|
||||
const ksdaan = JSON.parse(resultksdaan[i].ksdaan);
|
||||
let num=0;
|
||||
let ksdaantemp=[...ksdaan]
|
||||
ksdaan.map((value, index) => {
|
||||
if (value.lx === "填空题") {
|
||||
console.log(resultstd)
|
||||
const stddaan = JSON.parse(resultstd.std);
|
||||
if (stddaan[index].panjaun === "teacher") {
|
||||
num=num+value.teacherprint
|
||||
ksdaantemp[index].way="teacher"
|
||||
ksdaantemp[index].printstu=value.teacherprint
|
||||
}else{
|
||||
if(value.sr.trimStart()===stddaan[index].std.trimStart()){
|
||||
num=num+stddaan[index].print
|
||||
ksdaantemp[index].way="computer"
|
||||
ksdaantemp[index].printstu=stddaan[index].print
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (value.lx === "简答题") {
|
||||
const stddaan = JSON.parse(resultstd.std);
|
||||
num=num+value.teacherprint
|
||||
//ksdaantemp[index].way="teacher"
|
||||
ksdaantemp[index].printstu=value.teacherprint
|
||||
}else if(value.lx==="多选题"){
|
||||
let zq=true
|
||||
const stddaan = JSON.parse(resultstd.std);
|
||||
value.daan.map((item,xuaho)=>{
|
||||
if(!stddaan[index].std.includes(item)){}
|
||||
zq=false
|
||||
})
|
||||
if(value.daan.length!==stddaan[index].std.length){
|
||||
zq=false
|
||||
}
|
||||
if(zq){
|
||||
num=num+stddaan[index].print
|
||||
//ksdaantemp[index].way="teacher"
|
||||
ksdaantemp[index].printstu=stddaan[index].print
|
||||
}else{
|
||||
ksdaantemp[index].printstu=0
|
||||
}
|
||||
|
||||
|
||||
}else if(value.lx==="单选题"){
|
||||
const stddaan = JSON.parse(resultstd.std);
|
||||
if(value.daan===stddaan[index].std){
|
||||
num=num+stddaan[index].print
|
||||
//ksdaantemp[index].way="teacher"
|
||||
ksdaantemp[index].printstu=stddaan[index].print
|
||||
}else{
|
||||
ksdaantemp[index].printstu=0
|
||||
num=num+0
|
||||
}
|
||||
}else if(value.lx==="判断题"){
|
||||
const stddaan = JSON.parse(resultstd.std);
|
||||
if(value.daan===stddaan[index].std){
|
||||
num=num+stddaan[index].print
|
||||
//ksdaantemp[index].way="teacher"
|
||||
ksdaantemp[index].printstu=stddaan[index].print
|
||||
}else{
|
||||
ksdaantemp[index].printstu=0
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
const sqlupdate = 'UPDATE kaoshiend SET ksdaan=?,allprint=? WHERE id=?';
|
||||
//resultksdaan[i].
|
||||
await new Promise((resolve, reject) => {
|
||||
connection.query(sqlupdate,[JSON.stringify(ksdaantemp,null,4),num,resultksdaan[i].id],(error, results) => {
|
||||
if (error) throw error;
|
||||
resolve(results);
|
||||
|
||||
})
|
||||
})
|
||||
allprint.push(num)
|
||||
infor.push({infor:ksdaantemp,num:num})
|
||||
}
|
||||
}
|
||||
|
||||
res.send({finish: finishr})
|
||||
}else{
|
||||
res.send({finish: true})
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,165 @@
|
||||
const xml2js = require('xml2js');
|
||||
const parser = new xml2js.Parser();
|
||||
const fs = require('fs');
|
||||
const moment = require('moment');
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
var q = require('qiao-zip');
|
||||
const uuidv4 = require('uuid');
|
||||
|
||||
const sheetlist=async(xlsx)=>{
|
||||
const cacheDir = path.join(os.homedir(), '.cache');
|
||||
const filedir=cacheDir+'\\learn\\'+uuidv4.v4();
|
||||
fs.mkdirSync(filedir);
|
||||
await q.unzip(xlsx, filedir)
|
||||
const xmlwb=fs.readFileSync(filedir+"/[Content_Types].xml",'utf8');
|
||||
const wbresult=await new Promise((resolve,reject)=>{
|
||||
parser.parseString(xmlwb, (err, result) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
throw err;
|
||||
}
|
||||
resolve(result);
|
||||
});
|
||||
})
|
||||
//console.log(wbresult);
|
||||
let slist=[];
|
||||
let wblist=await wblsit(filedir+"/xl/sharedStrings.xml")
|
||||
|
||||
wbresult.Types.Override.map((value,index)=>{
|
||||
//console.log(value);
|
||||
if(value['$'].ContentType==="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"){
|
||||
slist.push(value['$'].PartName);
|
||||
}
|
||||
|
||||
})
|
||||
let chengji=[];
|
||||
//console.log(slist);
|
||||
let chengname=[];
|
||||
for(let i=0;i<slist.length;i++){
|
||||
|
||||
const biao=await wjb(filedir+slist[i],wblist);
|
||||
//
|
||||
let xiangnum=-1;//姓名项在第几列
|
||||
for(let j=0;j<biao.length;j++){
|
||||
if(biao[j].includes("姓名")){
|
||||
xiangnum=j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
let nameid=biao[xiangnum].indexOf("姓名");
|
||||
let xuehaoid=biao[xiangnum].indexOf("学号");
|
||||
let sex=biao[xiangnum].indexOf("性别");
|
||||
let classid=biao[xiangnum].indexOf("班级");
|
||||
let xueyaunid=biao[xiangnum].indexOf("学院");
|
||||
let idcardid=biao[xiangnum].indexOf("身份证号");
|
||||
let ruxuetime=biao[xiangnum].indexOf("入学日期")
|
||||
let iphone=biao[xiangnum].indexOf("学生手机号");
|
||||
let parentname=biao[xiangnum].indexOf("家长姓名")
|
||||
let parentphone=biao[xiangnum].indexOf("家长手机号")
|
||||
//console.log(nameid)
|
||||
// console.log(xiangnum);
|
||||
//console.log(biao);
|
||||
const stulsit=[];
|
||||
for(let j=xiangnum+1;j<biao.length;j++){
|
||||
let ruxue="" ;
|
||||
if( /^\d+$/.test(biao[j][ruxuetime])){
|
||||
if (parseInt(biao[j][ruxuetime])<80000){
|
||||
ruxue=moment("1900-01-01").add(parseInt(biao[j][ruxuetime])-2,'day').format();
|
||||
//console.log(mom);
|
||||
}
|
||||
}else{
|
||||
ruxue=moment(biao[j][ruxuetime]).format();
|
||||
}
|
||||
const stu={
|
||||
name:biao[j][nameid],
|
||||
xuehao:biao[j][xuehaoid],
|
||||
sex:biao[j][sex],
|
||||
classid:biao[j][classid],
|
||||
xueyuan:biao[j][xueyaunid],
|
||||
idcard:biao[j][idcardid],
|
||||
ruxuetime:ruxue,
|
||||
iphone:biao[j][iphone],
|
||||
parentphone:biao[j][parentphone],
|
||||
parentname:biao[j][parentname],
|
||||
choose:true
|
||||
}
|
||||
// console.log(stu);
|
||||
stulsit.push(stu);
|
||||
}
|
||||
chengji.push({stu:stulsit,name:path.parse(filedir+slist[i]).name,add:false});
|
||||
chengname.push(path.parse(filedir+slist[i]).name);
|
||||
}
|
||||
//
|
||||
// console.log(chengname);
|
||||
// console.log(chengji);
|
||||
return chengji;
|
||||
}
|
||||
const wblsit=async (file)=>{
|
||||
const xmlwb=fs.readFileSync(file,'utf8');
|
||||
// console.log(xmlwb);
|
||||
const wbresult=await new Promise((resolve,reject)=>{
|
||||
parser.parseString(xmlwb, (err, result) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
throw err;
|
||||
}
|
||||
resolve(result);
|
||||
});
|
||||
})
|
||||
let wbone=[];
|
||||
wbresult.sst.si.map((value)=>{
|
||||
//console.log(value);
|
||||
wbone.push(value.t[0]);
|
||||
})
|
||||
//console.log(wbone);
|
||||
return wbone;
|
||||
}
|
||||
const wjb=async(file,list)=>{
|
||||
const xmlwb=fs.readFileSync(file,'utf8');
|
||||
const wbresult=await new Promise((resolve,reject)=>{
|
||||
parser.parseString(xmlwb, (err, result) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
throw err;
|
||||
}
|
||||
resolve(result);
|
||||
});
|
||||
})
|
||||
const excerow=wbresult.worksheet.sheetData[0].row;
|
||||
let allexcel=[]
|
||||
|
||||
wbresult.worksheet.sheetData[0].row.map((value,index)=>{
|
||||
let hangexcel=[];
|
||||
value.c.map((value,index)=>{
|
||||
//console.log(value);
|
||||
const t=value['$'].t;
|
||||
const v=value.v[0];
|
||||
let zhi="";
|
||||
// if (parseInt(v)<40000&&parseInt(v)>80000) {
|
||||
if (t === undefined) {
|
||||
zhi = v;
|
||||
} else if (t === 's') {
|
||||
zhi = list[parseInt(v)];
|
||||
} else {
|
||||
zhi = v;
|
||||
}
|
||||
// }else{
|
||||
// zhi =moment("1900-01-01").add(parseInt(v),'days').format('YYYY-MM-DD');
|
||||
//}
|
||||
|
||||
hangexcel.push(zhi);
|
||||
|
||||
})
|
||||
allexcel.push(hangexcel);
|
||||
});
|
||||
// console.log(allexcel);
|
||||
return allexcel;
|
||||
}
|
||||
//wblsit("C:/Users/l/Desktop/a1/xl/sharedStrings.xml").then(t=>{
|
||||
// wjb("C:/Users/l/Desktop/a1/xl/worksheets/sheet1.xml",t)
|
||||
//})
|
||||
//sheetlist("C:\\Users\\l\\Desktop\\12\\a141.xlsx")
|
||||
const cacheDir = path.join(os.homedir(), '.cache');
|
||||
console.log(cacheDir);
|
||||
exports.sheetlist=sheetlist;
|
@ -0,0 +1,109 @@
|
||||
//生成课表
|
||||
|
||||
const fs = require('fs');
|
||||
const LkbString = require('lz-string');
|
||||
const kb=[];
|
||||
function compressText(text) {
|
||||
return LkbString.compressToEncodedURIComponent(text);
|
||||
}
|
||||
|
||||
for (let i = 0; i < 11; i++) {
|
||||
|
||||
kb[i*28+0]={ke:1,time:"n"+i.toString()+"z1A1"};
|
||||
kb[i*28+1]={ke:2,time:"n"+i.toString()+"z1A2"};
|
||||
kb[i*28+2]={ke:0,time:"n"+i.toString()+"z1A3"};
|
||||
kb[i*28+3]={ke:0,time:"n"+i.toString()+"z1A4"};
|
||||
kb[i*28+4]={ke:0,time:"n"+i.toString()+"z2A1"};
|
||||
kb[i*28+5]={ke:2,time:"n"+i.toString()+"z2A2"};
|
||||
kb[i*28+6]={ke:3,time:"n"+i.toString()+"z2A3"};
|
||||
kb[i*28+7]={ke:0,time:"n"+i.toString()+"z2A4"};
|
||||
kb[i*28+8]={ke:1,time:"n"+i.toString()+"z3A1"};
|
||||
kb[i*28+9]={ke:4,time:"n"+i.toString()+"z3A2"};
|
||||
kb[i*28+10]={ke:0,time:"n"+i.toString()+"z3A3"};
|
||||
kb[i*28+11]={ke:0,time:"n"+i.toString()+"z3A4"};
|
||||
kb[i*28+12]={ke:1,time:"n"+i.toString()+"z4A1"};
|
||||
kb[i*28+13]={ke:2,time:"n"+i.toString()+"z4A2"};
|
||||
kb[i*28+14]={ke:3,time:"n"+i.toString()+"z4A3"};
|
||||
kb[i*28+15]={ke:0,time:"n"+i.toString()+"z4A4"};
|
||||
kb[i*28+16]={ke:3,time:"n"+i.toString()+"z5A1"};
|
||||
kb[i*28+17]={ke:4,time:"n"+i.toString()+"z5A2"};
|
||||
kb[i*28+18]={ke:5,time:"n"+i.toString()+"z5A3"};
|
||||
kb[i*28+19]={ke:0,time:"n"+i.toString()+"z5A4"};
|
||||
kb[i*28+20]={ke:0,time:"n"+i.toString()+"z6A1"};
|
||||
kb[i*28+21]={ke:0,time:"n"+i.toString()+"z6A2"};
|
||||
kb[i*28+22]={ke:0,time:"n"+i.toString()+"z6A3"};
|
||||
kb[i*28+23]={ke:0,time:"n"+i.toString()+"z6A4"};
|
||||
kb[i*28+24]={ke:0,time:"n"+i.toString()+"z7A1"};
|
||||
kb[i*28+25]={ke:0,time:"n"+i.toString()+"z7A2"};
|
||||
kb[i*28+26]={ke:0,time:"n"+i.toString()+"z7A3"};
|
||||
kb[i*28+27]={ke:0,time:"n"+i.toString()+"z7A4"};
|
||||
}
|
||||
for (let i = 11; i < 15; i++) {
|
||||
|
||||
kb[i*28+0]={ke:1,time:"n"+i.toString()+"z1A1"};
|
||||
kb[i*28+1]={ke:2,time:"n"+i.toString()+"z1A2"};
|
||||
kb[i*28+2]={ke:0,time:"n"+i.toString()+"z1A3"};
|
||||
kb[i*28+3]={ke:6,time:"n"+i.toString()+"z1A4"};
|
||||
kb[i*28+4]={ke:0,time:"n"+i.toString()+"z2A1"};
|
||||
kb[i*28+5]={ke:2,time:"n"+i.toString()+"z2A2"};
|
||||
kb[i*28+6]={ke:3,time:"n"+i.toString()+"z2A3"};
|
||||
kb[i*28+7]={ke:0,time:"n"+i.toString()+"z2A4"};
|
||||
kb[i*28+8]={ke:1,time:"n"+i.toString()+"z3A1"};
|
||||
kb[i*28+9]={ke:4,time:"n"+i.toString()+"z3A2"};
|
||||
kb[i*28+10]={ke:0,time:"n"+i.toString()+"z3A3"};
|
||||
kb[i*28+11]={ke:0,time:"n"+i.toString()+"z3A4"};
|
||||
kb[i*28+12]={ke:1,time:"n"+i.toString()+"z4A1"};
|
||||
kb[i*28+13]={ke:2,time:"n"+i.toString()+"z4A2"};
|
||||
kb[i*28+14]={ke:3,time:"n"+i.toString()+"z4A3"};
|
||||
kb[i*28+15]={ke:0,time:"n"+i.toString()+"z4A4"};
|
||||
kb[i*28+16]={ke:3,time:"n"+i.toString()+"z5A1"};
|
||||
kb[i*28+17]={ke:4,time:"n"+i.toString()+"z5A2"};
|
||||
kb[i*28+18]={ke:5,time:"n"+i.toString()+"z5A3"};
|
||||
kb[i*28+19]={ke:0,time:"n"+i.toString()+"z5A4"};
|
||||
kb[i*28+20]={ke:0,time:"n"+i.toString()+"z6A1"};
|
||||
kb[i*28+21]={ke:0,time:"n"+i.toString()+"z6A2"};
|
||||
kb[i*28+22]={ke:0,time:"n"+i.toString()+"z6A3"};
|
||||
kb[i*28+23]={ke:0,time:"n"+i.toString()+"z6A4"};
|
||||
kb[i*28+24]={ke:0,time:"n"+i.toString()+"z7A1"};
|
||||
kb[i*28+25]={ke:0,time:"n"+i.toString()+"z7A2"};
|
||||
kb[i*28+26]={ke:0,time:"n"+i.toString()+"z7A3"};
|
||||
kb[i*28+27]={ke:0,time:"n"+i.toString()+"z7A4"};
|
||||
|
||||
}
|
||||
for (let i = 15; i < 20; i++) {
|
||||
|
||||
kb[i*28+0]={ke:1,time:"n"+i.toString()+"z1A1"};
|
||||
kb[i*28+1]={ke:0,time:"n"+i.toString()+"z1A2"};
|
||||
kb[i*28+2]={ke:0,time:"n"+i.toString()+"z1A3"};
|
||||
kb[i*28+3]={ke:0,time:"n"+i.toString()+"z1A4"};
|
||||
kb[i*28+4]={ke:0,time:"n"+i.toString()+"z2A1"};
|
||||
kb[i*28+5]={ke:0,time:"n"+i.toString()+"z2A2"};
|
||||
kb[i*28+6]={ke:3,time:"n"+i.toString()+"z2A3"};
|
||||
kb[i*28+7]={ke:0,time:"n"+i.toString()+"z2A4"};
|
||||
kb[i*28+8]={ke:1,time:"n"+i.toString()+"z3A1"};
|
||||
kb[i*28+9]={ke:0,time:"n"+i.toString()+"z3A2"};
|
||||
kb[i*28+10]={ke:0,time:"n"+i.toString()+"z3A3"};
|
||||
kb[i*28+11]={ke:0,time:"n"+i.toString()+"z3A4"};
|
||||
kb[i*28+12]={ke:1,time:"n"+i.toString()+"z4A1"};
|
||||
kb[i*28+13]={ke:0,time:"n"+i.toString()+"z4A2"};
|
||||
kb[i*28+14]={ke:3,time:"n"+i.toString()+"z4A3"};
|
||||
kb[i*28+15]={ke:0,time:"n"+i.toString()+"z4A4"};
|
||||
kb[i*28+16]={ke:3,time:"n"+i.toString()+"z5A1"};
|
||||
kb[i*28+17]={ke:0,time:"n"+i.toString()+"z5A2"};
|
||||
kb[i*28+18]={ke:5,time:"n"+i.toString()+"z5A3"};
|
||||
kb[i*28+19]={ke:0,time:"n"+i.toString()+"z5A4"};
|
||||
kb[i*28+20]={ke:0,time:"n"+i.toString()+"z6A1"};
|
||||
kb[i*28+21]={ke:0,time:"n"+i.toString()+"z6A2"};
|
||||
kb[i*28+22]={ke:0,time:"n"+i.toString()+"z6A3"};
|
||||
kb[i*28+23]={ke:0,time:"n"+i.toString()+"z6A4"};
|
||||
kb[i*28+24]={ke:0,time:"n"+i.toString()+"z7A1"};
|
||||
kb[i*28+25]={ke:0,time:"n"+i.toString()+"z7A2"};
|
||||
kb[i*28+26]={ke:0,time:"n"+i.toString()+"z7A3"};
|
||||
kb[i*28+27]={ke:0,time:"n"+i.toString()+"z7A4"};
|
||||
//kb.push(JSON.stringify(kb));
|
||||
}
|
||||
const compressedText = JSON.stringify(kb);
|
||||
fs.appendFile('wj3.json',compressedText, (err) => {
|
||||
if (err) throw err;
|
||||
console.log('数据已成功写入文件');
|
||||
});
|
@ -0,0 +1,64 @@
|
||||
const fs=require('fs');
|
||||
const moment=require('moment');
|
||||
var mysql = require('mysql');
|
||||
const LZString = require('lz-string');
|
||||
const e = require("express");
|
||||
var connection = mysql.createConnection({
|
||||
host : 'localhost',
|
||||
user : 'root',
|
||||
password : '416416',
|
||||
database : 'neigongda'
|
||||
});
|
||||
function decompressText(compressedText) {
|
||||
return LZString.decompressFromEncodedURIComponent(compressedText);
|
||||
}
|
||||
connection.connect();
|
||||
|
||||
function qjkebiao(xuehao,start,end) {
|
||||
const startxueiq=moment("2024-09-02T00:00:27+08:00");
|
||||
const daystart=moment(start).diff(startxueiq,"days");
|
||||
const dayend=moment(end).diff(startxueiq,"days");
|
||||
console.log(daystart);
|
||||
const minutestart=moment(start).minutes()+moment(start).hours()*60;
|
||||
const minutesend=moment(end).minutes()+moment(end).hours()*60;
|
||||
let kestart=0;
|
||||
if(minutestart<500){
|
||||
kestart=1;
|
||||
}else if(minutestart<620){
|
||||
kestart=2;
|
||||
}else if(minutestart<840){
|
||||
kestart=3;
|
||||
}else if(minutestart<960){
|
||||
kestart=4;
|
||||
}else {
|
||||
kestart=5;
|
||||
}
|
||||
let keend=0;
|
||||
if(minutesend>1060){
|
||||
keend=4;
|
||||
}else if(minutesend<940){
|
||||
keend=3;
|
||||
}else if(minutesend<720){
|
||||
keend=2;
|
||||
}else if(minutesend<600){
|
||||
keend=1;
|
||||
}else {
|
||||
keend=0;
|
||||
}
|
||||
const kaishi=daystart+kestart*4;
|
||||
const jieshu=dayend+keend*4;
|
||||
const sql = 'SELECT xunhuan(?,?,?)';
|
||||
|
||||
|
||||
connection.query(sql, [kaishi,jieshu,xuehao], (error, results, fields) => {
|
||||
if (error) throw error;
|
||||
|
||||
// 处理查询结果
|
||||
console.log(results);
|
||||
});
|
||||
console.log(dayend);
|
||||
return 0;
|
||||
}
|
||||
|
||||
exports.qjkebiao = qjkebiao;
|
||||
|
@ -0,0 +1 @@
|
||||
[{"z1A1":1,"z1A2":2,"z1A3":0,"z1A4":0,"z2A1":0,"z2A2":2,"z2A3":3,"z2A4":0,"z3A1":1,"z3A2":4,"z3A3":0,"z3A4":0,"z4A1":1,"z4A2":2,"z4A3":3,"z4A4":0,"z5A1":3,"z5A2":4,"z5A3":5,"z5A4":0},{"z1A1":1,"z1A2":2,"z1A3":0,"z1A4":0,"z2A1":0,"z2A2":2,"z2A3":3,"z2A4":0,"z3A1":1,"z3A2":4,"z3A3":0,"z3A4":0,"z4A1":1,"z4A2":2,"z4A3":3,"z4A4":0,"z5A1":3,"z5A2":4,"z5A3":5,"z5A4":0},{"z1A1":1,"z1A2":2,"z1A3":0,"z1A4":0,"z2A1":0,"z2A2":2,"z2A3":3,"z2A4":0,"z3A1":1,"z3A2":4,"z3A3":0,"z3A4":0,"z4A1":1,"z4A2":2,"z4A3":3,"z4A4":0,"z5A1":3,"z5A2":4,"z5A3":5,"z5A4":0},{"z1A1":1,"z1A2":2,"z1A3":0,"z1A4":0,"z2A1":0,"z2A2":2,"z2A3":3,"z2A4":0,"z3A1":1,"z3A2":4,"z3A3":0,"z3A4":0,"z4A1":1,"z4A2":2,"z4A3":3,"z4A4":0,"z5A1":3,"z5A2":4,"z5A3":5,"z5A4":0},{"z1A1":1,"z1A2":2,"z1A3":0,"z1A4":0,"z2A1":0,"z2A2":2,"z2A3":3,"z2A4":0,"z3A1":1,"z3A2":4,"z3A3":0,"z3A4":0,"z4A1":1,"z4A2":2,"z4A3":3,"z4A4":0,"z5A1":3,"z5A2":4,"z5A3":5,"z5A4":0},{"z1A1":1,"z1A2":2,"z1A3":0,"z1A4":0,"z2A1":0,"z2A2":2,"z2A3":3,"z2A4":0,"z3A1":1,"z3A2":4,"z3A3":0,"z3A4":0,"z4A1":1,"z4A2":2,"z4A3":3,"z4A4":0,"z5A1":3,"z5A2":4,"z5A3":5,"z5A4":0},{"z1A1":1,"z1A2":2,"z1A3":0,"z1A4":0,"z2A1":0,"z2A2":2,"z2A3":3,"z2A4":0,"z3A1":1,"z3A2":4,"z3A3":0,"z3A4":0,"z4A1":1,"z4A2":2,"z4A3":3,"z4A4":0,"z5A1":3,"z5A2":4,"z5A3":5,"z5A4":0},{"z1A1":1,"z1A2":2,"z1A3":0,"z1A4":0,"z2A1":0,"z2A2":2,"z2A3":3,"z2A4":0,"z3A1":1,"z3A2":4,"z3A3":0,"z3A4":0,"z4A1":1,"z4A2":2,"z4A3":3,"z4A4":0,"z5A1":3,"z5A2":4,"z5A3":5,"z5A4":0},{"z1A1":1,"z1A2":2,"z1A3":0,"z1A4":0,"z2A1":0,"z2A2":2,"z2A3":3,"z2A4":0,"z3A1":1,"z3A2":4,"z3A3":0,"z3A4":0,"z4A1":1,"z4A2":2,"z4A3":3,"z4A4":0,"z5A1":3,"z5A2":4,"z5A3":5,"z5A4":0},{"z1A1":1,"z1A2":2,"z1A3":0,"z1A4":0,"z2A1":0,"z2A2":2,"z2A3":3,"z2A4":0,"z3A1":1,"z3A2":4,"z3A3":0,"z3A4":0,"z4A1":1,"z4A2":2,"z4A3":3,"z4A4":0,"z5A1":3,"z5A2":4,"z5A3":5,"z5A4":0},{"z1A1":1,"z1A2":2,"z1A3":0,"z1A4":0,"z2A1":0,"z2A2":2,"z2A3":3,"z2A4":0,"z3A1":1,"z3A2":4,"z3A3":0,"z3A4":0,"z4A1":1,"z4A2":2,"z4A3":3,"z4A4":0,"z5A1":3,"z5A2":4,"z5A3":5,"z5A4":0},{"z1A1":1,"z1A2":2,"z1A3":0,"z1A4":6,"z2A1":0,"z2A2":2,"z2A3":3,"z2A4":0,"z3A1":1,"z3A2":4,"z3A3":0,"z3A4":0,"z4A1":1,"z4A2":2,"z4A3":3,"z4A4":0,"z5A1":3,"z5A2":4,"z5A3":5,"z5A4":0},{"z1A1":1,"z1A2":2,"z1A3":0,"z1A4":6,"z2A1":0,"z2A2":2,"z2A3":3,"z2A4":0,"z3A1":1,"z3A2":4,"z3A3":0,"z3A4":0,"z4A1":1,"z4A2":2,"z4A3":3,"z4A4":0,"z5A1":3,"z5A2":4,"z5A3":5,"z5A4":0},{"z1A1":1,"z1A2":2,"z1A3":0,"z1A4":6,"z2A1":0,"z2A2":2,"z2A3":3,"z2A4":0,"z3A1":1,"z3A2":4,"z3A3":0,"z3A4":0,"z4A1":1,"z4A2":2,"z4A3":3,"z4A4":0,"z5A1":3,"z5A2":4,"z5A3":5,"z5A4":0},{"z1A1":1,"z1A2":2,"z1A3":0,"z1A4":6,"z2A1":0,"z2A2":2,"z2A3":3,"z2A4":0,"z3A1":1,"z3A2":4,"z3A3":0,"z3A4":0,"z4A1":1,"z4A2":2,"z4A3":3,"z4A4":0,"z5A1":3,"z5A2":4,"z5A3":5,"z5A4":0},{"z1A1":1,"z1A2":0,"z1A3":0,"z1A4":0,"z2A1":0,"z2A2":0,"z2A3":3,"z2A4":0,"z3A1":1,"z3A2":0,"z3A3":0,"z3A4":0,"z4A1":1,"z4A2":0,"z4A3":3,"z4A4":0,"z5A1":3,"z5A2":0,"z5A3":5,"z5A4":0},{"z1A1":1,"z1A2":0,"z1A3":0,"z1A4":0,"z2A1":0,"z2A2":0,"z2A3":3,"z2A4":0,"z3A1":1,"z3A2":0,"z3A3":0,"z3A4":0,"z4A1":1,"z4A2":0,"z4A3":3,"z4A4":0,"z5A1":3,"z5A2":0,"z5A3":5,"z5A4":0},{"z1A1":1,"z1A2":0,"z1A3":0,"z1A4":0,"z2A1":0,"z2A2":0,"z2A3":3,"z2A4":0,"z3A1":1,"z3A2":0,"z3A3":0,"z3A4":0,"z4A1":1,"z4A2":0,"z4A3":3,"z4A4":0,"z5A1":3,"z5A2":0,"z5A3":5,"z5A4":0},{"z1A1":1,"z1A2":0,"z1A3":0,"z1A4":0,"z2A1":0,"z2A2":0,"z2A3":3,"z2A4":0,"z3A1":1,"z3A2":0,"z3A3":0,"z3A4":0,"z4A1":1,"z4A2":0,"z4A3":3,"z4A4":0,"z5A1":3,"z5A2":0,"z5A3":5,"z5A4":0},{"z1A1":1,"z1A2":0,"z1A3":0,"z1A4":0,"z2A1":0,"z2A2":0,"z2A3":3,"z2A4":0,"z3A1":1,"z3A2":0,"z3A3":0,"z3A4":0,"z4A1":1,"z4A2":0,"z4A3":3,"z4A4":0,"z5A1":3,"z5A2":0,"z5A3":5,"z5A4":0}]
|
@ -0,0 +1 @@
|
||||
N4IgJgDARgjAgjEAuGAac14CZlfZWOAZmQn0zgBZTyosEaM64ck8n6Skjb7qkyTIgxS1hrSmOKMCw-oIKURaJktbtF07rSXzaAVhE8mhiQa37ze8DEKJRNwuvy34XBa6ozb9ex+bOjpzIxmA+XgIuUML2KmHRLMiSjsLuUXLeUEqxUWq4uVqhtrqZhvZFUKZJUYZclo6G1mBYdshxLdj54B1aCj1NLb4yg4ls+CNcoSMDCTndCWbzqcMJM9lt41mjGi1Kk5slkfNlIZtVSMnNlRZnEQpErQ5gD51j4C+9+B9ND0NHzwEugDgtp3swfrMNmDxNVoZ84RD1k8Hnk3gC9qcwYd7tdyl9rosAbVkPUiXd8JRHnFKa8NDT4WB6U1KX8FCzthTmPtwOzmZCnpSYRdOct-oLyTytnNGVtAjKMaD5RKZSdFZTzpd1TdJY0ZPoqfh9bTDYQ0uAjcr9ayTfQ5VbCjbLfy4vqhZdXQyPU19UiXbKgT6Heatt7cZiwPqNSbiUhSZHlQA2A3gJPGlOmmSpxPMPz4JO2oH5oNgItNJMxKElhawquihTl7O+vP+tFJhWhNvZ1Udgk1pMx0n95UAdmTYFHafHGf+E5HOZko4LaMXxZXTVHFaeG9Gl23ZqnGRnUsro9RGlPq5DC7DitHUfAd+1U91-wAHGP35PPwzv0139bwH-DlAK5cMgL-Z18HfN0oISfdoOVd8mxAs9YPbNDEJvUJ33vMAcKffCmgATjHEjJzIhkKOI+d-hIpcNDo4tGOozc4hImDwHYyjVhkEjkLAPjgIErZuWE7F8BI7sJN7YVOOuOppJfDwKGlGAKDlNTp2Uwgmk0gCwmgeiXEM4s9OVTTWOM6tZIMuDvGgQ9tP4zTUJsaB0Lcq9-k0qTPNwnynwC3TPFUzwNM8fcYE8fgExccJcxscJwtAxUovBbxbEsxLrMuNK6zinjvOKZQCtcsJitEtLxOy3zypk3LbAHAqlJcHpVJ6DSeki-pkFimwRgSsIRk6lKimmbwWiyoactauzvMm8zdhK-qWw0GAlsqpbdJaWr1vq2ampWlqbA+VSPg0j5Iu+XqXF+EQPDui7Rtu9LvIeKaYHencXvyk7Coe48nk+1aXo8sIUXMh5dqh76-sO8Hrl0+lVPpDT6UipkbpsdlBpgdk0ee7HXo8cUUZmonfrCcUkcBuI8ZBomwfp6qqawlwtUJen4a58yLVUi1WA8C1IotXT7Vx+1BZce1KvtMXIJsD0pcVuahf+6XaY11E1aZwN5d2+NlbCeMFJV46wizVSsyNmAs0irNdKLXGixtotKtLbwGyt6yPAbe31ZsTtve1lxO3drzfbZwOZMj7mh102dVNnG3Z0i2cE5ojwVxTwmwjXbxtyTn2XD3AuA7zzWbAvHOmYvDPdsfHPucfXTv1U78be-SLf28IDcaAzvc5gcDe4VsIEMHynh-L6fnKQ0YPHnyr59bqPx5jlx8NN9fzZgCjVIom2KMiqjvEY3HGKPofmLPse9+LmwuJPmfBIPlsPEEyrBN0ySjBcX+r7c1-vIAAvkAA
|
@ -0,0 +1,10 @@
|
||||
/// <reference types='@dcloudio/types' />
|
||||
import 'vue'
|
||||
|
||||
declare module '@vue/runtime-core' {
|
||||
type Hooks = App.AppInstance & Page.PageInstance;
|
||||
|
||||
interface ComponentCustomOptions extends Hooks {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import { onLaunch, onShow, onHide } from "@dcloudio/uni-app";
|
||||
onLaunch(() => {
|
||||
console.log("App Launch");
|
||||
});
|
||||
onShow(() => {
|
||||
console.log("App Show");
|
||||
});
|
||||
onHide(() => {
|
||||
console.log("App Hide");
|
||||
});
|
||||
|
||||
</script>
|
||||
<style></style>
|
@ -0,0 +1,87 @@
|
||||
<template>
|
||||
<view
|
||||
class="tech-button"
|
||||
:class="[type, size]"
|
||||
@click="$emit('click')"
|
||||
>
|
||||
<slot></slot>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
type: {
|
||||
type: String,
|
||||
default: 'primary', // primary | secondary
|
||||
validator: (value) => ['primary', 'secondary'].includes(value)
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: 'normal', // normal | small
|
||||
validator: (value) => ['normal', 'small'].includes(value)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tech-button {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
border-radius: 50rpx;
|
||||
font-weight: 500;
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(135deg, #00f2fe 0%, #4facfe 100%);
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
&.primary {
|
||||
background: linear-gradient(135deg, #00f2fe 0%, #4facfe 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 4rpx 20rpx rgba(74, 144, 226, 0.3);
|
||||
|
||||
&:active {
|
||||
transform: translateY(2rpx);
|
||||
box-shadow: 0 2rpx 10rpx rgba(74, 144, 226, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
&.secondary {
|
||||
background: rgba(16, 24, 40, 0.8);
|
||||
color: #4facfe;
|
||||
border: 1rpx solid rgba(74, 144, 226, 0.5);
|
||||
|
||||
&:active {
|
||||
background: rgba(31, 47, 71, 0.8);
|
||||
}
|
||||
}
|
||||
|
||||
&.normal {
|
||||
height: 80rpx;
|
||||
padding: 0 40rpx;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
&.small {
|
||||
height: 60rpx;
|
||||
padding: 0 30rpx;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
&:active::before {
|
||||
opacity: 0.2;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<view
|
||||
class="tech-card"
|
||||
:class="{ active }"
|
||||
@click="$emit('click')"
|
||||
>
|
||||
<view class="card-bg"></view>
|
||||
<view class="card-content">
|
||||
<uni-icons
|
||||
:type="icon"
|
||||
size="28"
|
||||
:color="active ? '#4facfe' : 'rgba(255,255,255,0.7)'"
|
||||
/>
|
||||
<text class="card-title">{{ title }}</text>
|
||||
</view>
|
||||
<view class="card-decoration"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
title: String,
|
||||
icon: String,
|
||||
active: Boolean
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tech-card {
|
||||
height: 140rpx;
|
||||
border-radius: 16rpx;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
.card-bg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(16, 24, 40, 0.8);
|
||||
border: 1px solid rgba(74, 144, 226, 0.2);
|
||||
backdrop-filter: blur(5px);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.card-content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 20rpx;
|
||||
|
||||
.card-title {
|
||||
font-size: 28rpx;
|
||||
margin-top: 15rpx;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
}
|
||||
|
||||
.card-decoration {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
background: radial-gradient(circle, rgba(74, 144, 226, 0.3) 0%, transparent 70%);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&.active {
|
||||
transform: translateY(-5rpx);
|
||||
box-shadow: 0 10rpx 20rpx rgba(0, 242, 254, 0.2);
|
||||
|
||||
.card-bg {
|
||||
background: rgba(31, 47, 71, 0.8);
|
||||
border-color: rgba(74, 144, 226, 0.5);
|
||||
}
|
||||
|
||||
.card-decoration {
|
||||
background: radial-gradient(circle, rgba(74, 144, 226, 0.6) 0%, transparent 70%);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<view class="tech-progress">
|
||||
<view
|
||||
class="progress-bar"
|
||||
:style="{ width: `${percent}%` }"
|
||||
>
|
||||
<view class="progress-highlight"></view>
|
||||
</view>
|
||||
<text class="progress-text">{{ percent }}%</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
percent: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
validator: (value) => value >= 0 && value <= 100
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tech-progress {
|
||||
height: 16rpx;
|
||||
background: rgba(16, 24, 40, 0.8);
|
||||
border-radius: 8rpx;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border: 1rpx solid rgba(74, 144, 226, 0.3);
|
||||
|
||||
.progress-bar {
|
||||
height: 100%;
|
||||
border-radius: 8rpx;
|
||||
background: linear-gradient(90deg, #00f2fe 0%, #4facfe 100%);
|
||||
position: relative;
|
||||
transition: width 0.6s ease;
|
||||
|
||||
.progress-highlight {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(90deg, rgba(255,255,255,0.3) 0%, transparent 100%);
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.progress-text {
|
||||
position: absolute;
|
||||
right: 10rpx;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
font-size: 22rpx;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,8 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
declare module '*.vue' {
|
||||
import { DefineComponent } from 'vue'
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
|
||||
const component: DefineComponent<{}, {}, any>
|
||||
export default component
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
import { createSSRApp } from "vue";
|
||||
import App from "./App.vue";
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App);
|
||||
return {
|
||||
app,
|
||||
};
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
{
|
||||
"name" : "",
|
||||
"appid" : "",
|
||||
"description" : "",
|
||||
"versionName" : "1.0.0",
|
||||
"versionCode" : "100",
|
||||
"transformPx" : false,
|
||||
/* 5+App特有相关 */
|
||||
"app-plus" : {
|
||||
"usingComponents" : true,
|
||||
"nvueStyleCompiler" : "uni-app",
|
||||
"compilerVersion" : 3,
|
||||
"splashscreen" : {
|
||||
"alwaysShowBeforeRender" : true,
|
||||
"waiting" : true,
|
||||
"autoclose" : true,
|
||||
"delay" : 0
|
||||
},
|
||||
/* 模块配置 */
|
||||
"modules" : {},
|
||||
/* 应用发布信息 */
|
||||
"distribute" : {
|
||||
/* android打包配置 */
|
||||
"android" : {
|
||||
"permissions" : [
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||
]
|
||||
},
|
||||
/* ios打包配置 */
|
||||
"ios" : {},
|
||||
/* SDK配置 */
|
||||
"sdkConfigs" : {}
|
||||
}
|
||||
},
|
||||
/* 快应用特有相关 */
|
||||
"quickapp" : {},
|
||||
/* 小程序特有相关 */
|
||||
"mp-weixin" : {
|
||||
"appid" : "",
|
||||
"setting" : {
|
||||
"urlCheck" : false,
|
||||
"minified" : true
|
||||
},
|
||||
"usingComponents" : true,
|
||||
"optimization" : {
|
||||
"subPackages" : true
|
||||
},
|
||||
"lazyCodeLoading": "requiredComponents"
|
||||
},
|
||||
"mp-alipay" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-baidu" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-toutiao" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"uniStatistics" : {
|
||||
"enable" : false
|
||||
},
|
||||
"vueVersion" : "3"
|
||||
}
|
@ -0,0 +1,185 @@
|
||||
{
|
||||
"pages": [
|
||||
{
|
||||
"path": "pages/index/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "首页",
|
||||
"enablePullDownRefresh": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/learning/learning",
|
||||
"style": {
|
||||
"navigationBarTitleText": "课程学习"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/management/management",
|
||||
"style": {
|
||||
"navigationBarTitleText": "课程管理"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/schedule/schedule",
|
||||
"style": {
|
||||
"navigationBarTitleText": "智能课程表",
|
||||
"navigationBarBackgroundColor": "#0a192f",
|
||||
"navigationBarTextStyle": "white",
|
||||
"backgroundColor": "#0a192f"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/user",
|
||||
"style": {
|
||||
"navigationBarTitleText": "个人中心"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/leave/leave",
|
||||
"style": {
|
||||
"navigationBarTitleText": "leave"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/plan/plan",
|
||||
"style": {
|
||||
"navigationBarTitleText": "plan"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/bussin/bussin",
|
||||
"style": {
|
||||
"navigationBarTitleText": "bussin"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/course/course",
|
||||
"style": {
|
||||
"navigationBarTitleText": "course"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/score/score",
|
||||
"style": {
|
||||
"navigationBarTitleText": "score"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/settings/settings",
|
||||
"style": {
|
||||
"navigationBarTitleText": "settings"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/management/leave",
|
||||
"style": {
|
||||
"navigationBarTitleText": "leave"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/management/program",
|
||||
"style": {
|
||||
"navigationBarTitleText": "program"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/management/transcript",
|
||||
"style": {
|
||||
"navigationBarTitleText": "transcript"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/management/selection",
|
||||
"style": {
|
||||
"navigationBarTitleText": "selection"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/list/list",
|
||||
"style": {
|
||||
"navigationBarTitleText": "list"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/discussion/discussion",
|
||||
"style": {
|
||||
"navigationBarTitleText": "discussion"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/checkin/checkin",
|
||||
"style": {
|
||||
"navigationBarTitleText": "checkin"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/quiz/quiz",
|
||||
"style": {
|
||||
"navigationBarTitleText": "quiz"
|
||||
}
|
||||
},{
|
||||
"path": "pages/quiz_outclass/quiz_outclass",
|
||||
"style": {
|
||||
"navigationBarTitleText": "课程答题"
|
||||
}
|
||||
},{
|
||||
"path": "pages/quiz_outclass/selectquestion",
|
||||
"style": {
|
||||
"navigationBarTitleText": "课程答题"
|
||||
}
|
||||
}
|
||||
],
|
||||
"subPackages": [{
|
||||
"root": "pages_A",
|
||||
"pages": [{
|
||||
"path": "exam/selectexam",
|
||||
"style": {
|
||||
"navigationBarTitleText": "课程考试"
|
||||
}
|
||||
},{
|
||||
"path": "exam/exam",
|
||||
"style": {
|
||||
"navigationBarTitleText": "exam2"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "shangke/shangke",
|
||||
"style": {
|
||||
"navigationBarTitleText": "shnagke"
|
||||
}
|
||||
}
|
||||
]
|
||||
}],
|
||||
|
||||
"tabBar": {
|
||||
"color": "#7A7E83",
|
||||
"selectedColor": "#007AFF",
|
||||
"list": [
|
||||
{
|
||||
"pagePath": "pages/learning/learning",
|
||||
"text": "课程学习",
|
||||
"iconPath": "static/edu-tabs/learning.png",
|
||||
"selectedIconPath": "static/edu-tabs/learning-active.png"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/schedule/schedule",
|
||||
"text": "课程表",
|
||||
"iconPath": "/static/edu-tabs/calendar.png",
|
||||
"selectedIconPath": "/static/edu-tabs/calendar-active.png"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/management/management",
|
||||
"text": "课程管理",
|
||||
"iconPath": "/static/edu-tabs/dashboard.png",
|
||||
"selectedIconPath": "/static/edu-tabs/dashboard-active.png"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/user/user",
|
||||
"text": "我的",
|
||||
"iconPath": "/static/edu-tabs/user.png",
|
||||
"selectedIconPath": "/static/edu-tabs/user-active.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,284 @@
|
||||
<template>
|
||||
<view class="tech-container">
|
||||
<!-- 科技风顶部导航 -->
|
||||
<view class="tech-header">
|
||||
<view class="header-content">
|
||||
<text class="header-title">我的课程中心</text>
|
||||
<view class="header-line"></view>
|
||||
</view>
|
||||
<view class="tech-pattern"></view>
|
||||
</view>
|
||||
|
||||
<!-- 课程内容区域 -->
|
||||
<view class="course-content">
|
||||
<!-- 课程分类导航 -->
|
||||
<scroll-view class="category-nav" scroll-x>
|
||||
<view
|
||||
v-for="(category, index) in categories"
|
||||
:key="index"
|
||||
class="category-item"
|
||||
:class="{ active: activeCategory === index }"
|
||||
@click="switchCategory(index)"
|
||||
>
|
||||
<text>{{ category }}</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 课程列表 -->
|
||||
<view class="course-list">
|
||||
<view
|
||||
v-for="(course, index) in filteredCourses"
|
||||
:key="index"
|
||||
class="course-card"
|
||||
>
|
||||
<image class="course-cover" :src="course.cover" mode="aspectFill" />
|
||||
<view class="course-info">
|
||||
<view class="title-wrapper">
|
||||
<text class="course-title">{{ course.title }}</text>
|
||||
<text class="course-teacher">{{ course.teacher }}</text>
|
||||
</view>
|
||||
<view class="progress-bar">
|
||||
<view
|
||||
class="progress-fill"
|
||||
:style="{ width: `${course.progress}%` }"
|
||||
></view>
|
||||
</view>
|
||||
<text class="progress-text">已学 {{ course.progress }}%</text>
|
||||
</view>
|
||||
<view class="tech-corner"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 科技风底部装饰 -->
|
||||
<view class="tech-footer">
|
||||
<view class="footer-line"></view>
|
||||
<view class="footer-dots">
|
||||
<view class="dot"></view>
|
||||
<view class="dot"></view>
|
||||
<view class="dot"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue'
|
||||
|
||||
// 课程分类数据
|
||||
const categories = ref(['全部', '进行中', '已完成', '未开始', '收藏'])
|
||||
const activeCategory = ref(0)
|
||||
|
||||
// 课程数据
|
||||
const courses = ref([
|
||||
{
|
||||
id: 1,
|
||||
title: 'Vue3高级开发实战',
|
||||
teacher: '张老师',
|
||||
cover: '/static/student-course/bg.png',
|
||||
progress: 65,
|
||||
category: '进行中'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: 'React全栈开发',
|
||||
teacher: '李老师',
|
||||
cover: '/static/student-course/bg.png',
|
||||
progress: 30,
|
||||
category: '进行中'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: 'Node.js后端开发',
|
||||
teacher: '王老师',
|
||||
cover: '/static/course3.jpg',
|
||||
progress: 100,
|
||||
category: '已完成'
|
||||
}
|
||||
])
|
||||
|
||||
// 切换分类
|
||||
const switchCategory = (index) => {
|
||||
activeCategory.value = index
|
||||
}
|
||||
|
||||
// 过滤课程
|
||||
const filteredCourses = computed(() => {
|
||||
if (activeCategory.value === 0) return courses.value
|
||||
const categoryMap = ['全部', '进行中', '已完成', '未开始', '收藏']
|
||||
return courses.value.filter(course =>
|
||||
course.category === categoryMap[activeCategory.value]
|
||||
)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.tech-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
background-color: #0f1621;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
.tech-header {
|
||||
position: relative;
|
||||
padding: 40rpx 30rpx 30rpx;
|
||||
background: linear-gradient(135deg, #1a2a3a 0%, #0f1621 100%);
|
||||
overflow: hidden;
|
||||
z-index: 1;
|
||||
|
||||
.header-content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 42rpx;
|
||||
font-weight: bold;
|
||||
background: linear-gradient(to right, #4facfe, #00f2fe);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.header-line {
|
||||
height: 4rpx;
|
||||
width: 80rpx;
|
||||
background: linear-gradient(to right, #4facfe, #00f2fe);
|
||||
margin-top: 15rpx;
|
||||
border-radius: 2rpx;
|
||||
}
|
||||
|
||||
.tech-pattern {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 300rpx;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, rgba(79, 172, 254, 0.1) 0%, transparent 70%);
|
||||
opacity: 0.3;
|
||||
}
|
||||
}
|
||||
|
||||
.course-content {
|
||||
flex: 1;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.category-nav {
|
||||
white-space: nowrap;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.category-item {
|
||||
display: inline-block;
|
||||
padding: 15rpx 30rpx;
|
||||
margin-right: 20rpx;
|
||||
font-size: 28rpx;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
border-radius: 40rpx;
|
||||
transition: all 0.3s;
|
||||
|
||||
&.active {
|
||||
background: linear-gradient(to right, #4facfe, #00f2fe);
|
||||
color: #fff;
|
||||
box-shadow: 0 5rpx 15rpx rgba(79, 172, 254, 0.3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.course-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 30rpx;
|
||||
}
|
||||
|
||||
.course-card {
|
||||
position: relative;
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.2);
|
||||
|
||||
.course-cover {
|
||||
width: 100%;
|
||||
height: 300rpx;
|
||||
}
|
||||
|
||||
.course-info {
|
||||
padding: 25rpx;
|
||||
}
|
||||
|
||||
.title-wrapper {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.course-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.course-teacher {
|
||||
font-size: 26rpx;
|
||||
color: #4facfe;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
height: 8rpx;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 4rpx;
|
||||
margin-bottom: 10rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.progress-fill {
|
||||
height: 100%;
|
||||
background: linear-gradient(to right, #4facfe, #00f2fe);
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.progress-text {
|
||||
font-size: 24rpx;
|
||||
color: rgba(79, 172, 254, 0.8);
|
||||
}
|
||||
|
||||
.tech-corner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
border-width: 0 60rpx 60rpx 0;
|
||||
border-color: transparent rgba(79, 172, 254, 0.2) transparent transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.tech-footer {
|
||||
padding: 30rpx 0;
|
||||
position: relative;
|
||||
|
||||
.footer-line {
|
||||
height: 1rpx;
|
||||
background: linear-gradient(to right, transparent, rgba(79, 172, 254, 0.3), transparent);
|
||||
}
|
||||
|
||||
.footer-dots {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 20rpx;
|
||||
margin-top: 20rpx;
|
||||
|
||||
.dot {
|
||||
width: 10rpx;
|
||||
height: 10rpx;
|
||||
border-radius: 50%;
|
||||
background-color: rgba(79, 172, 254, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,17 @@
|
||||
<script setup >
|
||||
import { onMounted, onUnmounted } from 'vue'
|
||||
import moment from "moment/min/moment-with-locales";
|
||||
|
||||
import io from '@hyoga/uni-socket.io'
|
||||
import { ref } from 'vue'
|
||||
import {onLoad} from "@dcloudio/uni-app";
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -0,0 +1,253 @@
|
||||
<template>
|
||||
<view class="tech-welcome-container">
|
||||
<!-- 科技风背景元素 -->
|
||||
<view class="tech-background">
|
||||
<view class="tech-circle circle-1"></view>
|
||||
<view class="tech-circle circle-2"></view>
|
||||
<view class="tech-line line-1"></view>
|
||||
<view class="tech-line line-2"></view>
|
||||
<view class="tech-dots">
|
||||
<view class="dot" v-for="i in 20" :key="i" :style="getDotStyle(i)"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 主要内容区 -->
|
||||
<view class="welcome-content">
|
||||
<!-- 动态科技感标题 -->
|
||||
<view class="tech-title">
|
||||
<text class="title-text">只为遇见</text>
|
||||
<text class="title-text highlight">更好的你</text>
|
||||
</view>
|
||||
|
||||
<!-- 加载进度条 -->
|
||||
<view class="tech-progress">
|
||||
<view class="progress-bar">
|
||||
<view class="progress-fill" :style="{width: progress + '%'}"></view>
|
||||
</view>
|
||||
<text class="progress-text">{{progress}}%</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部科技风装饰 -->
|
||||
<view class="tech-footer">
|
||||
<view class="footer-line"></view>
|
||||
<text class="footer-text">智慧教育平台</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
|
||||
const progress = ref(0)
|
||||
|
||||
onMounted(() => {
|
||||
// 模拟加载进度
|
||||
const timer = setInterval(() => {
|
||||
progress.value += Math.floor(Math.random() * 10) + 5
|
||||
if (progress.value >= 100) {
|
||||
progress.value = 100
|
||||
clearInterval(timer)
|
||||
// 加载完成后跳转到身份选择页面
|
||||
uni.switchTab({
|
||||
url: '/pages/learning/learning'
|
||||
})
|
||||
}
|
||||
}, 300)
|
||||
})
|
||||
|
||||
// 生成随机点样式
|
||||
const getDotStyle = (index) => {
|
||||
const size = Math.random() * 6 + 2
|
||||
return {
|
||||
width: `${size}px`,
|
||||
height: `${size}px`,
|
||||
left: `${Math.random() * 100}%`,
|
||||
top: `${Math.random() * 100}%`,
|
||||
opacity: Math.random() * 0.5 + 0.3,
|
||||
animationDelay: `${index * 0.1}s`
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
.tech-welcome-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, #0a0e21 0%, #121a3a 100%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* 科技风背景元素 */
|
||||
.tech-background {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.tech-circle {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
background: radial-gradient(circle, rgba(0, 240, 255, 0.05), transparent 70%);
|
||||
|
||||
&.circle-1 {
|
||||
width: 600rpx;
|
||||
height: 600rpx;
|
||||
top: -300rpx;
|
||||
right: -300rpx;
|
||||
}
|
||||
|
||||
&.circle-2 {
|
||||
width: 500rpx;
|
||||
height: 500rpx;
|
||||
bottom: -250rpx;
|
||||
left: -250rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.tech-line {
|
||||
position: absolute;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, transparent, rgba(0, 240, 255, 0.2), transparent);
|
||||
|
||||
&.line-1 {
|
||||
top: 30%;
|
||||
left: -100px;
|
||||
right: -100px;
|
||||
transform: rotate(-5deg);
|
||||
}
|
||||
|
||||
&.line-2 {
|
||||
top: 60%;
|
||||
left: -100px;
|
||||
right: -100px;
|
||||
transform: rotate(5deg);
|
||||
}
|
||||
}
|
||||
|
||||
.tech-dots {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.dot {
|
||||
position: absolute;
|
||||
background-color: #00f0ff;
|
||||
border-radius: 50%;
|
||||
animation: float 3s infinite ease-in-out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.welcome-content {
|
||||
position: relative;
|
||||
width: 80%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* 科技感标题 */
|
||||
.tech-title {
|
||||
text-align: center;
|
||||
margin-bottom: 80rpx;
|
||||
|
||||
.title-text {
|
||||
display: block;
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
letter-spacing: 2rpx;
|
||||
|
||||
&.highlight {
|
||||
background: linear-gradient(to right, #00f0ff, #0088ff);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
margin-top: 20rpx;
|
||||
font-size: 56rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 科技风进度条 */
|
||||
.tech-progress {
|
||||
width: 100%;
|
||||
margin-top: 60rpx;
|
||||
|
||||
.progress-bar {
|
||||
height: 8rpx;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 4rpx;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(90deg, transparent, rgba(0, 240, 255, 0.3), transparent);
|
||||
animation: shine 2s infinite;
|
||||
}
|
||||
}
|
||||
|
||||
.progress-fill {
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, #00f0ff, #0088ff);
|
||||
border-radius: 4rpx;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
.progress-text {
|
||||
display: block;
|
||||
text-align: center;
|
||||
margin-top: 20rpx;
|
||||
font-size: 28rpx;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
}
|
||||
|
||||
/* 底部装饰 */
|
||||
.tech-footer {
|
||||
position: absolute;
|
||||
bottom: 60rpx;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.footer-line {
|
||||
width: 100px;
|
||||
height: 2px;
|
||||
background: linear-gradient(90deg, transparent, #00f0ff, transparent);
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.footer-text {
|
||||
font-size: 24rpx;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 动画效果 */
|
||||
@keyframes float {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-10px); }
|
||||
}
|
||||
|
||||
@keyframes shine {
|
||||
0% { transform: translateX(-100%); }
|
||||
100% { transform: translateX(100%); }
|
||||
}
|
||||
</style>
|
@ -0,0 +1,285 @@
|
||||
<template>
|
||||
<view class="tech-container">
|
||||
<!-- 科技风背景装饰 -->
|
||||
<view class="tech-bg">
|
||||
<view class="tech-line line-1"></view>
|
||||
<view class="tech-line line-2"></view>
|
||||
<view class="tech-dot dot-1"></view>
|
||||
<view class="tech-dot dot-2"></view>
|
||||
</view>
|
||||
|
||||
<!-- 功能导航入口 -->
|
||||
<view class="nav-grid">
|
||||
<view
|
||||
v-for="(item, index) in navItems"
|
||||
:key="index"
|
||||
class="nav-item"
|
||||
@click="navigateTo(item.page)"
|
||||
>
|
||||
<view class="nav-icon" :style="{ background: item.bgColor }">
|
||||
<!-- 使用uni-icons或图片作为图标 -->
|
||||
<image v-if="item.icon.includes('.png')" :src="item.icon" mode="aspectFit" style="width: 32rpx; height: 32rpx;"/>
|
||||
<uni-icons v-else :type="item.icon" size="40" color="#fff"></uni-icons>
|
||||
</view>
|
||||
<text class="nav-text">{{ item.name }}</text>
|
||||
<text class="nav-action">立即进入</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 我的课程 -->
|
||||
<view class="my-course">
|
||||
<view class="section-header">
|
||||
<text class="section-title">我的课程 (1)</text>
|
||||
<text class="section-more">查看全部 </text>
|
||||
</view>
|
||||
|
||||
<view class="course-card">
|
||||
<image class="course-cover" src="/static/student-course/bg.png" mode="aspectFill"></image>
|
||||
<view class="course-info">
|
||||
<text class="course-name">军事理论</text>
|
||||
<text class="course-subtitle">军事理论-综合版</text>
|
||||
<view class="progress-bar">
|
||||
<view class="progress-active" style="width: 100%"></view>
|
||||
</view>
|
||||
<text class="progress-text">已完成 100%</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
// 导航项数据
|
||||
const navItems = ref([
|
||||
{
|
||||
name: '讨论',
|
||||
icon: '/static/student-course/discussion.png', // 确保图片路径正确
|
||||
page: '/pages/discussion/discussion'
|
||||
},
|
||||
{
|
||||
name: '签到',
|
||||
icon: '/static/student-course/checkin.png',
|
||||
page: '/pages/checkin/checkin'
|
||||
},
|
||||
{
|
||||
name: '答题',
|
||||
icon: '/static/student-course/quiz.png',
|
||||
page: '/pages/quiz_outclass/selectquestion'
|
||||
},
|
||||
{
|
||||
name: '考试',
|
||||
icon: '/static/student-course/exam.png',
|
||||
page: '/pages_A/exam/selectexam'
|
||||
},
|
||||
{
|
||||
name: '扫码',
|
||||
icon: '/static/student-course/scan.png',
|
||||
page: 'scan'
|
||||
}
|
||||
])
|
||||
|
||||
// 导航到子页面
|
||||
const navigateTo = (url) => {
|
||||
if(url === 'scan') {
|
||||
uni.scanCode({
|
||||
success: function (res) {
|
||||
console.log('条码类型:' + res.scanType);
|
||||
console.log('条码内容:' + res.result);
|
||||
console.log('/pages/shangke/shangke?uuid='+JSON.parse(res.result).uuid+'&kch='+JSON.parse(res.result).kch+'&kctime='+JSON.parse(res.result).kctime)
|
||||
uni.navigateTo({
|
||||
url: '/pages/shangke/shangke?uuid='+JSON.parse(res.result).uuid+'&kch='+JSON.parse(res.result).kch+'&kctime='+JSON.parse(res.result).kctime
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: url
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.tech-container {
|
||||
position: relative;
|
||||
padding: 30rpx;
|
||||
background-color: #0a0e21;
|
||||
color: #fff;
|
||||
min-height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 科技风背景 */
|
||||
.tech-bg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: -1;
|
||||
overflow: hidden;
|
||||
|
||||
.tech-line {
|
||||
position: absolute;
|
||||
height: 1rpx;
|
||||
background: linear-gradient(90deg, transparent, rgba(0, 240, 255, 0.2), transparent);
|
||||
|
||||
&.line-1 {
|
||||
top: 30%;
|
||||
left: -100rpx;
|
||||
right: -100rpx;
|
||||
transform: rotate(-5deg);
|
||||
}
|
||||
|
||||
&.line-2 {
|
||||
top: 60%;
|
||||
left: -100rpx;
|
||||
right: -100rpx;
|
||||
transform: rotate(5deg);
|
||||
}
|
||||
}
|
||||
|
||||
.tech-dot {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
background-color: rgba(0, 240, 255, 0.05);
|
||||
|
||||
&.dot-1 {
|
||||
width: 400rpx;
|
||||
height: 400rpx;
|
||||
top: -200rpx;
|
||||
right: -200rpx;
|
||||
}
|
||||
|
||||
&.dot-2 {
|
||||
width: 300rpx;
|
||||
height: 300rpx;
|
||||
bottom: -150rpx;
|
||||
left: -150rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 导航网格 */
|
||||
.nav-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 40rpx;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.nav-item {
|
||||
position: relative;
|
||||
background-color: rgba(20, 30, 50, 0.6);
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx;
|
||||
border: 1rpx solid rgba(0, 240, 255, 0.1);
|
||||
overflow: hidden;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
}
|
||||
|
||||
.nav-icon {
|
||||
width: 75rpx;
|
||||
height: 75rpx;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 20rpx;
|
||||
box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.nav-text {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.nav-action {
|
||||
font-size: 24rpx;
|
||||
color: #00f0ff;
|
||||
}
|
||||
}
|
||||
|
||||
/* 我的课程 */
|
||||
.my-course {
|
||||
background-color: rgba(20, 30, 50, 0.6);
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
border: 1rpx solid rgba(0, 240, 255, 0.1);
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.section-more {
|
||||
font-size: 24rpx;
|
||||
color: #00f0ff;
|
||||
}
|
||||
}
|
||||
|
||||
.course-card {
|
||||
display: flex;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 12rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.course-cover {
|
||||
width: 200rpx;
|
||||
height: 150rpx;
|
||||
}
|
||||
|
||||
.course-info {
|
||||
flex: 1;
|
||||
padding: 20rpx;
|
||||
|
||||
.course-name {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
|
||||
.course-subtitle {
|
||||
font-size: 24rpx;
|
||||
color: #aaa;
|
||||
display: block;
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
height: 8rpx;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 4rpx;
|
||||
margin-bottom: 10rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.progress-active {
|
||||
height: 100%;
|
||||
background: linear-gradient(to right, #00f0ff, #0088ff);
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.progress-text {
|
||||
font-size: 22rpx;
|
||||
color: #00f0ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<text class="title">请假</text>
|
||||
<!-- 页面内容 -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue'
|
||||
|
||||
// 这里可以添加页面逻辑
|
||||
const pageTitle = ref('请假')
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 18px;
|
||||
color: #333;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view>课程列表</view>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
@ -0,0 +1,134 @@
|
||||
<template>
|
||||
<view class="tech-container">
|
||||
<!-- 科技风格头部 -->
|
||||
<view class="tech-header">
|
||||
<view class="header-content">
|
||||
<text class="header-title">课程管理中心</text>
|
||||
<view class="header-subtitle">Course Management System</view>
|
||||
</view>
|
||||
<view class="header-decoration"></view>
|
||||
</view>
|
||||
|
||||
<!-- 内容区域 -->
|
||||
<view class="content-wrapper">
|
||||
<!-- 导航卡片 -->
|
||||
<view class="nav-grid">
|
||||
<TechCard
|
||||
v-for="(item, index) in navItems"
|
||||
:key="index"
|
||||
:title="item.title"
|
||||
:icon="item.icon"
|
||||
:active="activeIndex === index"
|
||||
@click="switchTab(index)"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 修改后的子页面容器 -->
|
||||
<view class="page-container">
|
||||
<LeavePage v-if="activeIndex === 0" />
|
||||
<ProgramPage v-if="activeIndex === 1" />
|
||||
<TranscriptPage v-if="activeIndex === 2" />
|
||||
<SelectionPage v-if="activeIndex === 3" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import TechCard from '@/components/managemet/TechCard.vue'
|
||||
import LeavePage from './leave.vue'
|
||||
import ProgramPage from './program.vue'
|
||||
import TranscriptPage from './transcript.vue'
|
||||
import SelectionPage from './selection.vue'
|
||||
|
||||
// 导航项数据
|
||||
const navItems = ref([
|
||||
{ title: '请假申请', icon: 'calendar-remove' },
|
||||
{ title: '培养方案', icon: 'book' },
|
||||
{ title: '成绩单', icon: 'document-text' },
|
||||
{ title: '选课中心', icon: 'checkmark-circle' }
|
||||
])
|
||||
|
||||
const activeIndex = ref(0)
|
||||
|
||||
// 切换标签页
|
||||
const switchTab = (index) => {
|
||||
activeIndex.value = index
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tech-container {
|
||||
min-height: 100vh;
|
||||
background: #0a0e17;
|
||||
color: #fff;
|
||||
font-family: 'PingFang SC', 'Helvetica Neue', sans-serif;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tech-header {
|
||||
position: relative;
|
||||
padding: 40rpx 30rpx 60rpx;
|
||||
background: linear-gradient(135deg, #1a2a3a 0%, #0a0e17 100%);
|
||||
z-index: 1;
|
||||
overflow: hidden;
|
||||
|
||||
.header-content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
.header-title {
|
||||
font-size: 42rpx;
|
||||
font-weight: 600;
|
||||
letter-spacing: 1rpx;
|
||||
background: linear-gradient(to right, #00f2fe, #4facfe);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.header-subtitle {
|
||||
font-size: 24rpx;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
margin-top: 10rpx;
|
||||
letter-spacing: 1rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.header-decoration {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
background: radial-gradient(circle, rgba(74, 144, 226, 0.2) 0%, transparent 70%);
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.content-wrapper {
|
||||
padding: 0 20rpx 40rpx;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
margin-top: -30rpx;
|
||||
}
|
||||
|
||||
.nav-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 20rpx;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.page-container {
|
||||
background: rgba(16, 24, 40, 0.8);
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx;
|
||||
min-height: 600rpx;
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid rgba(74, 144, 226, 0.2);
|
||||
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
</style>
|
@ -0,0 +1,289 @@
|
||||
<template>
|
||||
<view class="program-page">
|
||||
<!-- 基本信息 -->
|
||||
<view class="info-section">
|
||||
<view class="section-title">
|
||||
<text class="title-text">培养方案</text>
|
||||
<view class="title-decoration"></view>
|
||||
</view>
|
||||
|
||||
<view class="info-grid">
|
||||
<view class="info-item">
|
||||
<uni-icons type="medal" size="20" color="#4facfe"></uni-icons>
|
||||
<text class="info-label">专业名称</text>
|
||||
<text class="info-value">计算机科学与技术</text>
|
||||
</view>
|
||||
|
||||
<view class="info-item">
|
||||
<uni-icons type="flag" size="20" color="#4facfe"></uni-icons>
|
||||
<text class="info-label">培养层次</text>
|
||||
<text class="info-value">本科</text>
|
||||
</view>
|
||||
|
||||
<view class="info-item">
|
||||
<uni-icons type="calendar" size="20" color="#4facfe"></uni-icons>
|
||||
<text class="info-label">学制</text>
|
||||
<text class="info-value">4年</text>
|
||||
</view>
|
||||
|
||||
<view class="info-item">
|
||||
<uni-icons type="star" size="20" color="#4facfe"></uni-icons>
|
||||
<text class="info-label">毕业学分</text>
|
||||
<text class="info-value">160学分</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 课程体系 -->
|
||||
<view class="course-section">
|
||||
<view class="section-title">
|
||||
<text class="title-text">课程体系</text>
|
||||
<view class="title-decoration"></view>
|
||||
</view>
|
||||
|
||||
<uni-collapse>
|
||||
<uni-collapse-item
|
||||
v-for="(item, index) in courseSystem"
|
||||
:key="index"
|
||||
:title="item.name"
|
||||
:show-animation="true"
|
||||
:border="false"
|
||||
>
|
||||
<view class="course-list">
|
||||
<view
|
||||
v-for="(course, cIndex) in item.courses"
|
||||
:key="cIndex"
|
||||
class="course-item"
|
||||
>
|
||||
<text class="course-name">{{ course.name }}</text>
|
||||
<view class="course-meta">
|
||||
<text class="course-credit">{{ course.credit }}学分</text>
|
||||
<text class="course-type">{{ course.type }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-collapse-item>
|
||||
</uni-collapse>
|
||||
</view>
|
||||
|
||||
<!-- 学分进度 -->
|
||||
<view class="progress-section">
|
||||
<view class="section-title">
|
||||
<text class="title-text">学分进度</text>
|
||||
<view class="title-decoration"></view>
|
||||
</view>
|
||||
|
||||
<view class="progress-list">
|
||||
<view
|
||||
v-for="(item, index) in creditProgress"
|
||||
:key="index"
|
||||
class="progress-item"
|
||||
>
|
||||
<view class="progress-header">
|
||||
<text class="category">{{ item.category }}</text>
|
||||
<text class="value">{{ item.completed }}/{{ item.total }}学分</text>
|
||||
</view>
|
||||
<TechProgress :percent="item.percent" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import TechProgress from '@/components/managemet/TechProgress.vue'
|
||||
|
||||
const courseSystem = ref([
|
||||
{
|
||||
name: '通识教育课程',
|
||||
courses: [
|
||||
{ name: '大学英语', credit: 8, type: '必修' },
|
||||
{ name: '高等数学', credit: 10, type: '必修' },
|
||||
{ name: '大学物理', credit: 6, type: '必修' },
|
||||
{ name: '思想政治理论', credit: 12, type: '必修' },
|
||||
{ name: '人文艺术选修', credit: 4, type: '选修' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '专业基础课程',
|
||||
courses: [
|
||||
{ name: '程序设计基础', credit: 4, type: '必修' },
|
||||
{ name: '数据结构', credit: 4, type: '必修' },
|
||||
{ name: '计算机组成原理', credit: 4, type: '必修' },
|
||||
{ name: '操作系统', credit: 4, type: '必修' },
|
||||
{ name: '离散数学', credit: 3, type: '必修' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '专业核心课程',
|
||||
courses: [
|
||||
{ name: '算法设计与分析', credit: 4, type: '必修' },
|
||||
{ name: '计算机网络', credit: 4, type: '必修' },
|
||||
{ name: '数据库系统', credit: 4, type: '必修' },
|
||||
{ name: '软件工程', credit: 4, type: '必修' },
|
||||
{ name: '人工智能基础', credit: 3, type: '选修' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '实践环节',
|
||||
courses: [
|
||||
{ name: '课程设计', credit: 6, type: '必修' },
|
||||
{ name: '毕业实习', credit: 4, type: '必修' },
|
||||
{ name: '毕业论文', credit: 8, type: '必修' },
|
||||
{ name: '创新创业实践', credit: 2, type: '选修' }
|
||||
]
|
||||
}
|
||||
])
|
||||
|
||||
const creditProgress = ref([
|
||||
{ category: '通识教育', completed: 32, total: 40, percent: 80 },
|
||||
{ category: '专业基础', completed: 15, total: 20, percent: 75 },
|
||||
{ category: '专业核心', completed: 8, total: 16, percent: 50 },
|
||||
{ category: '实践环节', completed: 4, total: 20, percent: 20 }
|
||||
])
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.program-page {
|
||||
.section-title {
|
||||
margin-bottom: 30rpx;
|
||||
position: relative;
|
||||
|
||||
.title-text {
|
||||
font-size: 32rpx;
|
||||
color: #4facfe;
|
||||
font-weight: 600;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding-right: 20rpx;
|
||||
background: linear-gradient(to right, #00f2fe, #4facfe);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.title-decoration {
|
||||
position: absolute;
|
||||
bottom: -10rpx;
|
||||
left: 0;
|
||||
width: 60rpx;
|
||||
height: 4rpx;
|
||||
background: linear-gradient(to right, #00f2fe, #4facfe);
|
||||
border-radius: 2rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.info-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 20rpx;
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
.info-item {
|
||||
background: rgba(16, 24, 40, 0.8);
|
||||
border-radius: 12rpx;
|
||||
padding: 25rpx;
|
||||
border: 1rpx solid rgba(74, 144, 226, 0.3);
|
||||
|
||||
.info-label {
|
||||
display: block;
|
||||
font-size: 24rpx;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
margin: 10rpx 0 5rpx;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.course-section {
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
:deep(.uni-collapse) {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
:deep(.uni-collapse-item__title) {
|
||||
background: rgba(16, 24, 40, 0.8);
|
||||
color: #fff;
|
||||
border-radius: 12rpx;
|
||||
margin-bottom: 10rpx;
|
||||
border: 1rpx solid rgba(74, 144, 226, 0.3);
|
||||
padding: 20rpx 25rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-collapse-item__wrap) {
|
||||
background: rgba(16, 24, 40, 0.6);
|
||||
border: none;
|
||||
border-radius: 0 0 12rpx 12rpx;
|
||||
}
|
||||
|
||||
.course-list {
|
||||
padding: 0 25rpx 20rpx;
|
||||
|
||||
.course-item {
|
||||
padding: 20rpx 0;
|
||||
border-bottom: 1rpx solid rgba(74, 144, 226, 0.1);
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.course-name {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.course-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.course-credit {
|
||||
font-size: 24rpx;
|
||||
color: #4facfe;
|
||||
}
|
||||
|
||||
.course-type {
|
||||
font-size: 24rpx;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.progress-list {
|
||||
.progress-item {
|
||||
background: rgba(16, 24, 40, 0.8);
|
||||
border-radius: 12rpx;
|
||||
padding: 25rpx;
|
||||
margin-bottom: 20rpx;
|
||||
border: 1rpx solid rgba(74, 144, 226, 0.3);
|
||||
|
||||
.progress-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 15rpx;
|
||||
|
||||
.category {
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 26rpx;
|
||||
color: #4facfe;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,614 @@
|
||||
<template>
|
||||
<view class="selection-page">
|
||||
<!-- 头部信息 -->
|
||||
<view class="header-section">
|
||||
<view class="header-content">
|
||||
<text class="title">选课中心</text>
|
||||
<text class="subtitle">Course Selection System</text>
|
||||
</view>
|
||||
<view class="header-decoration"></view>
|
||||
</view>
|
||||
|
||||
<!-- 选课状态卡片 -->
|
||||
<view class="status-cards">
|
||||
<view class="status-card">
|
||||
<view class="card-content">
|
||||
<text class="card-label">可选学分</text>
|
||||
<text class="card-value">{{ availableCredits }}</text>
|
||||
<text class="card-unit">学分</text>
|
||||
</view>
|
||||
<view class="card-decoration"></view>
|
||||
</view>
|
||||
|
||||
<view class="status-card">
|
||||
<view class="card-content">
|
||||
<text class="card-label">已选学分</text>
|
||||
<text class="card-value">{{ selectedCredits }}</text>
|
||||
<text class="card-unit">学分</text>
|
||||
</view>
|
||||
<view class="card-decoration"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 选课进度 -->
|
||||
<view class="progress-section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">选课进度</text>
|
||||
<view class="section-decoration"></view>
|
||||
</view>
|
||||
<TechProgress :percent="selectionProgress" />
|
||||
</view>
|
||||
|
||||
<!-- 课程筛选 -->
|
||||
<view class="filter-section">
|
||||
<view class="filter-tabs">
|
||||
<view
|
||||
v-for="(tab, index) in tabs"
|
||||
:key="index"
|
||||
class="filter-tab"
|
||||
:class="{ active: activeTab === index }"
|
||||
@click="changeTab(index)"
|
||||
>
|
||||
<text>{{ tab }}</text>
|
||||
<view class="tab-indicator"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="filter-options">
|
||||
<picker
|
||||
mode="selector"
|
||||
:range="semesters"
|
||||
@change="handleSemesterChange"
|
||||
>
|
||||
<view class="filter-option">
|
||||
<text>{{ currentSemester || '选择学期' }}</text>
|
||||
<uni-icons type="arrowdown" size="16" color="#4facfe"></uni-icons>
|
||||
</view>
|
||||
</picker>
|
||||
|
||||
<picker
|
||||
mode="selector"
|
||||
:range="categories"
|
||||
range-key="name"
|
||||
@change="handleCategoryChange"
|
||||
>
|
||||
<view class="filter-option">
|
||||
<text>{{ currentCategory.name || '课程类别' }}</text>
|
||||
<uni-icons type="arrowdown" size="16" color="#4facfe"></uni-icons>
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 课程列表 -->
|
||||
<view class="course-list">
|
||||
<view
|
||||
v-for="(course, index) in filteredCourses"
|
||||
:key="index"
|
||||
class="course-card"
|
||||
>
|
||||
<view class="course-header">
|
||||
<text class="course-name">{{ course.name }}</text>
|
||||
<text class="course-credit">{{ course.credit }}学分</text>
|
||||
</view>
|
||||
|
||||
<view class="course-meta">
|
||||
<view class="meta-item">
|
||||
<uni-icons type="person" size="16" color="rgba(255,255,255,0.6)"></uni-icons>
|
||||
<text>{{ course.teacher }}</text>
|
||||
</view>
|
||||
<view class="meta-item">
|
||||
<uni-icons type="calendar" size="16" color="rgba(255,255,255,0.6)"></uni-icons>
|
||||
<text>{{ course.time }}</text>
|
||||
</view>
|
||||
<view class="meta-item">
|
||||
<uni-icons type="location" size="16" color="rgba(255,255,255,0.6)"></uni-icons>
|
||||
<text>{{ course.location }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="course-footer">
|
||||
<text class="remaining">剩余名额: {{ course.remaining }}/{{ course.capacity }}</text>
|
||||
|
||||
<TechButton
|
||||
size="small"
|
||||
:type="course.selected ? 'secondary' : 'primary'"
|
||||
@click="toggleSelection(course)"
|
||||
>
|
||||
{{ course.selected ? '已选' : '选课' }}
|
||||
</TechButton>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<view class="action-bar">
|
||||
<view class="selected-info">
|
||||
<text>已选 {{ selectedCount }} 门课程</text>
|
||||
<text>{{ selectedCredits }}学分</text>
|
||||
</view>
|
||||
<TechButton @click="handleSubmit">提交选课</TechButton>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import TechProgress from '@/components/managemet/TechProgress.vue'
|
||||
import TechButton from '@/components/managemet/TechButton.vue'
|
||||
|
||||
// 选课状态数据
|
||||
const availableCredits = ref(25)
|
||||
const selectedCredits = ref(0)
|
||||
const selectedCount = ref(0)
|
||||
|
||||
// 筛选相关数据
|
||||
const tabs = ref(['全部课程', '专业选修', '公共选修', '通识教育'])
|
||||
const activeTab = ref(0)
|
||||
const semesters = ref(['2023-2024学年 第一学期', '2022-2023学年 第二学期', '2022-2023学年 第一学期'])
|
||||
const currentSemester = ref('2023-2024学年 第一学期')
|
||||
const categories = ref([
|
||||
{ id: 1, name: '全部类别' },
|
||||
{ id: 2, name: '人文社科' },
|
||||
{ id: 3, name: '自然科学' },
|
||||
{ id: 4, name: '工程技术' },
|
||||
{ id: 5, name: '艺术体育' }
|
||||
])
|
||||
const currentCategory = ref({})
|
||||
|
||||
// 课程数据
|
||||
const courses = ref([
|
||||
{
|
||||
id: 1,
|
||||
name: '人工智能基础',
|
||||
credit: 3,
|
||||
teacher: '张教授',
|
||||
time: '周一 3-4节',
|
||||
location: '信息楼201',
|
||||
remaining: 15,
|
||||
capacity: 60,
|
||||
category: '工程技术',
|
||||
type: '专业选修',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '数据可视化',
|
||||
credit: 2,
|
||||
teacher: '李副教授',
|
||||
time: '周三 5-6节',
|
||||
location: '计算机中心305',
|
||||
remaining: 8,
|
||||
capacity: 40,
|
||||
category: '工程技术',
|
||||
type: '专业选修',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '西方艺术史',
|
||||
credit: 2,
|
||||
teacher: '王教授',
|
||||
time: '周二 7-8节',
|
||||
location: '人文楼101',
|
||||
remaining: 5,
|
||||
capacity: 80,
|
||||
category: '人文社科',
|
||||
type: '公共选修',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: '环境科学导论',
|
||||
credit: 2,
|
||||
teacher: '赵教授',
|
||||
time: '周四 1-2节',
|
||||
location: '理学院203',
|
||||
remaining: 12,
|
||||
capacity: 100,
|
||||
category: '自然科学',
|
||||
type: '通识教育',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: '羽毛球',
|
||||
credit: 1,
|
||||
teacher: '陈老师',
|
||||
time: '周五 5-6节',
|
||||
location: '体育馆A',
|
||||
remaining: 3,
|
||||
capacity: 30,
|
||||
category: '艺术体育',
|
||||
type: '公共选修',
|
||||
selected: false
|
||||
}
|
||||
])
|
||||
|
||||
// 计算属性
|
||||
const selectionProgress = computed(() => {
|
||||
return Math.round((selectedCredits.value / availableCredits.value) * 100)
|
||||
})
|
||||
|
||||
const filteredCourses = computed(() => {
|
||||
let result = [...courses.value]
|
||||
|
||||
// 按标签筛选
|
||||
if (activeTab.value > 0) {
|
||||
result = result.filter(course => course.type === tabs.value[activeTab.value])
|
||||
}
|
||||
|
||||
// 按类别筛选
|
||||
if (currentCategory.value.id > 1) {
|
||||
result = result.filter(course => course.category === currentCategory.value.name)
|
||||
}
|
||||
|
||||
return result
|
||||
})
|
||||
|
||||
// 方法
|
||||
const changeTab = (index) => {
|
||||
activeTab.value = index
|
||||
}
|
||||
|
||||
const handleSemesterChange = (e) => {
|
||||
currentSemester.value = semesters.value[e.detail.value]
|
||||
}
|
||||
|
||||
const handleCategoryChange = (e) => {
|
||||
currentCategory.value = categories.value[e.detail.value]
|
||||
}
|
||||
|
||||
const toggleSelection = (course) => {
|
||||
if (course.selected) {
|
||||
// 取消选课
|
||||
course.selected = false
|
||||
selectedCredits.value -= course.credit
|
||||
selectedCount.value--
|
||||
course.remaining++
|
||||
} else {
|
||||
// 检查学分是否足够
|
||||
if (selectedCredits.value + course.credit > availableCredits.value) {
|
||||
uni.showToast({
|
||||
title: '已超过可选学分限制',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否还有名额
|
||||
if (course.remaining <= 0) {
|
||||
uni.showToast({
|
||||
title: '该课程已无剩余名额',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 选课
|
||||
course.selected = true
|
||||
selectedCredits.value += course.credit
|
||||
selectedCount.value++
|
||||
course.remaining--
|
||||
|
||||
uni.showToast({
|
||||
title: '选课成功',
|
||||
icon: 'success'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmit = () => {
|
||||
if (selectedCount.value === 0) {
|
||||
uni.showToast({
|
||||
title: '请至少选择一门课程',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
uni.showLoading({ title: '提交中...' })
|
||||
|
||||
// 模拟API请求
|
||||
setTimeout(() => {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: '选课提交成功',
|
||||
icon: 'success'
|
||||
})
|
||||
|
||||
// 重置选课状态
|
||||
courses.value.forEach(course => {
|
||||
if (course.selected) {
|
||||
course.capacity--
|
||||
course.selected = false
|
||||
}
|
||||
})
|
||||
|
||||
selectedCredits.value = 0
|
||||
selectedCount.value = 0
|
||||
}, 1500)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.selection-page {
|
||||
padding-bottom: 120rpx;
|
||||
background: linear-gradient(to bottom, #0a0e17 0%, #1a2a3a 100%);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.header-section {
|
||||
position: relative;
|
||||
padding: 40rpx 30rpx 30rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.header-content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
.title {
|
||||
font-size: 42rpx;
|
||||
font-weight: 600;
|
||||
background: linear-gradient(to right, #00f2fe, #4facfe);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 24rpx;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.header-decoration {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
background: radial-gradient(circle, rgba(74, 144, 226, 0.2) 0%, transparent 70%);
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.status-cards {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
padding: 0 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.status-card {
|
||||
flex: 1;
|
||||
background: rgba(16, 24, 40, 0.8);
|
||||
border-radius: 16rpx;
|
||||
padding: 25rpx;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border: 1rpx solid rgba(74, 144, 226, 0.3);
|
||||
|
||||
.card-content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
.card-label {
|
||||
font-size: 26rpx;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.card-value {
|
||||
font-size: 40rpx;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
display: block;
|
||||
background: linear-gradient(to right, #00f2fe, #4facfe);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.card-unit {
|
||||
font-size: 24rpx;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
.card-decoration {
|
||||
position: absolute;
|
||||
bottom: -20rpx;
|
||||
right: -20rpx;
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
background: radial-gradient(circle, rgba(74, 144, 226, 0.2) 0%, transparent 70%);
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.progress-section {
|
||||
padding: 0 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.section-header {
|
||||
margin-bottom: 20rpx;
|
||||
position: relative;
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
color: #4facfe;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding-right: 20rpx;
|
||||
}
|
||||
|
||||
.section-decoration {
|
||||
position: absolute;
|
||||
bottom: -8rpx;
|
||||
left: 0;
|
||||
width: 60rpx;
|
||||
height: 4rpx;
|
||||
background: linear-gradient(to right, #00f2fe, #4facfe);
|
||||
border-radius: 2rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.filter-section {
|
||||
padding: 0 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.filter-tabs {
|
||||
display: flex;
|
||||
margin-bottom: 25rpx;
|
||||
border-bottom: 1rpx solid rgba(74, 144, 226, 0.2);
|
||||
|
||||
.filter-tab {
|
||||
padding: 15rpx 25rpx;
|
||||
position: relative;
|
||||
|
||||
text {
|
||||
font-size: 28rpx;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
.tab-indicator {
|
||||
position: absolute;
|
||||
bottom: -1rpx;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 0;
|
||||
height: 4rpx;
|
||||
background: linear-gradient(to right, #00f2fe, #4facfe);
|
||||
border-radius: 2rpx;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
&.active {
|
||||
text {
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.tab-indicator {
|
||||
width: 60rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.filter-options {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
|
||||
.filter-option {
|
||||
flex: 1;
|
||||
height: 70rpx;
|
||||
line-height: 70rpx;
|
||||
padding: 0 25rpx;
|
||||
background: rgba(16, 24, 40, 0.8);
|
||||
border-radius: 12rpx;
|
||||
border: 1rpx solid rgba(74, 144, 226, 0.3);
|
||||
color: #fff;
|
||||
font-size: 26rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.course-list {
|
||||
padding: 0 30rpx;
|
||||
|
||||
.course-card {
|
||||
background: rgba(16, 24, 40, 0.8);
|
||||
border-radius: 16rpx;
|
||||
padding: 25rpx;
|
||||
margin-bottom: 20rpx;
|
||||
border: 1rpx solid rgba(74, 144, 226, 0.3);
|
||||
|
||||
.course-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
.course-name {
|
||||
font-size: 30rpx;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.course-credit {
|
||||
font-size: 26rpx;
|
||||
color: #4facfe;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.course-meta {
|
||||
margin-bottom: 25rpx;
|
||||
|
||||
.meta-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
margin-bottom: 15rpx;
|
||||
|
||||
text {
|
||||
font-size: 26rpx;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.course-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.remaining {
|
||||
font-size: 24rpx;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.action-bar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 100rpx;
|
||||
background: rgba(16, 24, 40, 0.95);
|
||||
backdrop-filter: blur(10px);
|
||||
border-top: 1rpx solid rgba(74, 144, 226, 0.3);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 30rpx;
|
||||
|
||||
.selected-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
text {
|
||||
font-size: 26rpx;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
|
||||
&:last-child {
|
||||
font-size: 24rpx;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.tech-button) {
|
||||
width: 200rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,450 @@
|
||||
<template>
|
||||
<view class="transcript-page">
|
||||
<!-- 头部信息 -->
|
||||
<view class="header-section">
|
||||
<view class="header-content">
|
||||
<text class="title">成绩单</text>
|
||||
<text class="subtitle">Academic Transcript</text>
|
||||
</view>
|
||||
<view class="header-decoration"></view>
|
||||
</view>
|
||||
|
||||
<!-- 学期选择器 -->
|
||||
<view class="semester-selector">
|
||||
<picker
|
||||
mode="selector"
|
||||
:range="semesters"
|
||||
range-key="name"
|
||||
@change="handleSemesterChange"
|
||||
>
|
||||
<view class="selector-box">
|
||||
<text class="current-semester">{{ currentSemester.name }}</text>
|
||||
<uni-icons type="arrowdown" size="18" color="#4facfe"></uni-icons>
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
|
||||
<!-- GPA统计卡片 -->
|
||||
<view class="stats-grid">
|
||||
<view class="stat-card">
|
||||
<view class="stat-content">
|
||||
<text class="stat-label">学期GPA</text>
|
||||
<text class="stat-value">{{ currentSemester.gpa }}</text>
|
||||
<view class="stat-trend" :class="gpaTrendClass">
|
||||
<uni-icons :type="gpaTrendIcon" size="16" color="currentColor"></uni-icons>
|
||||
<text>{{ gpaTrendText }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="stat-decoration"></view>
|
||||
</view>
|
||||
|
||||
<view class="stat-card">
|
||||
<view class="stat-content">
|
||||
<text class="stat-label">累计GPA</text>
|
||||
<text class="stat-value">{{ cumulativeGPA }}</text>
|
||||
<text class="stat-meta">专业排名 {{ rank }}</text>
|
||||
</view>
|
||||
<view class="stat-decoration"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 成绩列表 -->
|
||||
<view class="grades-section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">课程成绩</text>
|
||||
<view class="section-decoration"></view>
|
||||
</view>
|
||||
|
||||
<view class="grades-list">
|
||||
<view
|
||||
v-for="(course, index) in currentSemester.courses"
|
||||
:key="index"
|
||||
class="grade-item"
|
||||
>
|
||||
<view class="course-info">
|
||||
<text class="course-name">{{ course.name }}</text>
|
||||
<text class="course-credit">{{ course.credit }}学分</text>
|
||||
</view>
|
||||
<view class="grade-score" :class="getScoreClass(course.score)">
|
||||
<text>{{ course.score }}</text>
|
||||
<text class="grade-level">{{ getGradeLevel(course.score) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部操作按钮 -->
|
||||
<view class="action-buttons">
|
||||
<TechButton type="primary" @click="handleDownload">
|
||||
<uni-icons type="download" size="18" color="#fff"></uni-icons>
|
||||
<text>下载成绩单</text>
|
||||
</TechButton>
|
||||
<TechButton type="secondary" @click="handleShare">
|
||||
<uni-icons type="share" size="18" color="#4facfe"></uni-icons>
|
||||
<text>分享成绩</text>
|
||||
</TechButton>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import TechButton from '@/components/managemet/TechButton.vue'
|
||||
|
||||
const semesters = ref([
|
||||
{
|
||||
id: 1,
|
||||
name: '2023-2024学年 第一学期',
|
||||
gpa: '3.82',
|
||||
trend: 'up',
|
||||
courses: [
|
||||
{ name: '人工智能原理', credit: 4, score: 94 },
|
||||
{ name: '机器学习', credit: 4, score: 89 },
|
||||
{ name: '大数据技术', credit: 3, score: 91 },
|
||||
{ name: '计算机视觉', credit: 3, score: 87 },
|
||||
{ name: '自然语言处理', credit: 3, score: 92 }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '2022-2023学年 第二学期',
|
||||
gpa: '3.75',
|
||||
trend: 'up',
|
||||
courses: [
|
||||
{ name: '操作系统', credit: 4, score: 88 },
|
||||
{ name: '计算机网络', credit: 4, score: 85 },
|
||||
{ name: '数据库系统', credit: 4, score: 90 },
|
||||
{ name: '软件工程', credit: 3, score: 87 },
|
||||
{ name: '编译原理', credit: 4, score: 83 }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '2022-2023学年 第一学期',
|
||||
gpa: '3.68',
|
||||
trend: 'down',
|
||||
courses: [
|
||||
{ name: '数据结构', credit: 4, score: 85 },
|
||||
{ name: '算法分析', credit: 4, score: 82 },
|
||||
{ name: '计算机组成', credit: 4, score: 84 },
|
||||
{ name: '离散数学', credit: 3, score: 79 },
|
||||
{ name: '概率统计', credit: 3, score: 88 }
|
||||
]
|
||||
}
|
||||
])
|
||||
|
||||
const currentSemesterIndex = ref(0)
|
||||
const currentSemester = computed(() => semesters.value[currentSemesterIndex.value])
|
||||
const cumulativeGPA = computed(() => '3.75')
|
||||
const rank = computed(() => '8/120')
|
||||
|
||||
// GPA趋势相关计算
|
||||
const gpaTrendIcon = computed(() => {
|
||||
return currentSemester.value.trend === 'up' ? 'arrow-up' : 'arrow-down'
|
||||
})
|
||||
|
||||
const gpaTrendClass = computed(() => {
|
||||
return currentSemester.value.trend === 'up' ? 'trend-up' : 'trend-down'
|
||||
})
|
||||
|
||||
const gpaTrendText = computed(() => {
|
||||
return currentSemester.value.trend === 'up' ? '较上学期提升' : '较上学期下降'
|
||||
})
|
||||
|
||||
// 成绩等级计算
|
||||
const getGradeLevel = (score) => {
|
||||
if (score >= 90) return 'A'
|
||||
if (score >= 80) return 'B'
|
||||
if (score >= 70) return 'C'
|
||||
if (score >= 60) return 'D'
|
||||
return 'F'
|
||||
}
|
||||
|
||||
const getScoreClass = (score) => {
|
||||
if (score >= 90) return 'excellent'
|
||||
if (score >= 80) return 'good'
|
||||
if (score >= 70) return 'average'
|
||||
if (score >= 60) return 'pass'
|
||||
return 'fail'
|
||||
}
|
||||
|
||||
// 事件处理
|
||||
const handleSemesterChange = (e) => {
|
||||
currentSemesterIndex.value = e.detail.value
|
||||
}
|
||||
|
||||
const handleDownload = () => {
|
||||
uni.showLoading({ title: '生成成绩单中...' })
|
||||
setTimeout(() => {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: '成绩单已保存到相册',
|
||||
icon: 'success'
|
||||
})
|
||||
}, 1500)
|
||||
}
|
||||
|
||||
const handleShare = () => {
|
||||
uni.showActionSheet({
|
||||
itemList: ['微信好友', 'QQ好友', '保存图片'],
|
||||
success: (res) => {
|
||||
uni.showToast({
|
||||
title: `已分享到${['微信好友', 'QQ好友', '保存图片'][res.tapIndex]}`,
|
||||
icon: 'success'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.transcript-page {
|
||||
padding-bottom: 40rpx;
|
||||
background: linear-gradient(to bottom, #0a0e17 0%, #1a2a3a 100%);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.header-section {
|
||||
position: relative;
|
||||
padding: 40rpx 30rpx 30rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.header-content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
.title {
|
||||
font-size: 42rpx;
|
||||
font-weight: 600;
|
||||
background: linear-gradient(to right, #00f2fe, #4facfe);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 24rpx;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.header-decoration {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
background: radial-gradient(circle, rgba(74, 144, 226, 0.2) 0%, transparent 70%);
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.semester-selector {
|
||||
padding: 0 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.selector-box {
|
||||
height: 80rpx;
|
||||
background: rgba(16, 24, 40, 0.8);
|
||||
border-radius: 12rpx;
|
||||
border: 1rpx solid rgba(74, 144, 226, 0.3);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 25rpx;
|
||||
|
||||
.current-semester {
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 20rpx;
|
||||
padding: 0 30rpx;
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
.stat-card {
|
||||
background: rgba(16, 24, 40, 0.8);
|
||||
border-radius: 16rpx;
|
||||
padding: 25rpx;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border: 1rpx solid rgba(74, 144, 226, 0.3);
|
||||
|
||||
.stat-content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
.stat-label {
|
||||
font-size: 26rpx;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 40rpx;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
display: block;
|
||||
margin-bottom: 15rpx;
|
||||
background: linear-gradient(to right, #00f2fe, #4facfe);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.stat-trend {
|
||||
font-size: 24rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
|
||||
&.trend-up {
|
||||
color: #00c853;
|
||||
}
|
||||
|
||||
&.trend-down {
|
||||
color: #ff5252;
|
||||
}
|
||||
}
|
||||
|
||||
.stat-meta {
|
||||
font-size: 24rpx;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
.stat-decoration {
|
||||
position: absolute;
|
||||
bottom: -20rpx;
|
||||
right: -20rpx;
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
background: radial-gradient(circle, rgba(74, 144, 226, 0.2) 0%, transparent 70%);
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.grades-section {
|
||||
padding: 0 30rpx;
|
||||
|
||||
.section-header {
|
||||
margin-bottom: 25rpx;
|
||||
position: relative;
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
color: #4facfe;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding-right: 20rpx;
|
||||
}
|
||||
|
||||
.section-decoration {
|
||||
position: absolute;
|
||||
bottom: -8rpx;
|
||||
left: 0;
|
||||
width: 60rpx;
|
||||
height: 4rpx;
|
||||
background: linear-gradient(to right, #00f2fe, #4facfe);
|
||||
border-radius: 2rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.grades-list {
|
||||
.grade-item {
|
||||
background: rgba(16, 24, 40, 0.8);
|
||||
border-radius: 12rpx;
|
||||
padding: 25rpx;
|
||||
margin-bottom: 20rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border: 1rpx solid rgba(74, 144, 226, 0.3);
|
||||
|
||||
.course-info {
|
||||
flex: 1;
|
||||
|
||||
.course-name {
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.course-credit {
|
||||
font-size: 24rpx;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
.grade-score {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-weight: 600;
|
||||
|
||||
&.excellent {
|
||||
background: rgba(0, 200, 83, 0.15);
|
||||
border: 2rpx solid rgba(0, 200, 83, 0.3);
|
||||
color: #00c853;
|
||||
}
|
||||
|
||||
&.good {
|
||||
background: rgba(74, 144, 226, 0.15);
|
||||
border: 2rpx solid rgba(74, 144, 226, 0.3);
|
||||
color: #4facfe;
|
||||
}
|
||||
|
||||
&.average {
|
||||
background: rgba(255, 171, 0, 0.15);
|
||||
border: 2rpx solid rgba(255, 171, 0, 0.3);
|
||||
color: #ffab00;
|
||||
}
|
||||
|
||||
&.pass {
|
||||
background: rgba(255, 82, 82, 0.15);
|
||||
border: 2rpx solid rgba(255, 82, 82, 0.3);
|
||||
color: #ff5252;
|
||||
}
|
||||
|
||||
&.fail {
|
||||
background: rgba(255, 82, 82, 0.3);
|
||||
border: 2rpx solid rgba(255, 82, 82, 0.5);
|
||||
color: #ff5252;
|
||||
}
|
||||
|
||||
.grade-level {
|
||||
font-size: 24rpx;
|
||||
margin-top: 5rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
padding: 0 30rpx;
|
||||
margin-top: 40rpx;
|
||||
|
||||
:deep(.tech-button) {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<text class="title">培养方案</text>
|
||||
<!-- 页面内容 -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue'
|
||||
|
||||
// 这里可以添加页面逻辑
|
||||
const pageTitle = ref('培养方案')
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 18px;
|
||||
color: #333;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<view class="role-select-page">
|
||||
<view class="title">请选择您的身份</view>
|
||||
<view class="role-buttons">
|
||||
<button @click="selectStudent">学生</button>
|
||||
<button @click="selectTeacher">教师</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { uni } from '@dcloudio/uni-app';
|
||||
|
||||
const selectStudent = () => {
|
||||
uni.reLaunch({
|
||||
url: '/pages/Student/learning/learning'
|
||||
});
|
||||
};
|
||||
|
||||
const selectTeacher = () => {
|
||||
uni.reLaunch({
|
||||
url: '/pages/Teacher/teacherCourseManagement/teacherCourseManagement'
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.role-select-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 24px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.role-buttons {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,433 @@
|
||||
<template>
|
||||
<view class="cyber-container">
|
||||
<!-- 霓虹风格顶部栏 -->
|
||||
<view class="cyber-header">
|
||||
<view class="header-glitch" data-text="智能课程表">智能课程表</view>
|
||||
<view class="week-display">
|
||||
<text class="week-label">当前周次</text>
|
||||
<text class="week-value">{{ currentWeek }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 全息投影风格课表 -->
|
||||
<view class="hologram-grid">
|
||||
<!-- 星期表头 -->
|
||||
<view class="grid-header">
|
||||
<view class="time-slot">时间</view>
|
||||
<view
|
||||
v-for="day in weekDays"
|
||||
:key="day.value"
|
||||
class="day-header"
|
||||
:class="{ today: isToday(day.value) }"
|
||||
>
|
||||
{{ day.label }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 课程行 -->
|
||||
<view
|
||||
v-for="(timeSlot, slotIndex) in timeSlots"
|
||||
:key="slotIndex"
|
||||
class="grid-row"
|
||||
>
|
||||
<view class="time-slot">
|
||||
<text class="time">{{ timeSlot }}</text>
|
||||
<text class="slot-num">第{{ slotIndex + 1 }}节</text>
|
||||
</view>
|
||||
|
||||
<!-- <view>测试{{ coursesData.mon[0].name }}</view> -->
|
||||
|
||||
<view
|
||||
v-for="day in weekDays"
|
||||
:key="day.value"
|
||||
class="course-slot"
|
||||
@click="showCourseDetail(day.value, slotIndex)"
|
||||
>
|
||||
<!-- <course-hologram
|
||||
v-if="hasCourse(day.value, slotIndex)"
|
||||
:course="getCourse(day.value, slotIndex)"
|
||||
:active="isCurrentWeekCourse(day.value, slotIndex)"
|
||||
/> -->
|
||||
<course-hologram
|
||||
v-if="hasCourse(day.value, slotIndex)"
|
||||
:course="getCourse(day.value, slotIndex)"
|
||||
:active="isCurrentWeekCourse(day.value, slotIndex)"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 全息弹窗 -->
|
||||
<uni-popup ref="popup" type="dialog">
|
||||
<uni-popup-dialog
|
||||
v-if="currentCourse"
|
||||
:title="currentCourse.name"
|
||||
:message="courseDetail"
|
||||
confirmText="确定"
|
||||
@confirm="closePopup"
|
||||
/>
|
||||
</uni-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import dayjs from 'dayjs'
|
||||
import 'dayjs/locale/zh-cn'
|
||||
// 初始化dayjs中文
|
||||
dayjs.locale('zh-cn')
|
||||
|
||||
// 霓虹颜色方案
|
||||
const COLOR_SCHEME = {
|
||||
math: '#00ff9d',
|
||||
programming: '#00b8ff',
|
||||
english: '#ff2d75',
|
||||
physics: '#ff9d00',
|
||||
default: '#8a2be2'
|
||||
}
|
||||
|
||||
// 星期数据
|
||||
const weekDays = [
|
||||
{ label: '周一', value: 'mon' },
|
||||
{ label: '周二', value: 'tue' },
|
||||
{ label: '周三', value: 'wed' },
|
||||
{ label: '周四', value: 'thu' },
|
||||
{ label: '周五', value: 'fri' },
|
||||
{ label: '周六', value: 'sat' },
|
||||
{ label: '周日', value: 'sun' }
|
||||
]
|
||||
|
||||
// 时间配置
|
||||
const timeSlots = [
|
||||
'08:20-09:05', '09:10-09:55', '10:15-11:00',
|
||||
'11:05-11:50', '14:00-14:45', '14:50-15:35',
|
||||
'15:55-16:40', '16:45-17:30', '18:30-19:15',
|
||||
'19:20-20:05', '20:10-20:55', '21:00-21:45'
|
||||
]
|
||||
|
||||
// 课程数据
|
||||
const coursesData = {
|
||||
mon: [
|
||||
{
|
||||
section: 0,
|
||||
name: '高等数学A(一)',
|
||||
teacher: '李教授',
|
||||
location: 'A101',
|
||||
weeks: '1-16',
|
||||
type: 'math'
|
||||
},
|
||||
{
|
||||
section: 1,
|
||||
name: '高等数学A(一)',
|
||||
teacher: '李教授',
|
||||
location: 'A101',
|
||||
weeks: '1-19',
|
||||
type: 'math'
|
||||
}
|
||||
],
|
||||
tue: [
|
||||
{
|
||||
section: 3,
|
||||
name: '程序设计基础',
|
||||
teacher: '王老师',
|
||||
location: '计科实验室',
|
||||
weeks: '1-12',
|
||||
type: 'programming'
|
||||
}
|
||||
],
|
||||
wed: [
|
||||
{
|
||||
section: 2,
|
||||
name: '大学英语',
|
||||
teacher: '张老师',
|
||||
location: 'C203',
|
||||
weeks: '1-18',
|
||||
type: 'english'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
// 响应式数据
|
||||
const currentWeek = ref(1)
|
||||
const currentCourse = ref(null)
|
||||
const popup = ref(null)
|
||||
|
||||
// 计算属性
|
||||
const courseDetail = computed(() => {
|
||||
if (!currentCourse.value) return ''
|
||||
return `教师: ${currentCourse.value.teacher}\n地点: ${currentCourse.value.location}\n周次: ${currentCourse.value.weeks}周`
|
||||
})
|
||||
|
||||
// 计算当前周次
|
||||
const calculateCurrentWeek = () => {
|
||||
const startDate = dayjs('2025-03-1') // 开学日期
|
||||
const weeks = dayjs().diff(startDate, 'week') + 1
|
||||
currentWeek.value = Math.max(1, Math.min(weeks, 18)) // 限制在1-18周
|
||||
}
|
||||
|
||||
// 判断是否是今天
|
||||
const isToday = (dayValue) => {
|
||||
const dayMap = { mon: 1, tue: 2, wed: 3, thu: 4, fri: 5, sat: 6, sun: 0 }
|
||||
return dayMap[dayValue] === dayjs().day()
|
||||
}
|
||||
|
||||
// 检查某天某节是否有课
|
||||
const hasCourse = (day, section) => {
|
||||
return coursesData[day]?.some(c => c.section === section) ?? false
|
||||
}
|
||||
|
||||
// 获取课程
|
||||
const getCourse = (day, section) => {
|
||||
return coursesData[day]?.find(c => c.section === section) || null
|
||||
}
|
||||
|
||||
// 是否当前周课程
|
||||
const isCurrentWeekCourse = (day, section) => {
|
||||
const course = getCourse(day, section)
|
||||
if (!course) return false
|
||||
|
||||
const weeks = course.weeks
|
||||
if (weeks.includes('-')) {
|
||||
const [start, end] = weeks.split('-').map(Number)
|
||||
return currentWeek.value >= start && currentWeek.value <= end
|
||||
} else if (weeks.includes(',')) {
|
||||
return weeks.split(',').map(Number).includes(currentWeek.value)
|
||||
}
|
||||
return Number(weeks) === currentWeek.value
|
||||
}
|
||||
|
||||
// 显示课程详情
|
||||
const showCourseDetail = (day, section) => {
|
||||
currentCourse.value = getCourse(day, section)
|
||||
if (currentCourse.value) {
|
||||
popup.value.open()
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const closePopup = () => {
|
||||
popup.value.close()
|
||||
}
|
||||
|
||||
// 组件生命周期
|
||||
onMounted(() => {
|
||||
calculateCurrentWeek()
|
||||
})
|
||||
|
||||
//课程卡片组件
|
||||
const CourseHologram = {
|
||||
props: ['course', 'active'],
|
||||
computed: {
|
||||
courseColor() {
|
||||
return COLOR_SCHEME[this.course.type] || COLOR_SCHEME.default
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<view
|
||||
class="hologram-card"
|
||||
:style="{
|
||||
'--hologram-color': courseColor,
|
||||
opacity: active ? 1 : 0.6
|
||||
}"
|
||||
>
|
||||
<text class="course-name">{{ course.name }}</text>
|
||||
<text class="course-location">{{ course.location }}</text>
|
||||
<view class="hologram-effect"></view>
|
||||
</view>
|
||||
`
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.cyber-container {
|
||||
background: #0a0e17;
|
||||
color: #00ff9d;
|
||||
min-height: 100vh;
|
||||
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||
}
|
||||
|
||||
.cyber-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 20rpx 30rpx;
|
||||
background: rgba(0, 20, 40, 0.8);
|
||||
border-bottom: 1px solid rgba(0, 255, 157, 0.3);
|
||||
|
||||
.header-glitch {
|
||||
position: relative;
|
||||
font-size: 44rpx;
|
||||
font-weight: bold;
|
||||
color: #00ff9d;
|
||||
text-shadow: 0 0 10px rgba(0, 255, 157, 0.5);
|
||||
}
|
||||
|
||||
.week-display {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.week-label {
|
||||
font-size: 28rpx;
|
||||
margin-right: 10rpx;
|
||||
color: rgba(0, 255, 157, 0.7);
|
||||
}
|
||||
|
||||
.week-value {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #00ff9d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hologram-grid {
|
||||
margin: 20rpx;
|
||||
border: 1px solid rgba(0, 255, 157, 0.2);
|
||||
border-radius: 8rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.grid-header {
|
||||
display: flex;
|
||||
background: rgba(0, 30, 60, 0.8);
|
||||
|
||||
.time-slot {
|
||||
width: 160rpx;
|
||||
padding: 20rpx;
|
||||
text-align: center;
|
||||
border-right: 1px solid rgba(0, 255, 157, 0.2);
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.day-header {
|
||||
flex: 1;
|
||||
padding: 20rpx;
|
||||
text-align: center;
|
||||
border-right: 1px solid rgba(0, 255, 157, 0.2);
|
||||
font-size: 28rpx;
|
||||
|
||||
&:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
&.today {
|
||||
color: #00ff9d;
|
||||
position: relative;
|
||||
font-weight: bold;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 10rpx;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 40rpx;
|
||||
height: 3rpx;
|
||||
background: #00ff9d;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.grid-row {
|
||||
display: flex;
|
||||
border-bottom: 1px solid rgba(0, 255, 157, 0.1);
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.time-slot {
|
||||
width: 160rpx;
|
||||
padding: 15rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-right: 1px solid rgba(0, 255, 157, 0.1);
|
||||
font-size: 24rpx;
|
||||
color: #00b8ff;
|
||||
|
||||
.slot-num {
|
||||
font-size: 20rpx;
|
||||
color: rgba(0, 184, 255, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
.course-slot {
|
||||
flex: 1;
|
||||
min-height: 120rpx;
|
||||
padding: 10rpx;
|
||||
border-right: 1px solid rgba(0, 255, 157, 0.1);
|
||||
|
||||
&:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hologram-card {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
padding: 15rpx;
|
||||
border-radius: 6rpx;
|
||||
background: rgba(var(--hologram-color-rgb), 0.1);
|
||||
border: 1px solid var(--hologram-color);
|
||||
color: white;
|
||||
overflow: hidden;
|
||||
|
||||
.course-name {
|
||||
font-size: 26rpx;
|
||||
font-weight: bold;
|
||||
margin-bottom: 5rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.course-location {
|
||||
font-size: 22rpx;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.hologram-effect {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgba(var(--hologram-color-rgb), 0.1) 0%,
|
||||
rgba(var(--hologram-color-rgb), 0.3) 50%,
|
||||
rgba(var(--hologram-color-rgb), 0.1) 100%
|
||||
);
|
||||
opacity: 0.5;
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 颜色变量转换 */
|
||||
.hologram-card {
|
||||
--hologram-color-rgb: 0, 255, 157;
|
||||
}
|
||||
|
||||
.hologram-card[style*="math"] {
|
||||
--hologram-color-rgb: 0, 255, 157;
|
||||
}
|
||||
|
||||
.hologram-card[style*="programming"] {
|
||||
--hologram-color-rgb: 0, 184, 255;
|
||||
}
|
||||
|
||||
.hologram-card[style*="english"] {
|
||||
--hologram-color-rgb: 255, 45, 117;
|
||||
}
|
||||
|
||||
.hologram-card[style*="physics"] {
|
||||
--hologram-color-rgb: 255, 157, 0;
|
||||
}
|
||||
|
||||
.hologram-card[style*="default"] {
|
||||
--hologram-color-rgb: 138, 43, 226;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<text class="title">成绩</text>
|
||||
<!-- 页面内容 -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue'
|
||||
|
||||
// 这里可以添加页面逻辑
|
||||
const pageTitle = ref('成绩')
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 18px;
|
||||
color: #333;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<text class="title">设置</text>
|
||||
<!-- 页面内容 -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue'
|
||||
|
||||
// 这里可以添加页面逻辑
|
||||
const pageTitle = ref('设置')
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 18px;
|
||||
color: #333;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,376 @@
|
||||
<template>
|
||||
<view class="tech-container">
|
||||
<!-- 科技风背景元素 -->
|
||||
<view class="tech-bg">
|
||||
<view class="tech-grid"></view>
|
||||
<view class="tech-circle circle-1"></view>
|
||||
<view class="tech-circle circle-2"></view>
|
||||
</view>
|
||||
|
||||
<!-- 用户信息卡片 -->
|
||||
<view class="tech-card user-card">
|
||||
<view class="user-info">
|
||||
<view class="avatar-wrapper" @click="chooseAvatar">
|
||||
<image class="avatar" :src="userInfo.avatar || '/static/user/avatar.png'" mode="aspectFill"></image>
|
||||
<view class="avatar-border"></view>
|
||||
</view>
|
||||
<view class="info-right">
|
||||
<view class="name-line" @click="editName">
|
||||
<text class="username">{{ userInfo.name || '张三' }}</text>
|
||||
<uni-icons type="compose" size="18" color="#00f0ff"></uni-icons>
|
||||
</view>
|
||||
<view class="tech-input-line" @click="editStudentId">
|
||||
<text class="tech-label">学号:</text>
|
||||
<text class="student-id">{{ userInfo.studentId || '20230001' }}</text>
|
||||
<uni-icons type="arrowright" size="18" color="#7f8fa6"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tech-divider"></view>
|
||||
</view>
|
||||
|
||||
<!-- 功能卡片 -->
|
||||
<view class="tech-card function-card">
|
||||
<view class="function-grid">
|
||||
<view class="function-item" v-for="item in functionList" :key="item.type" @click="navigateTo(item.type)">
|
||||
<view class="tech-icon-wrapper">
|
||||
<image class="function-icon" :src="item.icon"></image>
|
||||
<view class="icon-halo"></view>
|
||||
</view>
|
||||
<text class="function-text">{{ item.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
|
||||
// 用户信息
|
||||
const userInfo = ref({
|
||||
name: '张三',
|
||||
studentId: '20230001',
|
||||
avatar: ''
|
||||
})
|
||||
|
||||
// 功能列表
|
||||
const functionList = ref([
|
||||
{ type: 'leave', name: '请假', icon: '/static/user/leave.png' },
|
||||
{ type: 'plan', name: '培养方案', icon: '/static/user/plan.png' },
|
||||
{ type: 'course', name: '选课', icon: '/static/user/course.png' },
|
||||
{ type: 'score', name: '成绩', icon: '/static/user/score.png' },
|
||||
{ type: 'settings', name: '设置', icon: '/static/user/settings.png' }
|
||||
])
|
||||
|
||||
// 导航函数
|
||||
const navigateTo = (type) => {
|
||||
const pages = {
|
||||
'leave': '/pages/leave/leave',
|
||||
'plan': '/pages/plan/plan',
|
||||
'course': '/pages/course/course',
|
||||
'score': '/pages/score/score',
|
||||
'settings': '/pages/settings/settings'
|
||||
}
|
||||
uni.navigateTo({ url: pages[type] })
|
||||
}
|
||||
|
||||
// 选择头像
|
||||
const chooseAvatar = () => {
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
sizeType: ['compressed'],
|
||||
sourceType: ['album', 'camera'],
|
||||
success: (res) => {
|
||||
userInfo.value.avatar = res.tempFilePaths[0]
|
||||
saveUserInfo()
|
||||
uni.showToast({ title: '头像更新成功', icon: 'success' })
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({ title: '取消选择', icon: 'none' })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 编辑姓名
|
||||
const editName = () => {
|
||||
uni.showModal({
|
||||
title: '修改姓名',
|
||||
content: userInfo.value.name,
|
||||
editable: true,
|
||||
placeholderText: '请输入姓名',
|
||||
confirmText: '保存',
|
||||
cancelText: '取消',
|
||||
success: (res) => {
|
||||
if (res.confirm && res.content) {
|
||||
userInfo.value.name = res.content.trim()
|
||||
saveUserInfo()
|
||||
uni.showToast({ title: '姓名修改成功', icon: 'success' })
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 编辑学号
|
||||
const editStudentId = () => {
|
||||
uni.showModal({
|
||||
title: '修改学号',
|
||||
content: userInfo.value.studentId,
|
||||
editable: true,
|
||||
placeholderText: '请输入学号',
|
||||
confirmText: '保存',
|
||||
cancelText: '取消',
|
||||
success: (res) => {
|
||||
if (res.confirm && res.content) {
|
||||
userInfo.value.studentId = res.content.trim()
|
||||
saveUserInfo()
|
||||
uni.showToast({ title: '学号修改成功', icon: 'success' })
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 保存用户信息
|
||||
const saveUserInfo = () => {
|
||||
uni.setStorageSync('userInfo', userInfo.value)
|
||||
}
|
||||
|
||||
// 初始化数据
|
||||
onLoad(() => {
|
||||
const cachedUserInfo = uni.getStorageSync('userInfo')
|
||||
if (cachedUserInfo) {
|
||||
userInfo.value = cachedUserInfo
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tech-container {
|
||||
padding: 30rpx;
|
||||
background: linear-gradient(135deg, #0a0e21 0%, #121a3a 100%);
|
||||
min-height: 100vh;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 科技风背景 */
|
||||
.tech-bg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: -1;
|
||||
overflow: hidden;
|
||||
|
||||
.tech-grid {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image:
|
||||
linear-gradient(rgba(0, 240, 255, 0.05) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(0, 240, 255, 0.05) 1px, transparent 1px);
|
||||
background-size: 40rpx 40rpx;
|
||||
}
|
||||
|
||||
.tech-circle {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
background: radial-gradient(circle, rgba(0, 240, 255, 0.05), transparent 70%);
|
||||
|
||||
&.circle-1 {
|
||||
width: 400rpx;
|
||||
height: 400rpx;
|
||||
top: -200rpx;
|
||||
right: -200rpx;
|
||||
}
|
||||
|
||||
&.circle-2 {
|
||||
width: 300rpx;
|
||||
height: 300rpx;
|
||||
bottom: -150rpx;
|
||||
left: -150rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tech-card {
|
||||
background: rgba(30, 41, 59, 0.6);
|
||||
border-radius: 20rpx;
|
||||
margin-bottom: 30rpx;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1rpx solid rgba(0, 240, 255, 0.1);
|
||||
box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2rpx;
|
||||
background: linear-gradient(90deg, transparent, #00f0ff, transparent);
|
||||
}
|
||||
}
|
||||
|
||||
.user-card {
|
||||
padding: 40rpx;
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.avatar-wrapper {
|
||||
position: relative;
|
||||
width: 140rpx;
|
||||
height: 140rpx;
|
||||
margin-right: 30rpx;
|
||||
|
||||
.avatar {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.avatar-border {
|
||||
position: absolute;
|
||||
top: -4rpx;
|
||||
left: -4rpx;
|
||||
right: -4rpx;
|
||||
bottom: -4rpx;
|
||||
border-radius: 50%;
|
||||
border: 2rpx solid #00f0ff;
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
}
|
||||
|
||||
.info-right {
|
||||
flex: 1;
|
||||
|
||||
.name-line {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
.username {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
margin-right: 20rpx;
|
||||
background: linear-gradient(to right, #00f0ff, #0088ff);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.tech-input-line {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 16rpx 0;
|
||||
|
||||
.tech-label {
|
||||
font-size: 30rpx;
|
||||
color: #7f8fa6;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.student-id {
|
||||
font-size: 30rpx;
|
||||
color: #fff;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tech-divider {
|
||||
height: 2rpx;
|
||||
background: linear-gradient(90deg, transparent, rgba(0, 240, 255, 0.3), transparent);
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.function-card {
|
||||
padding: 30rpx;
|
||||
|
||||
.function-grid {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.function-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 30rpx 0;
|
||||
position: relative;
|
||||
|
||||
&:not(:last-child)::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 1rpx;
|
||||
background: linear-gradient(90deg, transparent, rgba(0, 240, 255, 0.1), transparent);
|
||||
}
|
||||
|
||||
.tech-icon-wrapper {
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
margin-right: 30rpx;
|
||||
background: rgba(0, 240, 255, 0.1);
|
||||
border-radius: 22rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
border: 1rpx solid rgba(0, 240, 255, 0.2);
|
||||
|
||||
.function-icon {
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.icon-halo {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 22rpx;
|
||||
background: radial-gradient(circle, rgba(0, 240, 255, 0.3), transparent 70%);
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
}
|
||||
|
||||
.function-text {
|
||||
font-size: 32rpx;
|
||||
color: #fff;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&:active {
|
||||
.tech-icon-wrapper .icon-halo {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 动画 */
|
||||
@keyframes pulse {
|
||||
0%, 100% {
|
||||
opacity: 0.7;
|
||||
transform: scale(0.98);
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
transform: scale(1.02);
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<!-- 基础分隔线 -->
|
||||
<view class="divider-line"></view>
|
||||
|
||||
<!-- 带文本的分隔线 -->
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* 基础分隔线 */
|
||||
.divider-line {
|
||||
height: 1rpx;
|
||||
background-color: red;
|
||||
margin: 20rpx 0;
|
||||
}
|
||||
|
||||
/* 带文本的分隔线 */
|
||||
.divider-with-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 30rpx 0;
|
||||
}
|
||||
.divider-with-text::before,
|
||||
.divider-with-text::after {
|
||||
content: '';
|
||||
flex: 1;
|
||||
height: 1rpx;
|
||||
background: linear-gradient(90deg, transparent, #e4e7ed 50%, transparent);
|
||||
}
|
||||
.divider-text {
|
||||
padding: 0 20rpx;
|
||||
color: #909399;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,201 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<!-- 页面内容 -->
|
||||
<h3 >
|
||||
上课
|
||||
</h3>
|
||||
<view v-if="kctivityAndPPT.length > 0">
|
||||
<H4>课堂活动与 PPT 列表</H4>
|
||||
<ul >
|
||||
<li v-for="item in kctivityAndPPT" :key="item.id">
|
||||
展示:课程活动
|
||||
<view v-if="item.lx=='ppt'">
|
||||
<view class="content" >
|
||||
<image
|
||||
:src="item.src"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</view>
|
||||
<view class="footer">
|
||||
<text class="time">{{moment(item.time).fromNow()}}</text>
|
||||
<text class="status">已完成</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else-if="item.lx=='activity'">
|
||||
<view class="activity-item" :style="{backgroundColor: !finish.includes(item.id) ?item.color:'#666'}">
|
||||
<view class="content" :style="{backgroundColor:!finish.includes(item.id) ?item.color:'#666'}">
|
||||
<view class="title">{{ item.showname }}</view>
|
||||
<view class="subtitle">{{ item.title }}</view>
|
||||
</view>
|
||||
<image class="icon" src="/src/static/student-course/course-active.png" mode="aspectFit"></image>
|
||||
</view>
|
||||
<view class="footer">
|
||||
<text class="time">{{moment(item.time).fromNow()}}</text>
|
||||
<text class="status">{{finish.includes(item.id)?'已完成':''}}</text>
|
||||
</view>
|
||||
<!-- <view :style="{backgroundColor:item.color,width:'90vw',height:'70px'}">
|
||||
<view :style="{fontSize:'30px'}">
|
||||
<text :style="{color:'white'}">{{item.name}}</text>
|
||||
</view>
|
||||
<view :style="{fontSize:'15px'}">
|
||||
<text :style="{color:'white'}">{{item.title}}</text>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
<view v-else-if="item.lx=='notice'">
|
||||
|
||||
<view class="notice-view">
|
||||
<text >{{item.wb}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</li>
|
||||
</ul>
|
||||
</view>
|
||||
<view v-else>
|
||||
<p>暂无课堂活动或 PPT 数据</p>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
||||
<script setup>
|
||||
import { onMounted, onUnmounted } from 'vue'
|
||||
import moment from "moment/min/moment-with-locales";
|
||||
|
||||
import io from '@hyoga/uni-socket.io'
|
||||
import { ref } from 'vue'
|
||||
import {onLoad} from "@dcloudio/uni-app";
|
||||
|
||||
// 课堂活动and PPT
|
||||
const kctivityAndPPT = ref([{id:0,lx:'notice',wb:'上课了'},
|
||||
{lx:'ppt',id:1,name:'PPT展示1',src:'https://img11.360buyimg.com/n1/s720x720_jfs/t1/303510/33/1806/82651/6815a7a6F2e5d77b6/08d231a86927b0ce.jpg',time:'2025-05-06T19:54:43+08:00'},
|
||||
{lx :'activity',id:2,name:'课堂活动1',lxA:'讨论',color:'green',showname:'课程讨论',title:'历史为什么选择了中国共产党',time:'2025-05-06T19:54:43+08:00'}
|
||||
])
|
||||
const finish=ref([1])
|
||||
|
||||
|
||||
// 定义 socket 变量
|
||||
let socket
|
||||
moment.locale('zh-cn');
|
||||
// 初始化连接
|
||||
onLoad((options) => {
|
||||
console.log('load',options)
|
||||
|
||||
console.log(kctivityAndPPT.value)
|
||||
socket = null;
|
||||
if(options) {
|
||||
socket= io('ws://localhost:3400', {
|
||||
transports: ['websocket'],
|
||||
auth: {
|
||||
xuehao: "202413501062",
|
||||
sf: "stu",
|
||||
kch: options.kch,
|
||||
kctime: options.kctime,
|
||||
k_id: options.uuid,
|
||||
}
|
||||
})
|
||||
}else {
|
||||
socket= io('ws://localhost:3400', {
|
||||
transports: ['websocket'],
|
||||
auth: {
|
||||
xuehao: "202413501062",
|
||||
sf: "stu",
|
||||
kch: "nokch",
|
||||
kctime: "nokctime",
|
||||
k_id: "nouuid",
|
||||
}
|
||||
})
|
||||
}
|
||||
// 监听事件
|
||||
socket.on('connect', () => console.log('Socket 已连接'))
|
||||
socket.on('server', (data) => {
|
||||
console.log(data)
|
||||
})
|
||||
socket.on('activeandppt', (data) => {
|
||||
kctivityAndPPT.value.unshift(data)
|
||||
})
|
||||
socket.on('message', (data) => handleMessage(data))
|
||||
})
|
||||
|
||||
// 断开连接并移除监听
|
||||
onUnmounted(() => {
|
||||
if (socket) {
|
||||
socket.off('message')
|
||||
socket.disconnect()
|
||||
}
|
||||
})
|
||||
|
||||
// 处理消息的方法
|
||||
const handleMessage = (data) => {
|
||||
// 处理消息逻辑
|
||||
console.log('处理消息:', data)
|
||||
}
|
||||
|
||||
// 发送数据的方法
|
||||
const sendData = () => {
|
||||
if (socket) {
|
||||
socket.emit('chat', { text: 'Hello' })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.classactivetitle {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
.activity-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 10px;
|
||||
border: 1px solid #080808;
|
||||
background-color: #c5c3c3;
|
||||
width: 90vw;
|
||||
}
|
||||
.content{
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #fff;
|
||||
padding: 10px;
|
||||
}
|
||||
.icon {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
.title {
|
||||
font-size: 18px;
|
||||
color: white;
|
||||
}
|
||||
.subtitle {
|
||||
font-size: 14px;
|
||||
color: white;
|
||||
}
|
||||
.footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.time {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.status {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
}
|
||||
.notice-view {
|
||||
color:white;
|
||||
display: flex;
|
||||
background-color: #666;
|
||||
align-items: center;
|
||||
|
||||
}
|
||||
|
||||
</style>
|
@ -0,0 +1,6 @@
|
||||
export {}
|
||||
|
||||
declare module "vue" {
|
||||
type Hooks = App.AppInstance & Page.PageInstance;
|
||||
interface ComponentCustomOptions extends Hooks {}
|
||||
}
|
After Width: | Height: | Size: 677 B |
After Width: | Height: | Size: 636 B |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 976 B |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1,85 @@
|
||||
{
|
||||
"id": "uni-badge",
|
||||
"displayName": "uni-badge 数字角标",
|
||||
"version": "1.2.2",
|
||||
"description": "数字角标(徽章)组件,在元素周围展示消息提醒,一般用于列表、九宫格、按钮等地方。",
|
||||
"keywords": [
|
||||
"",
|
||||
"badge",
|
||||
"uni-ui",
|
||||
"uniui",
|
||||
"数字角标",
|
||||
"徽章"
|
||||
],
|
||||
"repository": "https://github.com/dcloudio/uni-ui",
|
||||
"engines": {
|
||||
"HBuilderX": ""
|
||||
},
|
||||
"directories": {
|
||||
"example": "../../temps/example_temps"
|
||||
},
|
||||
"dcloudext": {
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
|
||||
"type": "component-vue"
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": ["uni-scss"],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "y"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "y",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "y",
|
||||
"百度": "y",
|
||||
"字节跳动": "y",
|
||||
"QQ": "y"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "y",
|
||||
"联盟": "y"
|
||||
},
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
@import './styles/index.scss';
|
@ -0,0 +1,7 @@
|
||||
@import './setting/_variables.scss';
|
||||
@import './setting/_border.scss';
|
||||
@import './setting/_color.scss';
|
||||
@import './setting/_space.scss';
|
||||
@import './setting/_radius.scss';
|
||||
@import './setting/_text.scss';
|
||||
@import './setting/_styles.scss';
|