Revert "改"

This reverts commit a88c7c0079.
This commit is contained in:
ryx 2026-01-26 15:45:33 +08:00
parent a88c7c0079
commit a767b7b370
6 changed files with 1047 additions and 331 deletions

View File

@ -412,15 +412,23 @@
]
},
{
"root": "pages/lab",
"pages": [
{
"path": "userlist",
"style": {
"enablePullDownRefresh": true
}
}
]
}
"root": "pages/lab",
"pages": [
{
"path": "userlist",
"style": {
"navigationBarTitleText": "成员管理", //
"enablePullDownRefresh": true
}
},
// lab
{
"path": "useredit",
"style": {
"navigationBarTitleText": "添加成员"
}
}
]
}
]
}

View File

@ -0,0 +1,382 @@
<template>
<view class="ciy-page">
<!-- 顶部导航栏复用框架标题样式 -->
<view class="ciy-title mk rel bg3">
<text class="abs l1 t0 txt9 tran5" @tap="goBack"> 返回</text>
<view class="title txt9">{{isEdit ? '编辑成员' : '新增成员'}}</view>
<view class="right">
<text class="btn man sm cc px3" @tap="submitForm">{{isEdit ? '保存' : '提交'}}</text>
</view>
</view>
<!-- 主体内容区滚动表单 -->
<view class="main overflow-auto">
<!-- 表单容器复用框架卡片/间距样式 -->
<view class="ciy-card my3 mx4">
<!-- 基础信息标题复用框架标题样式 -->
<view class="title mk">基础信息</view>
<view class="content">
<!-- 姓名输入项复用框架表单样式 -->
<view class="ciy-form char4 mb3">
<label class="imp txt7">姓名</label>
<view>
<input
class="ciy-edit txt7 bg4 py2 px3 rounded-md w-full"
v-model="formData.name"
placeholder="请输入姓名"
/>
</view>
</view>
<!-- 手机号输入项复用框架表单样式 -->
<view class="ciy-form char4 mb3">
<label class="imp txt7">手机号</label>
<view>
<input
class="ciy-edit txt7 bg4 py2 px3 rounded-md w-full"
v-model="formData.mobile"
type="number"
placeholder="请输入手机号"
:disabled="isEdit"
/>
</view>
</view>
<!-- 头衔选择项复用框架表单样式 -->
<view class="ciy-form char4 mb3">
<label class="imp txt7">头衔</label>
<view>
<picker
class="bg4 py2 px3 rounded-md w-full txt7"
:range="titleList"
range-key="name"
:value="titleIndex"
@change="handleTitleChange"
>
<view class="flex justify-between items-center">
<text>{{titleIndex >= 0 ? titleList[titleIndex].name : '请选择头衔'}}</text>
<text class="txt3"></text>
</view>
</picker>
</view>
</view>
<!-- 状态选择项复用框架表单样式 -->
<view class="ciy-form char4 mb3">
<label class="imp txt7">状态</label>
<view>
<picker
class="bg4 py2 px3 rounded-md w-full txt7"
:range="statusList"
range-key="name"
:value="statusIndex"
@change="handleStatusChange"
>
<view class="flex justify-between items-center">
<text>{{statusIndex >= 0 ? statusList[statusIndex].name : '请选择状态'}}</text>
<text class="txt3"></text>
</view>
</picker>
</view>
</view>
<!-- 性别选择项复用框架表单样式 -->
<view class="ciy-form char4 mb3">
<label class="txt7">性别</label>
<view>
<picker
class="bg4 py2 px3 rounded-md w-full txt7"
:range="sexList"
range-key="name"
:value="sexIndex"
@change="handleSexChange"
>
<view class="flex justify-between items-center">
<text>{{sexIndex >= 0 ? sexList[sexIndex].name : '请选择性别'}}</text>
<text class="txt3"></text>
</view>
</picker>
</view>
</view>
<!-- 邮箱输入项复用框架表单样式 -->
<view class="ciy-form char4 mb3">
<label class="txt7">邮箱</label>
<view>
<input
class="ciy-edit txt7 bg4 py2 px3 rounded-md w-full"
v-model="formData.email"
type="email"
placeholder="请输入邮箱"
/>
</view>
</view>
</view>
</view>
<!-- 密码设置仅新增显示复用框架卡片样式 -->
<view v-if="!isEdit" class="ciy-card my3 mx4">
<view class="title mk">密码设置</view>
<view class="content">
<!-- 初始密码 -->
<view class="ciy-form char4 mb3">
<label class="imp txt7">初始密码</label>
<view>
<input
class="ciy-edit txt7 bg4 py2 px3 rounded-md w-full"
v-model="formData.pass"
type="password"
placeholder="请设置初始密码不少于6位"
/>
</view>
</view>
<!-- 确认密码 -->
<view class="ciy-form char4 mb3">
<label class="imp txt7">确认密码</label>
<view>
<input
class="ciy-edit txt7 bg4 py2 px3 rounded-md w-full"
v-model="formData.pass2"
type="password"
placeholder="请再次输入密码"
/>
</view>
</view>
</view>
</view>
</view>
<!-- 底部固定区 -->
<view class="ciy-bottom"></view>
</view>
</template>
<script>
// 使md5
import md5 from '../../util/md5.js';
export default {
data() {
return {
isEdit: false, //
formData: {
id: 0,
name: '',
mobile: '',
usertitle: 1, //
status: 1, //
sex: 0, //
email: '',
pass: '',
pass2: ''
},
//
titleList: [
{id: 1, name: '负责人'},
{id: 2, name: '科研秘书'},
{id: 3, name: '在册成员'},
{id: 4, name: '历史成员'},
{id: 5, name: '外部成员'}
],
titleIndex: 0, //
//
statusList: [
{id: 1, name: '在册'},
{id: 2, name: '历史'}
],
statusIndex: 0, //
//
sexList: [
{id: 0, name: '未知'},
{id: 1, name: '男'},
{id: 2, name: '女'}
],
sexIndex: 0, //
submitting: false //
};
},
onLoad(options) {
if (options.id && options.id > 0) {
this.isEdit = true;
this.formData.id = parseInt(options.id);
this.getMemberDetail();
}
},
methods: {
//
goBack() {
uni.navigateBack();
},
//
async getMemberDetail() {
try {
const [err, res] = await uni.request({
url: '/ambap/member.php?act=member.detail',
method: 'POST',
data: { id: this.formData.id }
});
if (err) throw new Error('加载详情失败');
const result = res.data || {};
if (result.code === 1) {
const data = result.data;
this.formData = { ...this.formData, ...data };
//
this.titleIndex = this.titleList.findIndex(item => item.id === data.usertitle) || 0;
this.statusIndex = this.statusList.findIndex(item => item.id === data.status) || 0;
this.sexIndex = this.sexList.findIndex(item => item.id === data.sex) || 0;
} else {
uni.showToast({ title: result.errmsg || '成员不存在', icon: 'none' });
this.goBack();
}
} catch (err) {
uni.showToast({ title: '加载详情失败', icon: 'none' });
console.error('获取详情失败:', err);
this.goBack();
}
},
//
handleTitleChange(e) {
this.titleIndex = e.detail.value;
this.formData.usertitle = this.titleList[this.titleIndex].id;
},
//
handleStatusChange(e) {
this.statusIndex = e.detail.value;
this.formData.status = this.statusList[this.statusIndex].id;
},
//
handleSexChange(e) {
this.sexIndex = e.detail.value;
this.formData.sex = this.sexList[this.sexIndex].id;
},
//
validateForm() {
//
if (!this.formData.name.trim()) {
uni.showToast({ title: '请输入姓名', icon: 'none' });
return false;
}
//
const mobileReg = /^1[3-9]\d{9}$/;
if (!this.formData.mobile) {
uni.showToast({ title: '请输入手机号', icon: 'none' });
return false;
}
if (!mobileReg.test(this.formData.mobile)) {
uni.showToast({ title: '手机号格式错误', icon: 'none' });
return false;
}
//
if (this.titleIndex === -1) {
uni.showToast({ title: '请选择头衔', icon: 'none' });
return false;
}
//
if (this.statusIndex === -1) {
uni.showToast({ title: '请选择状态', icon: 'none' });
return false;
}
//
if (!this.isEdit) {
if (!this.formData.pass) {
uni.showToast({ title: '请设置初始密码', icon: 'none' });
return false;
}
if (this.formData.pass.length < 6) {
uni.showToast({ title: '密码不少于6位', icon: 'none' });
return false;
}
if (this.formData.pass !== this.formData.pass2) {
uni.showToast({ title: '两次密码不一致', icon: 'none' });
return false;
}
}
return true;
},
//
async submitForm() {
if (this.submitting) return;
if (!this.validateForm()) return;
this.submitting = true;
try {
//
const submitData = { ...this.formData };
// md5
if (!this.isEdit) {
const tokenSalt = getApp()?.globalData?.tokensalt || 'default_salt';
submitData.password = typeof md5 === 'function'
? md5(submitData.pass + tokenSalt)
: md5.md5(submitData.pass + tokenSalt);
delete submitData.pass;
delete submitData.pass2;
}
//
const [err, res] = await uni.request({
url: this.isEdit ? '/ambap/member.php?act=member.edit' : '/ambap/member.php?act=member.add',
method: 'POST',
data: submitData
});
if (err) throw new Error('提交失败,请检查网络');
const result = res.data || {};
if (result.code === 1) {
uni.showToast({ title: this.isEdit ? '修改成功' : '新增成功', icon: 'success' });
//
setTimeout(() => {
uni.navigateBack({
success: () => {
const pages = getCurrentPages();
const listPage = pages[pages.length - 2];
if (listPage && typeof listPage.refreshList === 'function') {
listPage.refreshList();
}
}
});
}, 1000);
} else {
uni.showToast({ title: result.errmsg || '操作失败', icon: 'none' });
}
} catch (err) {
uni.showToast({ title: err.message || '提交失败', icon: 'none' });
console.error('提交表单失败:', err);
} finally {
this.submitting = false;
}
}
}
};
</script>
<style scoped>
/* 仅补充框架未覆盖的极少量通用样式 */
.rounded-md {
border-radius: 0.3rem;
}
.w-full {
width: 100%;
}
.justify-between {
justify-content: space-between;
}
.items-center {
align-items: center;
}
.overflow-auto {
overflow: auto;
}
.mb3 {
margin-bottom: 0.75rem;
}
</style>

