測試平臺(tái)系列(22) 編寫項(xiàng)目的增刪改查接口和頁面(4)

回顧

上一節(jié)已經(jīng)貼出了項(xiàng)目列表頁面的全部前端代碼杖挣,由于筆者前端也沒有深入學(xué)習(xí)肩榕,所以只能給大家大概講解一下吧。還是按照之前的幾個(gè)部分來說吧惩妇!

狀態(tài)管理

image

設(shè)置了如下變量:

  • data

    存放當(dāng)前項(xiàng)目數(shù)組

  • pagination

    項(xiàng)目分頁

  • visible

    創(chuàng)建項(xiàng)目表單是否可見株汉,默認(rèn)是否

  • users

    由于我們需要選擇項(xiàng)目管理員,所以需要一個(gè)userId => 用戶信息的映射歌殃。當(dāng)然這個(gè)接口我們暫時(shí)還沒有實(shí)現(xiàn)乔妈。

方法編寫

const fetchData = async (current=pagination.current, size=pagination.size) => {
  await process(async ()=> {
    const res = await listProject({page: current, size });
    if (auth.response(res)) {
      setData(res.data)
      setPagination({...pagination, total: res.total})
    }
  });
}

這個(gè)方法是獲取項(xiàng)目列表的方法,current代表page氓皱,size代表分頁大小路召,如果不傳入則是pagination默認(rèn)的值勃刨。

listProject其實(shí)就是包裝的request方法,請(qǐng)求后端服務(wù)股淡。

useEffect(async () => {
  await fetchData();
}, [])

const onSearchProject = async projectName => {
  await process(async ()=> {
    const res = await listProject({page: 1, size: pagination.size, name: projectName});
    if (auth.response(res)) {
      setData(res.data)
      setPagination({...pagination, current: 1, total: res.total})
    }
  });
}

useEffectreact新版本的特性身隐,它支持2個(gè)參數(shù),第一個(gè)是方法揣非,第二個(gè)是變量數(shù)組抡医,傳入空數(shù)組的話,則每次這個(gè)組件開始渲染的時(shí)候會(huì)調(diào)用且只調(diào)用一次方法早敬。

我們?nèi)绻绞褂玫脑捈缮担菚?huì)有多套測試環(huán)境的。如果我們對(duì)項(xiàng)目做了環(huán)境的區(qū)分搞监,那么就應(yīng)該在切換環(huán)境的時(shí)候水孩,獲取不同環(huán)境的項(xiàng)目。

假設(shè)我們需要實(shí)現(xiàn)這種功能琐驴,那么我們先創(chuàng)建一個(gè)env的變量俘种,然后改寫useEffect:

useEffect(async () => {
  await fetchData();
}, [env])

這樣的話,每當(dāng)env發(fā)生變化绝淡,這個(gè)方法就會(huì)自動(dòng)執(zhí)行一次宙刘。需要說明的是,這里只是介紹一下useEffect的使用方式牢酵,因?yàn)槲覀冞@邊暫時(shí)還沒有擴(kuò)展到多套環(huán)境悬包,所以此處我們選擇[]即可

const onHandleCreate = async values => {
  const res = await insertProject(values);
  if (auth.response(res, true)) {
    // 創(chuàng)建成功后自動(dòng)獲取第一頁的數(shù)據(jù), 因?yàn)轫?xiàng)目會(huì)按創(chuàng)建時(shí)間排序
    await fetchData(1);
  }
}

這邊也如出一轍馍乙,創(chuàng)建完畢了之后如果接口未返回錯(cuò)誤布近,則刷新項(xiàng)目列表頁面,并且自動(dòng)去第一頁丝格。

const content = (item) => {
  return <div>
     {/* <p>負(fù)責(zé)人: {userMap[item.owner].name}</p> */}
     <p>簡介: {item.description || '無'}</p>
     <p>更新時(shí)間: {item.updated_at}</p>
  </div>
};