View File

@ -1,331 +1,271 @@
<template>
<ciy-header title="搜索/列表/删除页" ref="header"></ciy-header>
<view v-if="init.code != 1">
<view class="px4 py4">
<view style="height:2em;width:60%;" class="ciy-skeleton"></view>
<view style="height:1em;width:40%;margin-left:1em;" class="ciy-skeleton"></view>
<view style="height:1em;width:50%;" class="ciy-skeleton"></view>
<view style="height:6em;width:100%;" class="ciy-skeleton"></view>
<view class="ciy-page">
<!-- 顶部导航栏复用框架标题样式 + 返回首页按钮 -->
<view class="ciy-title mk rel bg3">
<text class="abs l1 t0 txt9 tran5" @tap="goToHome"> 首页</text>
<view class="title txt9">成员管理</view>
<view class="right"></view>
</view>
</view>
<view v-else>
<view class="sti" :style="{top:(header_statusbar_height+header_title_height)+'px'}">
<ciy-segment :lis="init.lis" all="全部" @change="segment_change"></ciy-segment>
<ciy-query ref="query" :gdict="g" :qry="init.searchinput" @confirm="query_confirm">
<template v-slot="{itm}">
<ciy-input :name="itm.item.form" v-model="itm.data[itm.item.form]"></ciy-input>
</template>
</ciy-query>
<!-- 主体内容区 -->
<view class="main">
<!-- 搜索+新增区域复用框架布局/按钮样式 -->
<view class="flex flex-center px4 py2 bg1">
<!-- 搜索框复用框架背景/内边距样式 -->
<view class="flex1 bg4 py1 px3 rounded-lg flex flex-center">
<text class="txt3 mr2">🔍</text>
<input
class="flex1 ciy-edit txt7"
v-model="searchKey"
placeholder="按姓名/头衔搜索"
@input="handleSearch"
/>
</view>
<!-- 新增按钮复用框架btn样式 -->
<view class="btn man cc ml3 sm" @tap="goToUserEdit">
<text class="mr1">+</text>
<text>新增</text>
</view>
</view>
<!-- 分类标签栏复用框架滚动/布局样式 -->
<scroll-view scroll-x class="bg1">
<view class="flex px4 py2">
<view
class="px3 py1 mx1 rounded-lg tran5"
v-for="(tab, idx) in tabs"
:key="idx"
:class="[activeTab === idx ? 'man txt-white' : 'bg4 txt6']"
@tap="switchTab(idx)"
>
<text>{{tab.name}}</text>
</view>
</view>
</scroll-view>
<!-- 成员列表区域复用框架网格/卡片样式 -->
<scroll-view
class="flex1"
scroll-y
@scrolltolower="loadMore"
refresher-enabled="true"
@refresherrefresh="refreshList"
>
<!-- 成员网格复用框架九宫格样式 -->
<view class="ciy-grid grid3 px4 py3 bg4">
<!-- 成员卡片复用框架列表/背景样式 -->
<view
class="grid my2"
v-for="(item, idx) in filterMembers"
:key="item.id"
@tap="goToUserEdit(item.id)"
>
<view class="bg1 rounded-lg p3 shadow-sm flex flexcol items-center">
<!-- 头像 -->
<image
class="w12 h12 rounded-full mb2"
:src="item.avatar || '/static/avatar-default.png'"
mode="aspectFill"
@error="handleImgError($event)"
/>
<!-- 姓名 -->
<text class="txt8 txt-lg txt-wb">{{item.name}}</text>
<!-- 头衔 -->
<text class="txt5 txt-sm mt1">{{getTitleName(item.usertitle)}}</text>
<!-- 负责人标签复用框架警示样式 -->
<text v-if="item.isLeader" class="warn txt-xs px2 py05 rounded mt1">负责人</text>
</view>
</view>
</view>
<!-- 空列表提示复用框架提示样式 -->
<view v-if="filterMembers.length === 0" class="ciy-tip txt-center py4">
<text class="txt6">暂无{{tabs[activeTab].name}}类成员</text>
<view class="btn succ sm cc mt3" @tap="goToUserEdit">
<text>立即添加</text>
</view>
</view>
<!-- 加载更多复用框架文字/间距样式 -->
<view v-if="hasMore && filterMembers.length > 0" class="txt-center py3 txt4">
<text>加载更多...</text>
</view>
</scroll-view>
</view>
<view class="ciy-list" :class="{del:item._del}" v-for="(item,index) in init.list" :key="item.id" @tap="showmenu(index)">
<view class="l0">No: {{item.id}}</view>
<view v-if="item.id%2 == 0" class="rt">
<view class="code b" :class="ccode(g.auditstatus, item.auditstatus,'clas')">{{ccode(g.auditstatus, item.auditstatus)}}</view>
</view>
<view v-else class="rtz liner" :class="ccode(g.auditstatus, item.auditstatus,'clas')">
{{ccode(g.auditstatus, item.auditstatus)}}
</view>
<view class="l1 c">
<view>{{item.name}}</view>
</view>
<view class="ciy-hr"></view>
<view class="l2">审核人 {{ccode('xa_user', item.audituser)}}</view>
<view class="l2" v-if="item.auditmsg">审核理由 <text v-html="tobr(item.auditmsg)"></text></view>
<view class="l2">审核时间 {{todatetime(item.audittimes)}}</view>
<view class="ciy-hr"></view>
<view class="l2">
<label>所属菜单</label>
<view>{{ccode(init.zc_menu, item.menuid)}}</view>
</view>
<view class="l2">
<label>文件大小</label>
<view>{{tofix(item.filesize/1024, -2)}}KB</view>
</view>
<view class="l2">
<label>长度</label>
<view>{{tofix(item.metre/1000, -2)}}</view>
</view>
<view class="l2">
<label>贷款金额</label>
<view>{{tofix(item.bankmoney/1000000)}}万元</view>
</view>
<view class="l2">
<label>设置日期</label>
<view>{{todatetime(item.setdate, 'd')}}</view>
</view>
<view class="l2">
<label>设置时间</label>
<view>{{todatetime(item.settimes)}}</view>
</view>
<view class="l2">
<label>营业时间</label>
<view>{{totimepoint(item.dayclock, true)}}</view>
</view>
<ciy-showimgs label="文档" :src="item.downurl"></ciy-showimgs>
<ciy-showimgs :src="item.avar" width="20em" mode="widthFix"></ciy-showimgs>
<view class="l2">
<label>是否使用</label>
<view>{{item.isuse==1?'√':'×'}}</view>
</view>
<view class="l2">
<label>是否开启</label>
<view>{{item.isopen==1?'开启':'关闭'}}</view>
</view>
<view class="l2">
<label>库存单位</label>
<view>{{tounit(item.unit)}}</view>
</view>
<view class="l2">
<label>单选状态</label>
<view>{{ccode(g.auditstatus, item.sigstatus)}}</view>
</view>
<view class="l2">
<label>多选状态</label>
<view>
<view class="kbd" v-for="(itm, index) in scode(g.auditstatus, item.mauditstatus)" :key="index">{{itm.name}}</view>
</view>
</view>
<view class="l2">
<label>组织结构</label>
<view>{{mcode(g.zc_depart, item.prodcata, 'name').join(' . ')}}</view>
</view>
<view class="l2">
<label>所在地区</label>
<view>
<text class="code" v-for="(itm, index) in mcode(g.ciy_arearpc, item.areacode)" :key="index">{{itm.name}}</text>
</view>
</view>
<view class="l2">
<label>认证情况</label>
<view>
<text class="kbd" v-for="(itm, index) in bcode(g.renzheng, item.renzheng)" :key="index">{{itm.name}}</text>
</view>
</view>
<view class="l2">
<label>临时字典</label>
<view>{{ccode(g.ppint, item.ppint)}}</view>
</view>
<view class="l2">
<label>执行周期</label>
<view>{{tocyc(item.npcyc)}}</view>
</view>
<view class="l2">
<label>执行用时</label>
<view>{{totimesec(item.runsec)}}</view>
</view>
<view class="l2">
<label>活动期数</label>
<view>{{item.acttm}}</view>
</view>
<ciy-showimgs label="活动花絮" :src="item.imgs"></ciy-showimgs>
<view class="l2">
<label>吨位</label>
<view>{{tofix(item.ton/1000000, 3)}}</view>
</view>
<view class="l2">
<label>单价</label>
<view>{{tofix(item.price/100, 2)}}</view>
</view>
<view class="l2">
<label>位置</label>
<view><text style="text-decoration: underline;" @tap.stop="goloc(item.lat, item.lng)">查看位置</text>
</view>
</view>
<view class="l2">
<label>百分比</label>
<view>{{tofix(item.pct/100, 2)}}%</view>
</view>
<view class="l2">
<label>链接</label>
<view><text style="text-decoration: underline;" @tap.stop="goweb(item.url)">转到链接</text>
</view>
</view>
<view class="l2">
<label>体重</label>
<view>{{tofix(item.weightg/1000)}}公斤</view>
</view>
<view class="l2">
<label>耳温</label>
<view>{{tofix(item.eartmpr/1000, 1)}}</view>
</view>
<view class="l2">
<label>身份证号</label>
<view>{{tomsk(item.idcard,'******#*')}}</view>
</view>
<view class="rb">
添加时间 {{todatetime(item.addtimes)}}
</view>
</view>
<ciy-listend :page="pageno" :listlen="init.list.length" :nodataimg="file_stor('/img/mbnone.png')"></ciy-listend>
<view class="ciy-add" @tap="edit()"></view>
<!-- 底部固定区框架默认 -->
<view class="ciy-bottom"></view>
</view>
</template>
<style>
</style>
<script>
export default {
data() {
return {}
},
onLoad() {
this.load_ciydict(this.file_stor('/dict/ciy_arearpc.js')).then(json => {
if (json.code != 1)
return this.alert(json.errmsg);
this.g.ciy_arearpc = json.arr;
});
this.getlist();
},
onReachBottom(b) {
console.log('onReachBottom page', this.pageno);
if (this.init.code != 1)
return;
this.getlist();
},
onPullDownRefresh(b) {
console.log('onPullDownRefresh page');
this.pageno = 0;
this._stopPullDown = true;
this.getlist();
},
watch: {},
computed: {},
methods: {
async getlist() {
if (this.pageno < 0)
return;
if (this._loading)
return;
this.pagepost.pageno = this.pageno + 1;
this.pagepost.once = !this.init.once;
this._loading = true;
var retjson = await this.callfunc({
func: 'demo/demo.list',
data: this.pagepost
});
this._loading = false;
if (retjson.code != 1)
return this.alert(retjson.errmsg);
this.pageno++;
if (this.pageno == 1)
this.init.list = [];
this.init = this.objdeepmerge(this.init, retjson);
if (retjson.once) {
this.init.lis = [...this.g.auditstatus];
this.g.zc_depart = retjson.zc_depart;
this.g.ppint = retjson.ppint;
export default {
data() {
return {
searchKey: '', //
activeTab: 0, //
// ////
tabs: [
{ name: '负责人', type: 'leader' },
{ name: '科研秘书', type: 'secretary' },
{ name: '在册成员', type: 'current' },
{ name: '历史成员', type: 'history' },
{ name: '外部成员', type: 'external' }
],
allMembers: [], //
page: 1, //
pageSize: 15, //
hasMore: true, //
loading: false //
};
},
computed: {
// +
filterMembers() {
let list = [...this.allMembers];
// 1.
const activeType = this.tabs[this.activeTab].type;
list = list.filter(item => {
switch(activeType) {
case 'leader': return item.usertitle === 1; //
case 'secretary': return item.usertitle === 2; //
case 'current': return item.status === 1; //
case 'history': return item.status === 2; //
case 'external': return item.usertitle === 5; //
default: return true;
}
this.getrefs('query').then(ref => {
ref.setdata(retjson.where);
});
if (retjson.list.length < retjson.pagecount)
this.pageno = -1;
},
segment_change(e) {
this.pagepost.liid = e.value.id;
this.pageno = 0;
this.getlist();
uni.pageScrollTo({
scrollTop: 0,
duration: 800
});
},
query_confirm(dat) {
this.pagepost.query = dat;
this.pageno = 0;
this.getlist();
uni.pageScrollTo({
scrollTop: 0,
duration: 800
});
},
async edit(item) {
item = item || {
url: '',
data: {
id: 0,
_idx: -1
}
};
this.gourl('demo_edit?id=' + item.data.id, 'navigate', item.data, 'demo');
},
async del(item) {
if (await this.askmsg('是否删除?', '删除') != 'ok')
return;
var retjson = await this.callfunc({
func: 'demo/demo.del',
data: {
id: item.data.id
}
});
if (retjson.code != 1)
return this.alert(retjson.errmsg);
this.init.list[item.data._idx]._del = true;
setTimeout(() => {
this.init.list.splice(item.data._idx, 1);
}, 500);
},
async audit(item) {
var msg = await this.inputmsg({
title: '请填写审核理由',
ele: 'textarea'
}, [{
name: '审核通过',
btn: 'ok'
}, {
name: '驳回',
btn: 'ng',
cls: 'dag liner'
}, {
name: '取消',
btn: 'cancel',
cls: 'def'
}]);
if (msg.btn == 'cancel')
return;
var retjson = await this.callfunc({
func: 'demo/demo.audit',
data: {
id: item.data.id,
msg: msg.text,
status: msg.btn == 'ng' ? 90 : 100,
}
});
if (retjson.code != 1)
return this.alert(retjson.errmsg);
this.init.list[item.data._idx] = this.objdeepmerge(this.init.list[item.data._idx], retjson.data);
},
showmenu(idx) {
var dat = this.init.list[idx];
dat._idx = idx;
var items = [];
items.push({
func: 'audit',
name: '审核',
data: dat
});
items.push({
func: 'edit',
name: '变更',
data: dat
});
items.push({
func: 'del',
name: '删除',
style: 'color:var(--dag5)',
data: dat
});
this.popmenu({
items
});
// 2.
if (this.searchKey) {
list = list.filter(item => {
return item.name.includes(this.searchKey) || this.getTitleName(item.usertitle).includes(this.searchKey);
});
}
return list;
}
},
onLoad() {
//
this.getMemberList();
},
methods: {
//
goToHome() {
uni.switchTab({
url: '/pages/main/index' //
});
},
//
getTitleName(id) {
const titleMap = {
1: '负责人',
2: '科研秘书',
3: '在册成员',
4: '历史成员',
5: '外部成员'
};
return titleMap[id] || '未知';
},
//
async getMemberList() {
if (this.loading) return;
this.loading = true;
try {
// ambap
const [err, res] = await uni.request({
url: '/ambap/member.php?act=member.list',
method: 'POST',
data: {
page: this.page,
pageSize: this.pageSize
}
});
if (err) throw new Error('网络请求失败');
const result = res.data || {};
if (result.code === 1) {
const newList = result.list || [];
//
this.allMembers = this.page === 1 ? newList : [...this.allMembers, ...newList];
//
this.hasMore = newList.length >= this.pageSize;
} else {
uni.showToast({ title: result.errmsg || '获取列表失败', icon: 'none' });
}
} catch (err) {
uni.showToast({ title: '加载失败', icon: 'none' });
console.error('获取成员列表失败:', err);
} finally {
this.loading = false;
}
},
//
handleSearch() {
//
},
//
switchTab(idx) {
this.activeTab = idx;
},
//
refreshList() {
this.page = 1;
this.hasMore = true;
this.getMemberList().then(() => {
uni.stopPullDownRefresh();
});
},
//
loadMore() {
if (!this.hasMore || this.loading) return;
this.page++;
this.getMemberList();
},
// /
goToUserEdit(id = 0) {
uni.navigateTo({
url: `/pages/lab/useredit?id=${id}`
});
},
//
handleImgError(e) {
e.target.src = '/static/avatar-default.png';
}
}
};
</script>
<style scoped>
/* 完全复用框架样式,仅补充极少量必要样式 */
.rounded-lg {
border-radius: 0.5rem;
}
.shadow-sm {
box-shadow: 0 2px 4px var(--bg5);
}
.w12 {
width: 3rem;
}
.h12 {
height: 3rem;
}
.items-center {
align-items: center;
}
.py05 {
padding-top: 0.25rem;
padding-bottom: 0.25rem;
}
.txt-xs {
font-size: 0.7rem;
}
</style>

View File

@ -121,7 +121,6 @@ class login {
$rsuser['sid'] = $sid;
$rsuser['exptimes'] = $exp;
$rsuser['ip'] = getip();
$rsuser['laborgid'] = 0;
$rsuser['laborgid'] = 0; // 所属机构默认ID
$rsuser['usertitle'] = 0; // 头衔默认
$rsuser['sn'] = ''; // 编号默认
@ -129,6 +128,10 @@ class login {
$rsuser['totalpnt'] = 0; // 总积分默认
$rsuser['dvotecnt'] = 0; // 互动贡献默认
$rsuser['email'] = '';
$rsuser['education'] = 0; // 学历默认值0=未知对应education字典
$rsuser['userlevel'] = 10; // 成员等级默认值10=普通成员对应lab_userlevel字典
// ==================================================
$csql = new \ciy\sql('lab_user');
if ($db->insert($csql, $rsuser) === false)
return errjson('注册用户失败:' . $db->error);
@ -377,6 +380,12 @@ class login {
$ret['me']['dvotecnt'] = $userrow['dvotecnt'];
$ret['me']['needpass'] = empty($userrow['password']);
$ret['me']['cciy'] = '';
// ========== 新增修改2返回新增字段给前端 ==========
$ret['me']['education'] = $userrow['education'] ?? 0; // 学历字段(兼容旧数据)
$ret['me']['userlevel'] = $userrow['userlevel'] ?? 10; // 成员等级字段(兼容旧数据)
$ret['me']['usertitle'] = $userrow['usertitle'] ?? 0; // 头衔字段(补充返回,方便前端展示)
$ret['me']['sex'] = $userrow['sex'] ?? 0; // 性别字段(补充返回,方便前端展示)
// ==================================================
return succjson($ret);
}
public static function json_logout() {

248
web/ambap/member.php Normal file
View File

@ -0,0 +1,248 @@
<?php
namespace web\ambap;
class member {
// 接口入口:通过 act 参数路由到不同方法
public static function index() {
$act = $_REQUEST['act'] ?? '';
switch($act) {
case 'member.list':
self::json_list();
break;
case 'member.add':
self::json_add();
break;
case 'member.edit':
self::json_edit();
break;
case 'member.detail':
self::json_detail();
break;
case 'member.del':
self::json_del();
break;
case 'member.audit':
self::json_audit();
break;
default:
echo json_encode(['code' => 0, 'errmsg' => '无效的接口动作']);
break;
}
}
// 1. 获取成员列表(适配 ciy\db 类)
public static function json_list() {
global $db;
$post = new \ciy\post();
$page = $post->getint('page', 1);
$pageSize = $post->getint('pageSize', 15);
$offset = ($page - 1) * $pageSize;
// 构建查询条件
$csql = new \ciy\sql('lab_user');
$csql->limit($offset, $pageSize); // 分页:偏移量、每页条数
$csql->order('addtimes DESC');
// 核心修改:使用 ciy\db 的 get 方法获取列表+总数
$total = -1; // 传入 -1 自动查询总数
$list = $db->get($csql, $total); // $total 会被赋值为总条数
// 处理查询失败
if ($list === false) {
return self::err('获取列表失败:' . $db->error);
}
// 格式化返回数据
$retList = [];
foreach ($list as $item) {
$retList[] = [
'id' => $item['id'],
'name' => $item['name'],
'mobile' => $item['mobile'],
'usertitle' => $item['usertitle'],
'status' => $item['stpstatus'] == 10 ? 1 : 2, // 1=在册 2=历史
'sex' => $item['sex'],
'email' => $item['email'],
'avatar' => $item['avatar'] ?? '',
'isLeader' => $item['usertitle'] == 1, // 是否负责人
'addtimes' => $item['addtimes']
];
}
echo json_encode([
'code' => 1,
'list' => $retList,
'total' => $total
]);
}
// 2. 新增成员
public static function json_add() {
global $db;
$post = new \ciy\post();
// 获取表单数据
$name = $post->get('name');
$mobile = $post->get('mobile');
$usertitle = $post->getint('usertitle');
$status = $post->getint('status');
$sex = $post->getint('sex');
$email = $post->get('email');
$password = $post->get('password');
// 基础验证
if (empty($name)) return self::err('请输入姓名');
if (empty($mobile)) return self::err('请输入手机号');
if (!preg_match('/^1[3-9]\d{9}$/', $mobile)) return self::err('手机号格式错误');
if (empty($password)) return self::err('请设置密码');
// 检查手机号是否已注册
$csql = new \ciy\sql('lab_user');
$csql->where('mobile', $mobile);
$exist = $db->getone($csql);
if (is_array($exist)) return self::err('该手机号已注册');
// 组装数据
$data = [
'name' => $name,
'mobile' => $mobile,
'usertitle' => $usertitle,
'stpstatus' => $status == 1 ? 10 : 20, // 10=正常(在册) 20=禁用(历史)
'sex' => $sex,
'email' => $email,
'password' => $password, // 前端已加密
'userlevel' => 10, // 默认等级
'trytime' => 0,
'logintimes' => tostamp(),
'addtimes' => tostamp(),
'ip' => getip(),
'laborgid' => 0,
'sn' => '',
'totalpnt' => 0,
'dvotecnt' => 0
];
// 插入数据(使用 ciy\db 的 insert 方法)
$csql = new \ciy\sql('lab_user');
$result = $db->insert($csql, $data);
if ($result === false) {
return self::err('新增失败:' . $db->error);
}
echo json_encode(['code' => 1, 'msg' => '新增成功']);
}
// 3. 编辑成员
public static function json_edit() {
global $db;
$post = new \ciy\post();
$id = $post->getint('id');
$name = $post->get('name');
$usertitle = $post->getint('usertitle');
$status = $post->getint('status');
$sex = $post->getint('sex');
$email = $post->get('email');
if (empty($id)) return self::err('参数错误');
if (empty($name)) return self::err('请输入姓名');
// 组装更新数据
$data = [
'name' => $name,
'usertitle' => $usertitle,
'stpstatus' => $status == 1 ? 10 : 20,
'sex' => $sex,
'email' => $email,
'updatetime' => tostamp()
];
// 更新数据(使用 ciy\db 的 update 方法)
$csql = new \ciy\sql('lab_user');
$csql->where('id', $id);
$result = $db->update($csql, $data);
if ($result === false) {
return self::err('修改失败:' . $db->error);
}
echo json_encode(['code' => 1, 'msg' => '修改成功']);
}
// 4. 获取成员详情
public static function json_detail() {
global $db;
$post = new \ciy\post();
$id = $post->getint('id');
if (empty($id)) return self::err('参数错误');
// 查询详情(使用 ciy\db 的 getone 方法)
$csql = new \ciy\sql('lab_user');
$csql->where('id', $id);
$item = $db->getone($csql);
if (!is_array($item)) return self::err('成员不存在');
// 格式化返回数据
$data = [
'id' => $item['id'],
'name' => $item['name'],
'mobile' => $item['mobile'],
'usertitle' => $item['usertitle'],
'status' => $item['stpstatus'] == 10 ? 1 : 2,
'sex' => $item['sex'],
'email' => $item['email']
];
echo json_encode(['code' => 1, 'data' => $data]);
}
// 5. 删除成员
public static function json_del() {
global $db;
$post = new \ciy\post();
$id = $post->getint('id');
if (empty($id)) return self::err('参数错误');
// 删除数据(使用 ciy\db 的 delete 方法)
$csql = new \ciy\sql('lab_user');
$csql->where('id', $id);
$result = $db->delete($csql);
if ($result === false) {
return self::err('删除失败:' . $db->error);
}
echo json_encode(['code' => 1, 'msg' => '删除成功']);
}
// 6. 审核成员
public static function json_audit() {
global $db;
$post = new \ciy\post();
$id = $post->getint('id');
$status = $post->getint('status');
if (empty($id)) return self::err('参数错误');
$data = ['stpstatus' => $status == 10 ? 10 : 20];
$csql = new \ciy\sql('lab_user');
$csql->where('id', $id);
$result = $db->update($csql, $data);
if ($result === false) {
return self::err('审核失败:' . $db->error);
}
echo json_encode(['code' => 1, 'msg' => '审核成功']);
}
// 通用错误返回
private static function err($msg) {
echo json_encode(['code' => 0, 'errmsg' => $msg]);
exit;
}
}
// 执行入口
member::index();
?>

129
zc_cata.sql Normal file
View File

@ -0,0 +1,129 @@
/*
Navicat Premium Data Transfer
Source Server : ryx
Source Server Type : MariaDB
Source Server Version : 100510
Source Host : localhost:3307
Source Schema : c5_labsci
Target Server Type : MariaDB
Target Server Version : 100510
File Encoding : 65001
Date: 26/01/2026 14:39:29
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for zc_cata
-- ----------------------------
DROP TABLE IF EXISTS `zc_cata`;
CREATE TABLE `zc_cata` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`upid` int(11) NOT NULL COMMENT '上级,DB,zc_cata',
`csort` int(11) NOT NULL DEFAULT 10 COMMENT '排序',
`isuse` int(11) NOT NULL DEFAULT 1 COMMENT '|行为|,BOOL',
`cbid` int(11) NOT NULL DEFAULT 0 COMMENT '库,DB,zc_cata',
`codeid` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '',
`name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '名称',
`clas` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '样式类',
`extdata` varchar(180) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '扩展值',
PRIMARY KEY (`id`) USING BTREE,
INDEX `cbid`(`cbid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 12001701 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '字典表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of zc_cata
-- ----------------------------
INSERT INTO `zc_cata` VALUES (1, 0, 0, 1, 0, '', '固定字典', '', '');
INSERT INTO `zc_cata` VALUES (2, 0, 0, 1, 0, '', '灵活字典', '', '');
INSERT INTO `zc_cata` VALUES (10, 1, 0, 1, 0, 'sex', '性别', '', 'zc_admin');
INSERT INTO `zc_cata` VALUES (11, 1, 0, 1, 0, 'stpstatus', '账号状态', '', 'zc_admin');
INSERT INTO `zc_cata` VALUES (12, 1, 0, 1, 0, 'auditstatus', '审核状态', '', 'zc_urole');
INSERT INTO `zc_cata` VALUES (13, 1, 0, 1, 0, 'autotaskstatus', '任务状态', '', 'zc_autotask');
INSERT INTO `zc_cata` VALUES (14, 2, 0, 1, 0, 'targettype', '子系统', '', 'zc_debug_user\nzc_online');
INSERT INTO `zc_cata` VALUES (18, 1, 0, 1, 0, 'cashstatus', '提现状态', '', 'ap_cash_out');
INSERT INTO `zc_cata` VALUES (19, 2, 0, 1, 0, 'cashtype', '收支分类', '', 'ap_cash_ie,ap_cash_oe');
INSERT INTO `zc_cata` VALUES (21, 2, 0, 1, 0, 'userlevel', '用户等级', '', 'ap_user');
INSERT INTO `zc_cata` VALUES (22, 1, 0, 1, 0, 'artsort', '文章排序', '', 'ap_art_post');
INSERT INTO `zc_cata` VALUES (23, 1, 0, 1, 0, 'artstatus', '文章状态', '', 'ap_art_post');
INSERT INTO `zc_cata` VALUES (24, 2, 0, 1, 0, 'certs', '认证范围', '', 'ap_user');
INSERT INTO `zc_cata` VALUES (100, 2, 0, 1, 0, 'aicapacity', 'AI能力', '', 'zc_ai_key');
INSERT INTO `zc_cata` VALUES (101, 1, 0, 1, 0, 'aidotype', 'AI执行方式', '', 'zc_ai_tsk_run');
INSERT INTO `zc_cata` VALUES (102, 1, 10, 1, 0, 'education', '学历', '', '');
INSERT INTO `zc_cata` VALUES (103, 0, 10, 1, 0, 'orderstatus', '订单状态', '', '');
INSERT INTO `zc_cata` VALUES (1000, 0, 10, 1, 10, '10', '', '', '');
INSERT INTO `zc_cata` VALUES (1001, 0, 20, 1, 10, '20', '', '', '');
INSERT INTO `zc_cata` VALUES (1002, 0, 90, 1, 10, '90', '其他', '', '');
INSERT INTO `zc_cata` VALUES (1010, 0, 8, 1, 11, '8', '被禁用', 'dag', '');
INSERT INTO `zc_cata` VALUES (1011, 0, 9, 1, 11, '9', '登录保护', 'warn', '');
INSERT INTO `zc_cata` VALUES (1012, 0, 10, 1, 11, '10', '正常', 'succ', '');
INSERT INTO `zc_cata` VALUES (1020, 0, 10, 2, 12, '10', '草稿', 'def', '');
INSERT INTO `zc_cata` VALUES (1021, 0, 20, 1, 12, '20', '未审核', 'man', '');
INSERT INTO `zc_cata` VALUES (1022, 0, 50, 1, 12, '50', '审核中', 'warn', '');
INSERT INTO `zc_cata` VALUES (1023, 0, 90, 1, 12, '90', '驳回', 'dag', '');
INSERT INTO `zc_cata` VALUES (1024, 0, 95, 1, 12, '95', '撤回', 'def', '');
INSERT INTO `zc_cata` VALUES (1025, 0, 100, 1, 12, '100', '通过', 'succ', '');
INSERT INTO `zc_cata` VALUES (1030, 0, 20, 1, 13, '20', '等待执行', 'succ', '');
INSERT INTO `zc_cata` VALUES (1031, 0, 30, 1, 13, '30', '执行中', 'warn', '');
INSERT INTO `zc_cata` VALUES (1039, 0, 90, 1, 13, '90', '禁止执行', 'dag', '');
INSERT INTO `zc_cata` VALUES (1040, 0, 10, 1, 14, '10', '总控', '', '');
INSERT INTO `zc_cata` VALUES (1041, 0, 20, 1, 14, '20', 'SaaS PC端', '', '');
INSERT INTO `zc_cata` VALUES (1042, 0, 21, 1, 14, '21', 'SaaS 移动端', '', '');
INSERT INTO `zc_cata` VALUES (1150, 0, 10, 1, 18, '10', '申请中', 'def', '');
INSERT INTO `zc_cata` VALUES (1151, 0, 20, 1, 18, '20', '已通过', 'warn', '');
INSERT INTO `zc_cata` VALUES (1152, 0, 21, 2, 18, '21', '微信操作中', 'warn', '');
INSERT INTO `zc_cata` VALUES (1153, 0, 30, 1, 18, '30', '已传发票', 'man', '');
INSERT INTO `zc_cata` VALUES (1154, 0, 50, 1, 18, '50', '待打款', 'def', '');
INSERT INTO `zc_cata` VALUES (1155, 0, 90, 1, 18, '90', '已拒绝', 'dag', '');
INSERT INTO `zc_cata` VALUES (1156, 0, 100, 1, 18, '100', '已完成', 'succ', '');
INSERT INTO `zc_cata` VALUES (1200, 0, 10, 1, 19, '10', '充值', '', '');
INSERT INTO `zc_cata` VALUES (1201, 0, 11, 1, 19, '11', '提现', '', '');
INSERT INTO `zc_cata` VALUES (1210, 0, 20, 1, 19, '20', '推荐奖', '', '');
INSERT INTO `zc_cata` VALUES (1211, 0, 21, 1, 19, '21', '带新奖', '', '');
INSERT INTO `zc_cata` VALUES (1212, 0, 22, 1, 19, '22', '领导奖', '', '');
INSERT INTO `zc_cata` VALUES (1550, 0, 1, 1, 21, '10', 'LV.1', '', '');
INSERT INTO `zc_cata` VALUES (1551, 0, 2, 1, 21, '20', 'LV.2', '', '');
INSERT INTO `zc_cata` VALUES (1600, 0, 0, 1, 22, '10', '劣后', '', '');
INSERT INTO `zc_cata` VALUES (1601, 0, 0, 1, 22, '20', '正常', '', '');
INSERT INTO `zc_cata` VALUES (1602, 0, 0, 1, 22, '30', '置顶', '', '');
INSERT INTO `zc_cata` VALUES (1603, 0, 0, 1, 22, '40', '总置顶', '', '');
INSERT INTO `zc_cata` VALUES (1650, 0, 0, 1, 23, '10', '草稿', 'def', '');
INSERT INTO `zc_cata` VALUES (1651, 0, 0, 1, 23, '20', '待审核', 'warn', '');
INSERT INTO `zc_cata` VALUES (1652, 0, 0, 1, 23, '90', '驳回', 'dag', '');
INSERT INTO `zc_cata` VALUES (1653, 0, 0, 1, 23, '100', '发布', 'succ', '');
INSERT INTO `zc_cata` VALUES (1700, 0, 10, 1, 24, 'a', '实名认证', '', '');
INSERT INTO `zc_cata` VALUES (1701, 0, 20, 1, 24, 'b', '付费会员', '', '');
INSERT INTO `zc_cata` VALUES (10100, 0, 1, 1, 100, 'text', '文本', '', '');
INSERT INTO `zc_cata` VALUES (10101, 0, 2, 1, 100, 'json', 'JSON', '', '');
INSERT INTO `zc_cata` VALUES (10105, 0, 5, 1, 100, 'fcall', '函数', '', '');
INSERT INTO `zc_cata` VALUES (10110, 0, 10, 1, 100, 'image', '理解图像', '', '');
INSERT INTO `zc_cata` VALUES (10115, 0, 15, 1, 100, 'video', '理解视频', '', '');
INSERT INTO `zc_cata` VALUES (10120, 0, 20, 1, 100, '3dmodel', '理解三维', '', '');
INSERT INTO `zc_cata` VALUES (10150, 0, 0, 1, 101, '10', '等待介入', '', '');
INSERT INTO `zc_cata` VALUES (10151, 0, 0, 1, 101, '30', '专家研判', '', '');
INSERT INTO `zc_cata` VALUES (10152, 0, 0, 1, 101, '20', '专家建议', '', '');
INSERT INTO `zc_cata` VALUES (10154, 0, 0, 1, 101, '100', 'AI不执行', '', '');
INSERT INTO `zc_cata` VALUES (10155, 0, 0, 1, 101, '110', 'AI自主执行', '', '');
INSERT INTO `zc_cata` VALUES (10156, 0, 0, 1, 101, '150', '直接执行', '', '');
INSERT INTO `zc_cata` VALUES (10157, 0, 0, 1, 101, '160', '改后执行', '', '');
INSERT INTO `zc_cata` VALUES (10159, 0, 0, 1, 101, '190', '人类拒绝', '', '');
INSERT INTO `zc_cata` VALUES (10160, 0, 0, 1, 101, '200', 'AI执行已阅', '', '');
INSERT INTO `zc_cata` VALUES (10161, 0, 0, 1, 101, '210', 'AI执行问题', '', '');
INSERT INTO `zc_cata` VALUES (10200, 0, 10, 1, 102, '10', '小学', '', '');
INSERT INTO `zc_cata` VALUES (10201, 0, 10, 1, 102, '20', '初中', '', '');
INSERT INTO `zc_cata` VALUES (10202, 0, 10, 1, 102, '30', '高中', '', '');
INSERT INTO `zc_cata` VALUES (10203, 0, 10, 1, 102, '40', '大专', '', '');
INSERT INTO `zc_cata` VALUES (10204, 0, 10, 1, 102, '50', '本科', '', '');
INSERT INTO `zc_cata` VALUES (10205, 0, 10, 1, 102, '60', '硕士', '', '');
INSERT INTO `zc_cata` VALUES (10206, 0, 10, 1, 102, '70', '博士', '', '');
INSERT INTO `zc_cata` VALUES (10250, 0, 10, 1, 103, '10', '等待指令', '', '');
INSERT INTO `zc_cata` VALUES (10251, 0, 10, 1, 103, '20', '队列中', '', '');
INSERT INTO `zc_cata` VALUES (10252, 0, 10, 1, 103, '30', '转账中', '', '');
INSERT INTO `zc_cata` VALUES (10253, 0, 10, 1, 103, '100', '成功', '', '');
INSERT INTO `zc_cata` VALUES (10254, 0, 10, 1, 103, '90', '失败', '', '');
SET FOREIGN_KEY_CHECKS = 1;