const opt = <Select placeholder="請(qǐng)選擇項(xiàng)目負(fù)責(zé)人">
  {
    Object.keys(users).map(id => <Option key={id} value={id}>{users[id].name}</Option>)
  }
</Select>

const fields = [
    {
      name: 'projectName',
      label: '項(xiàng)目名稱',
      required: true,
      message: "請(qǐng)輸入項(xiàng)目名稱",
      type: 'input',
      placeholder: "請(qǐng)輸入項(xiàng)目名稱",
    },
    {
      name: 'owner',
      label: '項(xiàng)目負(fù)責(zé)人',
      required: true,
      component: opt,
      type: 'select',
    },
    {
      name: 'description',
      label: '項(xiàng)目描述',
      required: false,
      message: "請(qǐng)輸入項(xiàng)目描述",
      type: 'textarea',
      placeholder: "請(qǐng)輸入項(xiàng)目描述",
    },
    {
      name: 'private',
      label: '是否私有',
      required: true,
      message: "請(qǐng)選擇項(xiàng)目是否私有",
      type: 'switch',
      valuePropName: "checked",
    },
  ]

這里content是一個(gè)方法撑瞧,會(huì)返回一個(gè)div的html結(jié)構(gòu),目的是為了展示項(xiàng)目的詳情显蝌,比如負(fù)責(zé)人预伺,項(xiàng)目描述等。

fields的話曼尊,是表單的字段酬诀,因?yàn)槲裔槍?duì)antd的form進(jìn)行了一點(diǎn)封裝,編寫了一套高階組件涩禀。等于說是規(guī)劃好了表單里面的表單組成料滥,由input和select以及switch組件組成

待會(huì)會(huì)講這個(gè)組件艾船!

最后看return里面的組件

    return (
      <PageContainer title={false}>
        <FormForModal width={600} title="添加項(xiàng)目" left={6} right={18} record={{}}
                      visible={visible} onCancel={() => setVisible(false)} fields={fields} onFinish={onHandleCreate}
        />
        <Row gutter={8} style={{marginBottom: 16}}>
          <Col span={18}>
            <Button type="primary" onClick={() => setVisible(true)}>創(chuàng)建項(xiàng)目
              <Tooltip title="只有超級(jí)管理員可以創(chuàng)建項(xiàng)目"><QuestionCircleOutlined/></Tooltip>
            </Button>
          </Col>
          <Col span={6}>
            <Search onSearch={onSearchProject} style={{float: 'right'}} placeholder="請(qǐng)輸入項(xiàng)目名稱"/>
          </Col>
        </Row>
        <Spin spinning={false}>
          <Row gutter={16}>
            {
              data.length === 0 ? <Col span={24} style={{textAlign: 'center', marginBottom: 12}}>
                  <Card><Empty description="暫無項(xiàng)目, 快點(diǎn)擊『創(chuàng)建項(xiàng)目』創(chuàng)建一個(gè)吧!"/></Card>
                </Col> :
                data.map(item =>
                  <Col key={item.id} span={4} style={{marginBottom: 12}}>
                    <Popover content={content(item)} placement="rightTop">
                      <Card hoverable bordered={false} style={{borderRadius: 16, textAlign: 'center'}}
                            bodyStyle={{padding: 16}} onClick={() => {
                        history.push(`/project/${item.id}`);
                      }}>
                        <Avatar style={{backgroundColor: '#87d068'}} size={64}
                        >{item.name.slice(0, 2)}</Avatar>
                        <p style={{
                          textAlign: 'center',
                          fontWeight: 'bold',
                          fontSize: 18,
                          marginTop: 8
                        }}>{item.name}</p>
                      </Card>
                    </Popover>
                  </Col>
                )
            }
          </Row>
        </Spin>
      </PageContainer>
    )
}

PageContainer是最外層葵腹,也就是咱們看到的這一塊:

image

FormForModal是一個(gè)對(duì)話框表單高每,默認(rèn)是不顯示的,只有點(diǎn)擊創(chuàng)建項(xiàng)目才會(huì)顯示践宴。

然后用Row分了2行: 分別是 創(chuàng)建欄/搜索欄和項(xiàng)目展示欄

image

這邊項(xiàng)目展示欄如果data.length === 0就展示一個(gè)空狀態(tài)鲸匿,提示用戶去添加項(xiàng)目,否則就把項(xiàng)目展示出來阻肩,每個(gè)項(xiàng)目占屏幕的1/6带欢,因?yàn)镃ol總共有24份。

tips: 這里類似于bootstrap烤惊,一行共有24份乔煞,所以span={4}代表的是4/24,可參考: 官網(wǎng)介紹

image

其他的就是Card(卡片)組件和Avatar(頭像)組件的互相嵌入柒室,Popover是懸浮窗口渡贾,如圖:

image

編寫獲取用戶列表的接口

修改app/dao/auth/UserDao.py

image

篩選出未被刪除的用戶即可。

修改app/controllers/auth/user.py

image

這里注意開啟一下權(quán)限雄右,但是不能控制太死空骚,能讓登錄用戶訪問即可。

前端頁面編寫listUsers方法

image

看下效果

image

發(fā)現(xiàn)一個(gè)問題: 創(chuàng)建成功后擂仍,對(duì)話框沒有關(guān)閉

所以我們需要在創(chuàng)建成果后囤屹,setVisible(false)去關(guān)閉對(duì)話框。

image

還有一個(gè)地方就是之前注釋掉的項(xiàng)目負(fù)責(zé)人逢渔,現(xiàn)在可以重新開啟了肋坚。

image
image

看下搜索效果

image
image

這就是本節(jié)的內(nèi)容了,大部分是講解代碼為主复局,因?yàn)?strong>前端內(nèi)容居多冲簿,所以可能有點(diǎn)懵逼粟判。如果有不理解的地方亿昏,還請(qǐng)多多看看reactes6相關(guān)的教程。箭頭函數(shù)档礁,看著別怕角钩,熟悉了就好。

下一節(jié)可能是具體項(xiàng)目的編輯頁面了呻澜,感覺這一講就講了一個(gè)世紀(jì)递礼,再后面就是用例那塊了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末羹幸,一起剝皮案震驚了整個(gè)濱河市脊髓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌栅受,老刑警劉巖将硝,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件恭朗,死亡現(xiàn)場離奇詭異,居然都是意外死亡依疼,警方通過查閱死者的電腦和手機(jī)痰腮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來律罢,“玉大人膀值,你說我怎么就攤上這事∥蠹” “怎么了沧踏?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長巾钉。 經(jīng)常有香客問我悦冀,道長,這世上最難降的妖魔是什么睛琳? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任盒蟆,我火速辦了婚禮,結(jié)果婚禮上师骗,老公的妹妹穿的比我還像新娘历等。我一直安慰自己,他們只是感情好辟癌,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布寒屯。 她就那樣靜靜地躺著,像睡著了一般黍少。 火紅的嫁衣襯著肌膚如雪寡夹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天厂置,我揣著相機(jī)與錄音菩掏,去河邊找鬼。 笑死昵济,一個(gè)胖子當(dāng)著我的面吹牛智绸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播访忿,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼瞧栗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了海铆?” 一聲冷哼從身側(cè)響起迹恐,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎卧斟,沒想到半個(gè)月后殴边,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體通熄,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年找都,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了唇辨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡能耻,死狀恐怖赏枚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情晓猛,我是刑警寧澤饿幅,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站戒职,受9級(jí)特大地震影響栗恩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜洪燥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一磕秤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧捧韵,春花似錦市咆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至芒篷,卻和暖如春搜变,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背针炉。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國打工挠他, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人糊识。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓绩社,卻偏偏與公主長得像摔蓝,于是被迫代替她去往敵國和親赂苗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容